diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9bd671452..42235bef1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,8 +2,8 @@ name: Build on: push: - branches-ignore: - - main +# branches-ignore: +# - main paths-ignore: - '*.json' - '*.md' @@ -18,7 +18,7 @@ env: jobs: build-linux: name: Build Linux (${{matrix.name}} x86_64) - runs-on: ubuntu-20.04 + runs-on: ubuntu-latest env: BUILDCACHE_DIR: ${{github.workspace}}/.buildcache @@ -46,10 +46,8 @@ jobs: sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main" sudo apt-get -y install ninja-build clang lld libcurl4-openssl-dev intel-oneapi-ipp-devel \ 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 qt5-default - - yarn global add @sentry/cli - echo "$(yarn global bin)" >> $GITHUB_PATH + libpulse-dev libudev-dev libpng-dev libncurses5-dev libx11-xcb-dev libfreetype-dev \ + libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev # setup buildcache curl -LSfs https://github.com/encounter/buildcache/releases/download/$BUILDCACHE_VERSION/buildcache-linux.tar.gz | tar xz -C "$RUNNER_WORKSPACE" @@ -84,12 +82,22 @@ jobs: - name: Print buildcache stats run: buildcache -s + - name: Generate AppImage + run: ci/build-appimage.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: metaforce-${{env.METAFORCE_VERSION}}-linux-${{matrix.preset}}-x86_64 + path: | + build/install/Metaforce-*.AppImage + build/install/debug.tar.* + build-macos: name: Build macOS (AppleClang universal) - runs-on: macos-11 + runs-on: macos-latest env: - Qt_VERSION: 5.15.2 IPP_VERSION: 2021.2.0.192 BUILDCACHE_DIR: ${{github.workspace}}/.buildcache @@ -105,11 +113,7 @@ jobs: brew upgrade --formula brew install ninja graphicsmagick imagemagick yarn global add create-dmg - - # universal qt5 from macports - curl -LSfs https://axiodl.com/files/qt-$Qt_VERSION.mpkg -o /tmp/qt-$Qt_VERSION.mpkg - sudo installer -pkg /tmp/qt-$Qt_VERSION.mpkg -target / - echo /opt/local/libexec/qt5/bin >> $GITHUB_PATH + pip3 install markupsafe # setup buildcache curl -LSfs https://github.com/encounter/buildcache/releases/download/$BUILDCACHE_VERSION/buildcache-macos.zip -o /tmp/buildcache-macos.zip @@ -141,11 +145,103 @@ jobs: run: cmake --build --preset x-macos-ci - name: Print buildcache stats + if: 'false' # temporarily disabled run: buildcache -s + - name: Import signing certificate + uses: devbotsxyz/xcode-import-certificate@master + with: + certificate-data: ${{secrets.MACOS_CERTIFICATE_DATA}} + certificate-passphrase: ${{secrets.MACOS_CERTIFICATE_PASSWORD}} + keychain-password: ${{secrets.MACOS_KEYCHAIN_PASSWORD}} + + - name: Deploy & codesign application + env: + ASC_USERNAME: ${{secrets.MACOS_ASC_USERNAME}} + ASC_PASSWORD: ${{secrets.MACOS_ASC_PASSWORD}} + ASC_TEAM_ID: ${{secrets.MACOS_ASC_TEAM_ID}} + CODESIGN_IDENT: ${{secrets.MACOS_CODESIGN_IDENT}} + run: ci/build-dmg.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: metaforce-${{env.METAFORCE_VERSION}}-macos-appleclang-universal + path: | + build/install/Metaforce *.dmg + build/install/debug.tar.* + + build-ios: + name: Build iOS (AppleClang arm64) + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + submodules: recursive + + - name: Install dependencies + run: | + brew update + brew upgrade --formula + brew install ninja + pip3 install markupsafe + + - name: Configure CMake + run: cmake --preset ios-default + + - name: Build + run: cmake --build --preset ios-default --target install + + - name: Generate IPA + run: ci/build-ipa.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: metaforce-${{env.METAFORCE_VERSION}}-ios-appleclang-arm64 + path: | + build/install/Metaforce.ipa + build/install/debug.tar.* + + build-tvos: + name: Build tvOS (AppleClang arm64) + runs-on: macos-latest + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + submodules: recursive + + - name: Install dependencies + run: | + brew update + brew upgrade --formula + brew install ninja + pip3 install markupsafe + + - name: Configure CMake + run: cmake --preset tvos-default + + - name: Build + run: cmake --build --preset tvos-default --target install + + - name: Generate IPA + run: ci/build-ipa.sh + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: metaforce-${{env.METAFORCE_VERSION}}-tvos-appleclang-arm64 + path: | + build/install/Metaforce.ipa + build/install/debug.tar.* + build-windows: name: Build Windows (${{matrix.name}} x86_64) - runs-on: windows-2019 + runs-on: windows-latest env: Qt_VERSION: 5.15.2 @@ -158,11 +254,10 @@ jobs: fail-fast: false matrix: include: - # Disabled due to memory constraints -# - name: MSVC -# preset: msvc - - name: Clang - preset: clang + - name: MSVC + preset: msvc + #- name: Clang + # preset: clang steps: - uses: actions/checkout@v2 @@ -191,6 +286,7 @@ jobs: - name: Install dependencies run: | choco install ninja vulkan-sdk + pip install markupsafe # set up buildcache $TempDir = "$env:RUNNER_WORKSPACE\temp" @@ -221,3 +317,11 @@ jobs: - name: Print buildcache stats run: buildcache -s + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: metaforce-${{env.METAFORCE_VERSION}}-win32-${{matrix.preset}}-x86_64 + path: | + ${{env.BUILD_DIR}}/install/*.exe + ${{env.BUILD_DIR}}/install/debug.7z diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f1d2d5a15..b7e3b47c8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,13 +1,14 @@ name: Release -on: - push: - branches: - - main - paths-ignore: - - '*.json' - - '*.md' - - '*LICENSE' +on: workflow_dispatch +#on: +# push: +# branches: +# - main +# paths-ignore: +# - '*.json' +# - '*.md' +# - '*LICENSE' env: BUILDCACHE_VERSION: v0.27.3 @@ -46,7 +47,7 @@ jobs: sudo add-apt-repository "deb https://apt.repos.intel.com/oneapi all main" sudo apt-get -y install ninja-build clang lld libcurl4-openssl-dev intel-oneapi-ipp-devel \ 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 qt5-default + libpulse-dev libudev-dev libpng-dev libncurses5-dev libx11-xcb-dev qt5-default libfreetype-dev yarn global add @sentry/cli echo "$(yarn global bin)" >> $GITHUB_PATH @@ -121,7 +122,7 @@ jobs: run: | brew update brew upgrade --formula - brew install ninja graphicsmagick imagemagick getsentry/tools/sentry-cli + brew install ninja graphicsmagick imagemagick getsentry/tools/sentry-cli freetype yarn global add create-dmg # universal qt5 from macports diff --git a/.gitmodules b/.gitmodules index a4c7787d0..55c5ae9fe 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,59 +1,48 @@ -[submodule "nod"] +[submodule "extern/nod"] path = extern/nod url = ../nod.git branch = master -[submodule "amuse"] - path = extern/amuse - url = ../amuse.git - branch = master -[submodule "kabufuda"] +[submodule "extern/kabufuda"] path = extern/kabufuda url = ../kabufuda.git branch = master -[submodule "jbus"] +[submodule "extern/jbus"] path = extern/jbus url = ../jbus.git branch = master -[submodule "assetnameparser/tinyxml2"] - path = extern/tinyxml2 - url = ../tinyxml2.git - branch = master -[submodule "sanitizers-cmake"] - path = extern/sanitizers-cmake - url = https://github.com/arsenm/sanitizers-cmake.git - branch = master -[submodule "discord-rpc"] +[submodule "extern/discord-rpc"] path = extern/discord-rpc url = https://github.com/discordapp/discord-rpc.git branch = master -[submodule "rapidjson"] +[submodule "extern/rapidjson"] path = extern/rapidjson url = https://github.com/Tencent/rapidjson.git branch = master -[submodule "NESEmulator/fixNES"] +[submodule "extern/fixNES"] path = extern/fixNES url = https://github.com/FIX94/fixNES.git branch = master -[submodule "extern/libSquish"] - path = extern/libSquish - url = ../libSquish.git - branch = master [submodule "extern/athena"] path = extern/athena url = ../../libAthena/athena.git branch = master -[submodule "extern/boo"] - path = extern/boo - url = ../boo.git - branch = master [submodule "extern/libjpeg-turbo"] path = extern/libjpeg-turbo url = ../libjpeg-turbo.git branch = thp -[submodule "zeus"] +[submodule "extern/zeus"] path = extern/zeus url = ../zeus.git branch = master -[submodule "extern/imgui"] - path = extern/imgui - url = https://github.com/ocornut/imgui.git +[submodule "extern/nativefiledialog-extended"] + path = extern/nativefiledialog-extended + url = https://github.com/encounter/nativefiledialog-extended.git + branch = nfd-install-option +[submodule "extern/optick"] + path = extern/optick + url = https://github.com/AxioDL/optick.git + branch = master +[submodule "extern/aurora"] + path = extern/aurora + url = https://github.com/encounter/aurora.git + branch = main diff --git a/CMakeLists.txt b/CMakeLists.txt index d9e1a4f49..c3496bbf9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ endif () if (METAFORCE_WC_DESCRIBE) string(REGEX REPLACE "v([0-9]+)\.([0-9]+)\.([0-9]+)\-([0-9]+).*" "\\1.\\2.\\3.\\4" METAFORCE_VERSION_STRING "${METAFORCE_WC_DESCRIBE}") - string(REGEX REPLACE "v([0-9]+)\.([0-9]+)\.([0-9]+).*" "\\1.\\2.\\3" METAFORCE_VERSION_STRING "${METAFORCE_VERSION_STRING}") + string(REGEX REPLACE "v([0-9]+)\.([0-9]+)\.([0-9]+).*" "\\1.\\2.\\3" METAFORCE_SHORT_VERSION_STRING "${METAFORCE_WC_DESCRIBE}") else () set(METAFORCE_WC_DESCRIBE "UNKNOWN-VERSION") set(METAFORCE_VERSION_STRING "0.0.0") @@ -64,20 +64,36 @@ if(DEFINED ENV{GITHUB_ENV}) endif() message(STATUS "Metaforce version set to ${METAFORCE_WC_DESCRIBE}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") -project(metaforce LANGUAGES C CXX ASM VERSION ${METAFORCE_VERSION_STRING}) +if(APPLE) + set(EXTRA_LANGUAGES OBJC) +endif() +project(metaforce LANGUAGES C CXX ASM ${EXTRA_LANGUAGES} VERSION ${METAFORCE_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 (EMSCRIPTEN) + set(CMAKE_EXECUTABLE_SUFFIX .html) +endif () string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ATHENA_ARCH) string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" ATHENA_HOST_ARCH) +string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" HOST_PLATFORM_NAME) +string(TOLOWER "${CMAKE_SYSTEM_NAME}" PLATFORM_NAME) set(ATHENA_EXTENSION "tar.gz") -if (CMAKE_SYSTEM_NAME STREQUAL Darwin) - set(PLATFORM_NAME macos) +if (CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin) + set(HOST_PLATFORM_NAME macos) set(ATHENA_ARCH universal) set(ATHENA_HOST_ARCH universal) +elseif (CMAKE_HOST_SYSTEM_NAME STREQUAL Windows) + set(HOST_PLATFORM_NAME win32) + set(ATHENA_EXTENSION ".7z") +endif () +if (CMAKE_SYSTEM_NAME STREQUAL Darwin) + set(PLATFORM_NAME macos) elseif (CMAKE_SYSTEM_NAME STREQUAL Windows) set(PLATFORM_NAME win32) - set(ATHENA_EXTENSION ".7z") -elseif (CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(PLATFORM_NAME linux) endif () set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Binaries) @@ -89,15 +105,6 @@ if(APPLE AND NOT CMAKE_OSX_SYSROOT) OUTPUT_STRIP_TRAILING_WHITESPACE) endif() -option(METAFORCE_CROSSCOMPILING "Don't build tools; attempt package import" OFF) -if (METAFORCE_CROSSCOMPILING) - set(CMAKE_CROSSCOMPILING On) -endif() - -if(CMAKE_CROSSCOMPILING) - set(HAVE_WORDS_BIGENDIAN_EXITCODE 0 CACHE INTEGER "Makes soxr happy" FORCE) -endif() - # MSVC has a "latest" flag, which always uses the newest standard # when available. GCC and Clang posess no such flag, and must be # manually enforced. CMake, curiously, also doesn't have a "latest" @@ -110,9 +117,6 @@ endif() set(BUILD_SHARED_LIBS OFF CACHE BOOL "Force shared libs off" FORCE) set(BUILD_STATIC_LIBS ON CACHE BOOL "Force static libs on" FORCE) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/extern/sanitizers-cmake/cmake") -find_package(Sanitizers) - if (CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL AMD64) set(METAFORCE_VECTOR_ISA "sse41" CACHE STRING "Vector ISA to build for (sse2, sse3, sse41, avx, avx2)") endif () @@ -240,15 +244,20 @@ else() add_compile_options(-fno-asynchronous-unwind-tables) endif() - if(METAFORCE_MSAN) + if (METAFORCE_ASAN) + add_compile_options($<$:-stdlib=libc++> -fsanitize=address + -fsanitize-address-use-after-scope) + add_link_options($<$:-stdlib=libc++> -fsanitize=address + -fsanitize-address-use-after-scope) + elseif(METAFORCE_MSAN) add_compile_options($<$:-stdlib=libc++> -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-recover=all) endif() add_compile_options($<$:-fno-rtti> $<$:-fno-exceptions> - -Wall -Wno-multichar -Werror=implicit-fallthrough + -Wall -Wno-multichar -Wno-unused-variable -Wno-unused-result -Wno-unused-but-set-variable - -Wno-unused-function -Wno-sign-compare -Wno-unknown-pragmas -Werror) + -Wno-unused-function -Wno-sign-compare -Wno-unknown-pragmas) # doesn't work with generator expression in add_compile_options? if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") add_compile_options(-Wno-unknown-warning-option -Wno-unused-private-field) @@ -259,10 +268,6 @@ else() if(APPLE) add_compile_options(-Wno-error=deprecated-declarations $<$:-flto=thin>) - if (METAFORCE_ASAN) - add_compile_options(-fsanitize=address -fsanitize-address-use-after-scope) - add_link_options(-fsanitize=address -fsanitize-address-use-after-scope) - endif () endif() endif() @@ -341,161 +346,18 @@ if(USE_LD_GOLD) endif() endif() -# Add discord-rpc here -if(NOT GEKKO AND NOT NX) - set(PROJECT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/discord-rpc) - if (NOT CMAKE_INSTALL_LIBDIR) - set(CMAKE_INSTALL_LIBDIR ${CMAKE_BINARY_DIR}/fake-prefix) - endif() - add_subdirectory(extern/discord-rpc/src EXCLUDE_FROM_ALL) - target_include_directories(discord-rpc PRIVATE extern/rapidjson/include PUBLIC extern/discord-rpc/include) - if (APPLE) - # remove their nasty hack - get_target_property(DISCORD_LINK_LIBRARIES discord-rpc INTERFACE_LINK_LIBRARIES) - list(REMOVE_ITEM DISCORD_LINK_LIBRARIES "-framework AppKit, -mmacosx-version-min=10.10") - set_target_properties(discord-rpc PROPERTIES INTERFACE_LINK_LIBRARIES "${DISCORD_LINK_LIBRARIES}") - endif () - if (UNIX) - # remove another nasty hack - get_target_property(DISCORD_COMPILE_OPTIONS discord-rpc COMPILE_OPTIONS) - list(REMOVE_ITEM DISCORD_COMPILE_OPTIONS "-g") - set_target_properties(discord-rpc PROPERTIES COMPILE_OPTIONS "${DISCORD_COMPILE_OPTIONS}") - endif () -endif() - -if (NOT WIN32) - find_package(ZLIB REQUIRED) - set(ZLIB_LIBRARIES ZLIB::ZLIB CACHE STRING "zlib libraries" FORCE) -endif() - -option(BUILD_ATHENA "Build Athena libraries from source" ON) -if (WIN32 OR APPLE) - # Default to binary atdna on Windows & macOS - option(BUILD_ATDNA "Build atdna utility from source (requires LLVM)" OFF) -else () - option(BUILD_ATDNA "Build atdna utility from source (requires LLVM)" ON) -endif () - -if (NOT BUILD_ATDNA) - set(ATHENA_BASE_URL "https://github.com/libAthena/athena/releases/download/latest") - if (WIN32) - set(ATHENA_EXT 7z) - else() - set(ATHENA_EXT tar.gz) - endif() - include(FetchContent) - FetchContent_Declare(athena-host - URL "${ATHENA_BASE_URL}/athena-${PLATFORM_NAME}-${ATHENA_HOST_ARCH}.${ATHENA_EXT}") - message(STATUS "Fetching atdna host binary") - FetchContent_Populate(athena-host) - include(${athena-host_SOURCE_DIR}/lib/cmake/atdna/atdnaConfig.cmake) -endif () - -if (BUILD_ATHENA OR BUILD_ATDNA) - add_subdirectory(extern/athena EXCLUDE_FROM_ALL) -else() - if (ATHENA_ARCH STREQUAL ATHENA_HOST_ARCH) - set(athena_SOURCE_DIR "${athena-host_SOURCE_DIR}") - else() - FetchContent_Declare(athena - URL "${ATHENA_BASE_URL}/athena-${PLATFORM_NAME}-${ATHENA_ARCH}.tar.gz") - FetchContent_Populate(athena) - endif() - include(${athena_SOURCE_DIR}/lib/cmake/athena/AthenaConfig.cmake) - include(${athena_SOURCE_DIR}/lib/cmake/lzokay/lzokayConfig.cmake) - add_library(lzokay ALIAS lzokay::lzokay) - include(extern/athena/atdna/atdnaHelpers.cmake) -endif() - -set(DATA_SPEC_LIBS RetroDataSpec AssetNameMap) -set(HECL_DATASPEC_DECLS -"/* RetroCommon specs */ -namespace DataSpec -{ - extern hecl::Database::DataSpecEntry SpecEntMP1; - extern hecl::Database::DataSpecEntry SpecEntMP1PC; - extern hecl::Database::DataSpecEntry SpecEntMP1ORIG; - extern hecl::Database::DataSpecEntry SpecEntMP2; - extern hecl::Database::DataSpecEntry SpecEntMP2PC; - extern hecl::Database::DataSpecEntry SpecEntMP2ORIG; - extern hecl::Database::DataSpecEntry SpecEntMP3; - extern hecl::Database::DataSpecEntry SpecEntMP3PC; - extern hecl::Database::DataSpecEntry SpecEntMP3ORIG; -}") -set(HECL_DATASPEC_PUSHES -" /* RetroCommon */ - hecl::Database::DATA_SPEC_REGISTRY.reserve(9); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1PC); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP1ORIG); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2PC); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP2ORIG); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3PC); - hecl::Database::DATA_SPEC_REGISTRY.push_back(&DataSpec::SpecEntMP3ORIG);") - -add_subdirectory(extern/nod EXCLUDE_FROM_ALL) -add_subdirectory(extern/boo EXCLUDE_FROM_ALL) +find_package(ZLIB REQUIRED) +set(ZLIB_LIBRARIES ZLIB::ZLIB CACHE STRING "zlib libraries" FORCE) include(ExternalProject) -ExternalProject_Add(shaderc - SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/hecl/shaderc" +ExternalProject_Add(bintoc + SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/bintoc" CMAKE_ARGS -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH= INSTALL_COMMAND ${CMAKE_COMMAND} --build . --config Release --target install) +include(${CMAKE_CURRENT_LIST_DIR}/bintoc/bintocHelpers.cmake) -function(shaderc out) - if(IS_ABSOLUTE ${out}) - set(theOut ${out}) - else() - set(theOut ${CMAKE_CURRENT_BINARY_DIR}/${out}) - endif() - unset(theInsList) - foreach(in ${ARGN}) - if(IS_ABSOLUTE ${in}) - list(APPEND theInsList ${in}) - else() - list(APPEND theInsList ${CMAKE_CURRENT_SOURCE_DIR}/${in}) - endif() - endforeach() - get_filename_component(outDir ${theOut} DIRECTORY) - file(MAKE_DIRECTORY ${outDir}) - file(RELATIVE_PATH outRel ${CMAKE_BINARY_DIR} ${theOut}) - ExternalProject_Get_Property(shaderc INSTALL_DIR) - add_custom_command(OUTPUT ${theOut}.cpp ${theOut}.hpp - COMMAND "${INSTALL_DIR}/bin/shaderc" ARGS -o ${theOut} ${theInsList} - DEPENDS ${theInsList} shaderc - COMMENT "Compiling shader ${outRel}.shader") -endfunction() - -include(hecl/ApplicationTools.cmake) -add_subdirectory(Shaders) +add_subdirectory(extern) add_subdirectory(imgui) -add_subdirectory(extern/libSquish EXCLUDE_FROM_ALL) -add_subdirectory(extern/libpng EXCLUDE_FROM_ALL) -add_subdirectory(extern/libjpeg-turbo EXCLUDE_FROM_ALL) -add_subdirectory(hecl EXCLUDE_FROM_ALL) -add_subdirectory(extern/zeus EXCLUDE_FROM_ALL) -target_include_directories(hecl-full PRIVATE ${CMAKE_SOURCE_DIR}) -target_include_directories(hecl-light PRIVATE ${CMAKE_SOURCE_DIR}) -target_link_libraries(hecl-full PRIVATE zeus nod) -target_link_libraries(hecl-light PRIVATE zeus nod) - -bintoc(CModelShaders.common.glsl.cpp Shaders/CModelShaders.common.glsl CMODELSHADERS_COMMON_GLSL) -bintoc(CModelShaders.vert.glsl.cpp Shaders/CModelShaders.vert.glsl CMODELSHADERS_VERT_GLSL) -bintoc(CModelShaders.frag.glsl.cpp Shaders/CModelShaders.frag.glsl CMODELSHADERS_FRAG_GLSL) -bintoc(CModelShaders.common.hlsl.cpp Shaders/CModelShaders.common.hlsl CMODELSHADERS_COMMON_HLSL) -bintoc(CModelShaders.vert.hlsl.cpp Shaders/CModelShaders.vert.hlsl CMODELSHADERS_VERT_HLSL) -bintoc(CModelShaders.frag.hlsl.cpp Shaders/CModelShaders.frag.hlsl CMODELSHADERS_FRAG_HLSL) -bintoc(CModelShaders.common.metal.cpp Shaders/CModelShaders.common.metal CMODELSHADERS_COMMON_METAL) -bintoc(CModelShaders.vert.metal.cpp Shaders/CModelShaders.vert.metal CMODELSHADERS_VERT_METAL) -bintoc(CModelShaders.frag.metal.cpp Shaders/CModelShaders.frag.metal CMODELSHADERS_FRAG_METAL) -add_library(CModelShaders - CModelShaders.common.glsl.cpp CModelShaders.vert.glsl.cpp CModelShaders.frag.glsl.cpp - CModelShaders.common.hlsl.cpp CModelShaders.vert.hlsl.cpp CModelShaders.frag.hlsl.cpp - CModelShaders.common.metal.cpp CModelShaders.vert.metal.cpp CModelShaders.frag.metal.cpp) -target_link_libraries(CModelShaders PUBLIC zeus) -target_link_libraries(shader_CModelShaders PUBLIC CModelShaders) if(NOT TARGET atdna) # Import native atdna if cross-compiling @@ -505,86 +367,64 @@ if(NOT TARGET atdna) endif() endif() -add_subdirectory(extern/amuse EXCLUDE_FROM_ALL) -if (NOT CMAKE_CROSSCOMPILING) - add_subdirectory(assetnameparser EXCLUDE_FROM_ALL) -endif () -add_compile_definitions(URDE_ZIP_INPUT_STREAM=1) # Enable CZipInputStream now that zlib header is known -add_subdirectory(DataSpec) -add_subdirectory(extern/kabufuda EXCLUDE_FROM_ALL) - -add_subdirectory(extern/jbus EXCLUDE_FROM_ALL) -set(JBUS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/extern/jbus/include) - add_subdirectory(NESEmulator EXCLUDE_FROM_ALL) add_subdirectory(Runtime) -add_subdirectory(mpcksum EXCLUDE_FROM_ALL) add_subdirectory(gbalink EXCLUDE_FROM_ALL) -add_subdirectory(visigen) - -add_dependencies(hecl visigen) - -if (NOT WINDOWS_STORE AND NOT NX) - if (APPLE AND EXISTS /opt/local/libexec/qt5) - # macports qt5 (build with +universal) - set(Qt5Widgets_DIR /opt/local/libexec/qt5) - elseif (APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL x86_64) - set(QT_HOMEBREW_PATH /usr/local/opt/qt) - elseif (APPLE AND CMAKE_SYSTEM_PROCESSOR STREQUAL arm64) - set(QT_HOMEBREW_PATH /opt/homebrew/opt/qt) - else () - set(QT_HOMEBREW_PATH "") - endif () - - find_package(Qt6Widgets QUIET PATHS ${QT_HOMEBREW_PATH}) - find_package(Qt5Widgets QUIET PATHS ${QT_HOMEBREW_PATH}) - if (Qt6Widgets_FOUND) - message(STATUS "Qt6 found, metaforce-gui will be built") - add_subdirectory(metaforce-gui) - elseif(Qt5Widgets_FOUND) - message(STATUS "Qt5 found, metaforce-gui will be built") - add_subdirectory(metaforce-gui) - else() - message(STATUS "Qt5-6 not found, metaforce-gui will not be built") - endif() -endif() configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_BINARY_DIR}/version.h) # Packaging logic -list(APPEND BINARY_TARGETS metaforce hecl visigen) -set(DSYM_ONLY_TARGETS "") +function(get_target_output_name target result_var) + get_target_property(output_name ${target} OUTPUT_NAME) + if (output_name STREQUAL "output_name-NOTFOUND") + 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 metaforce) +set(EXTRA_TARGETS "") if (TARGET crashpad_handler) - list(APPEND BINARY_TARGETS crashpad_handler) + list(APPEND EXTRA_TARGETS crashpad_handler) endif () set(BIN_PREFIX "${CMAKE_INSTALL_PREFIX}") -if (TARGET metaforce-gui) - if (APPLE) - # app bundle already has all needed binaries - install(TARGETS metaforce-gui DESTINATION ${BIN_PREFIX}) - list(APPEND DSYM_ONLY_TARGETS metaforce-gui) - # we have to rename here, cmake is inflexible about bundle naming - install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND rm -fr Metaforce.app)") - install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND mv metaforce-gui.app Metaforce.app)") - set(BIN_PREFIX "${BIN_PREFIX}/Metaforce.app/Contents/MacOS") - else() - list(APPEND BINARY_TARGETS metaforce-gui) - endif () -endif () -install(TARGETS ${BINARY_TARGETS} DESTINATION ${BIN_PREFIX}) +install(TARGETS ${BINARY_TARGETS} ${EXTRA_TARGETS} DESTINATION ${BIN_PREFIX}) if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) - foreach (target IN LISTS BINARY_TARGETS DSYM_ONLY_TARGETS) + set(DEBUG_FILES_LIST "") + foreach (target IN LISTS BINARY_TARGETS EXTRA_TARGETS) + get_target_output_name(${target} output_name) if (WIN32) install(FILES $ DESTINATION ${BIN_PREFIX} OPTIONAL) elseif (APPLE) - install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND dsymutil ${target})") - install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND strip -S ${target})") + get_target_prefix(${target} target_prefix) + install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND rm -fr \"$.dSYM\")") + install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND dsymutil \"${target_prefix}$\")") + install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND strip -S \"${target_prefix}$\")") + if (NOT target_prefix STREQUAL "") + install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND mv \"${target_prefix}$.dSYM\" .)") + endif () elseif (UNIX) - install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND objcopy --only-keep-debug ${target} ${target}.dbg)") - install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND objcopy --strip-debug --add-gnu-debuglink=${target}.dbg ${target})") + get_target_prefix(${target} target_prefix) + install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND objcopy --only-keep-debug \"${target_prefix}$\" \"${target_prefix}$.dbg\")") + install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_PREFIX}\" COMMAND objcopy --strip-debug --add-gnu-debuglink=$.dbg \"${target_prefix}$\")") endif () + list(APPEND DEBUG_FILES_LIST "${output_name}") endforeach () - set(DEBUG_FILES_LIST ${BINARY_TARGETS} ${DSYM_ONLY_TARGETS}) if (WIN32) list(TRANSFORM DEBUG_FILES_LIST APPEND ".pdb") list(JOIN DEBUG_FILES_LIST " " DEBUG_FILES) @@ -599,3 +439,13 @@ if (CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) install(CODE "execute_process(WORKING_DIRECTORY \"${BIN_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 \"${BIN_PREFIX}\" COMMAND cp \"${extra_prefix}$\" \"${target_prefix}$\")") + endif () + endforeach () +endforeach () diff --git a/CMakePresets.json b/CMakePresets.json index ebd2a3aad..fd1e034d9 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -29,7 +29,11 @@ "generator": "Ninja", "binaryDir": "${sourceDir}/build/${presetName}", "cacheVariables": { - "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install" + "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install", + "USE_LTO": { + "type": "BOOL", + "value": false + } }, "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { @@ -83,7 +87,39 @@ "inherits": [ "relwithdebinfo", "linux-clang" - ] + ], + "cacheVariables": { + "USE_LTO": { + "type": "BOOL", + "value": true + } + } + }, + { + "name": "linux-clang-debug-asan", + "displayName": "Linux (Clang) Debug w/ ASAN", + "inherits": [ + "linux-clang-debug" + ], + "cacheVariables": { + "METAFORCE_ASAN": { + "type": "BOOL", + "value": true + } + } + }, + { + "name": "linux-clang-relwithdebinfo-asan", + "displayName": "Linux (Clang) RelWithDebInfo w/ ASAN", + "inherits": [ + "linux-clang-relwithdebinfo" + ], + "cacheVariables": { + "METAFORCE_ASAN": { + "type": "BOOL", + "value": true + } + } }, { "name": "windows-msvc", @@ -102,7 +138,11 @@ "type": "FILEPATH", "value": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" }, - "VCPKG_TARGET_TRIPLET": "x64-windows-static" + "VCPKG_TARGET_TRIPLET": "x64-windows-static", + "VCPKG_SETUP_CMAKE_PROGRAM_PATH": { + "type": "BOOL", + "value": false + } }, "vendor": { "microsoft.com/VisualStudioSettings/CMake/1.0": { @@ -193,6 +233,52 @@ "macos-default" ] }, + { + "name": "ios-default", + "displayName": "iOS", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "ios.toolchain.cmake", + "CMAKE_INSTALL_PREFIX": "${sourceDir}/build/install", + "PLATFORM": "OS64", + "DEPLOYMENT_TARGET": "13.0", + "ENABLE_BITCODE": { + "type": "BOOL", + "value": false + } + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ + "macOS" + ] + } + } + }, + { + "name": "tvos-default", + "displayName": "tvOS", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "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 + } + }, + "vendor": { + "microsoft.com/VisualStudioSettings/CMake/1.0": { + "hostOS": [ + "macOS" + ] + } + } + }, { "name": "x-linux-ci", "hidden": true, @@ -232,9 +318,11 @@ "macos-default-relwithdebinfo" ], "cacheVariables": { - "CMAKE_C_COMPILER_LAUNCHER": "buildcache", - "CMAKE_CXX_COMPILER_LAUNCHER": "buildcache", - "CMAKE_OSX_ARCHITECTURES": "arm64;x86_64" + "CMAKE_OSX_ARCHITECTURES": "arm64;x86_64", + "IMGUI_USE_FREETYPE": { + "type": "BOOL", + "value": false + } } }, { @@ -295,6 +383,18 @@ "description": "Linux (Clang) release build with debug info", "displayName": "Linux (Clang) RelWithDebInfo" }, + { + "name": "linux-clang-debug-asan", + "configurePreset": "linux-clang-debug-asan", + "description": "Linux (Clang) debug build w/ ASAN", + "displayName": "Linux (Clang) Debug w/ ASAN" + }, + { + "name": "linux-clang-relwithdebinfo-asan", + "configurePreset": "linux-clang-relwithdebinfo-asan", + "description": "Linux (Clang) release build with debug info w/ ASAN", + "displayName": "Linux (Clang) RelWithDebInfo w/ ASAN" + }, { "name": "macos-default-debug", "configurePreset": "macos-default-debug", @@ -307,6 +407,24 @@ "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": [ + "metaforce" + ] + }, + { + "name": "tvos-default", + "configurePreset": "tvos-default", + "description": "tvOS release build with debug info", + "displayName": "tvOS RelWithDebInfo", + "targets": [ + "metaforce" + ] + }, { "name": "windows-msvc-debug", "configurePreset": "windows-msvc-debug", diff --git a/DataSpec/AssetMap32Download.cmake b/DataSpec/AssetMap32Download.cmake deleted file mode 100644 index d9a017057..000000000 --- a/DataSpec/AssetMap32Download.cmake +++ /dev/null @@ -1,3 +0,0 @@ -message(STATUS "32-bit asset name map not found; downloading to '${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap32.bin'") -file(DOWNLOAD "https://axiodl.com/files/AssetNameMap32.dat" - ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap32.bin SHOW_PROGRESS EXPECTED_HASH SHA1=90b4e941c192eef41c81e60314f348bc787d1336) diff --git a/DataSpec/AssetMap64Download.cmake b/DataSpec/AssetMap64Download.cmake deleted file mode 100644 index a5502f9b1..000000000 --- a/DataSpec/AssetMap64Download.cmake +++ /dev/null @@ -1,3 +0,0 @@ -message(STATUS "64-bit asset name map not found; downloading to '${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap64.bin'") -file(DOWNLOAD "https://axiodl.com/files/AssetNameMap64.dat" - ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap64.bin SHOW_PROGRESS EXPECTED_HASH SHA1=e49c03c9fff66adccec7af8120dda091636513e2) diff --git a/DataSpec/AssetNameMap.cpp b/DataSpec/AssetNameMap.cpp deleted file mode 100644 index 350feb0ae..000000000 --- a/DataSpec/AssetNameMap.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "AssetNameMap.hpp" -#include "athena/Compression.hpp" -#include "athena/MemoryReader.hpp" - -extern "C" const uint8_t ASSET_NAME_MP32[]; -extern "C" const size_t ASSET_NAME_MP32_SZ; -extern "C" const size_t ASSET_NAME_MP32_DECOMPRESSED_SZ; -extern "C" const uint8_t ASSET_NAME_MP64[]; -extern "C" const size_t ASSET_NAME_MP64_SZ; -extern "C" const size_t ASSET_NAME_MP64_DECOMPRESSED_SZ; - -namespace DataSpec::AssetNameMap { -logvisor::Module Log("AssetNameMap"); - -struct SAsset { - std::string name; - std::string directory; - hecl::FourCC type; - SAsset() = default; - SAsset(const hecl::FourCC& typeIn, athena::io::IStreamReader& in) : type(typeIn) { - uint32_t nameLen = in.readUint32Big(); - name = in.readString(nameLen); - uint32_t dirLen = in.readUint32Big(); - directory = in.readString(dirLen); - } -}; - -static std::unordered_map g_AssetNameMap; -static bool g_AssetNameMapInit = false; - -void LoadAssetMap(athena::io::MemoryReader& ar) { - if (!ar.hasError()) { - hecl::FourCC magic; - if (ar.length() >= 4) - ar.readBytesToBuf(&magic, 4); - if (magic != FOURCC('AIDM')) - Log.report( - logvisor::Warning, - FMT_STRING("Unable to load asset map; Assets will not have proper filenames for most files.")); - else { - uint32_t assetCount = ar.readUint32Big(); - g_AssetNameMap.reserve(assetCount); - for (uint32_t i = 0; i < assetCount; ++i) { - hecl::FourCC type; - ar.readBytesToBuf(&type, 4); - uint64_t id = ar.readUint64Big(); - g_AssetNameMap[id] = SAsset(type, ar); - } - } - } -} - -void InitAssetNameMap() { - if (g_AssetNameMapInit) - return; - - Log.report(logvisor::Info, FMT_STRING("Initializing asset name database...")); - - /* First load the 32bit map for MP1/2 */ - if (ASSET_NAME_MP32_DECOMPRESSED_SZ != 0u) { - auto* decompressed = new uint8_t[ASSET_NAME_MP32_DECOMPRESSED_SZ]; - athena::io::Compression::decompressZlib(ASSET_NAME_MP32, ASSET_NAME_MP32_SZ, decompressed, - ASSET_NAME_MP32_DECOMPRESSED_SZ); - athena::io::MemoryReader ar(decompressed, ASSET_NAME_MP32_DECOMPRESSED_SZ); - LoadAssetMap(ar); - delete[](decompressed); - } else { - Log.report( - logvisor::Warning, - FMT_STRING("AssetNameMap32 unavailable; Assets will not have proper filenames for most files.")); - } - /* Now load the 64bit map for MP3 */ - if (ASSET_NAME_MP64_DECOMPRESSED_SZ != 0u) { - auto* decompressed = new uint8_t[ASSET_NAME_MP64_DECOMPRESSED_SZ]; - athena::io::Compression::decompressZlib(ASSET_NAME_MP64, ASSET_NAME_MP64_SZ, decompressed, - ASSET_NAME_MP64_DECOMPRESSED_SZ); - athena::io::MemoryReader ar(decompressed, ASSET_NAME_MP64_DECOMPRESSED_SZ); - LoadAssetMap(ar); - delete[](decompressed); - } else { - Log.report( - logvisor::Warning, - FMT_STRING("AssetNameMap64 unavailable; Assets will not have proper filenames for most files.")); - } - g_AssetNameMapInit = true; -} - -const std::string* TranslateIdToName(const UniqueID32& id) { - if (g_AssetNameMap.find(id.toUint64()) == g_AssetNameMap.cend()) - return nullptr; - - return &g_AssetNameMap[id.toUint64()].name; -} - -} // namespace DataSpec::AssetNameMap diff --git a/DataSpec/AssetNameMap.hpp b/DataSpec/AssetNameMap.hpp deleted file mode 100644 index fb3e5c49c..000000000 --- a/DataSpec/AssetNameMap.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include -#include -#include "DNACommon/DNACommon.hpp" - -namespace DataSpec::AssetNameMap { -void InitAssetNameMap(); -const std::string* TranslateIdToName(const UniqueID32&); -const std::string* TranslateIdToName(const UniqueID64&); -} // namespace DataSpec::AssetNameMap diff --git a/DataSpec/AssetNameMapNull.cpp b/DataSpec/AssetNameMapNull.cpp deleted file mode 100644 index b077d2a0f..000000000 --- a/DataSpec/AssetNameMapNull.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -#include - -extern "C" const uint8_t ASSET_NAME_MP32[] = {0}; -extern "C" const size_t ASSET_NAME_MP32_SZ = 0; -extern "C" const size_t ASSET_NAME_MP32_DECOMPRESSED_SZ = 0; -extern "C" const uint8_t ASSET_NAME_MP64[] = {0}; -extern "C" const size_t ASSET_NAME_MP64_SZ = 0; -extern "C" const size_t ASSET_NAME_MP64_DECOMPRESSED_SZ = 0; diff --git a/DataSpec/Blender/BlenderSupport.cpp b/DataSpec/Blender/BlenderSupport.cpp deleted file mode 100644 index b5fef6587..000000000 --- a/DataSpec/Blender/BlenderSupport.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include "hecl/Blender/Connection.hpp" -#include "BlenderSupport.hpp" - -extern "C" uint8_t RETRO_MASTER_SHADER[]; -extern "C" size_t RETRO_MASTER_SHADER_SZ; - -namespace DataSpec::Blender { - -bool BuildMasterShader(const hecl::ProjectPath& path) { - hecl::blender::Connection& conn = hecl::blender::Connection::SharedConnection(); - if (!conn.createBlend(path, hecl::blender::BlendType::None)) - return false; - { - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << std::string_view((char*)RETRO_MASTER_SHADER, RETRO_MASTER_SHADER_SZ); - os << "make_master_shader_library()\n"sv; - } - return conn.saveBlend(); -} - -} // namespace DataSpec::Blender diff --git a/DataSpec/Blender/BlenderSupport.hpp b/DataSpec/Blender/BlenderSupport.hpp deleted file mode 100644 index 8a5cd7eca..000000000 --- a/DataSpec/Blender/BlenderSupport.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include - -namespace DataSpec::Blender { - -bool BuildMasterShader(const hecl::ProjectPath& path); - -} diff --git a/DataSpec/Blender/RetroMasterShader.py b/DataSpec/Blender/RetroMasterShader.py deleted file mode 100644 index 70f837978..000000000 --- a/DataSpec/Blender/RetroMasterShader.py +++ /dev/null @@ -1,1876 +0,0 @@ -"Defines node groups implementing shader components found in Retro games" - -import bpy - - -# Root Eevee Nodes - -# Additive output node -def make_additive_output(): - new_grp = bpy.data.node_groups.new('HECLAdditiveOutput', 'ShaderNodeTree') - shader_input = new_grp.inputs.new('NodeSocketShader', 'Surface') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (0, 0) - - # Add Shader - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (200, 0) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (0, 100) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') - mat_out.location = (400, 0) - - # Links - new_grp.links.new(grp_in.outputs['Surface'], emissive_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs[0], emissive_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs[0], mat_out.inputs['Surface']) - - -# Blend output node -def make_blend_opaque_output(): - for tp in ('HECLBlendOutput', 'HECLOpaqueOutput'): - new_grp = bpy.data.node_groups.new(tp, 'ShaderNodeTree') - shader_input = new_grp.inputs.new('NodeSocketShader', 'Surface') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (0, 0) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('ShaderNodeOutputMaterial') - mat_out.location = (200, 0) - - # Links - new_grp.links.new(grp_in.outputs['Surface'], mat_out.inputs['Surface']) - - -# 0 - RetroShader -def make_retro_shader(): - new_grp = bpy.data.node_groups.new('RetroShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_mod_input = new_grp.inputs.new('NodeSocketColor', 'DiffuseMod') - diffuse_mod_input.default_value = (1.0, 1.0, 1.0, 1.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - alpha_mod_input = new_grp.inputs.new('NodeSocketFloatFactor', 'AlphaMod') - alpha_mod_input.default_value = 1.0 - alpha_mod_input.min_value = 0.0 - alpha_mod_input.max_value = 1.0 - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1280, 27) - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1280, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiples diffuse with diffusemod) - diffuse_mult = new_grp.nodes.new('ShaderNodeMixRGB') - diffuse_mult.location = (-1094, 122) - diffuse_mult.blend_type = 'MULTIPLY' - diffuse_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiples alpha with alphamod) - alpha_mult = new_grp.nodes.new('ShaderNodeMath') - alpha_mult.location = (-1094, -178) - alpha_mult.operation = 'MULTIPLY' - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Group outputs (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DiffuseMod'], diffuse_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_mult.inputs[0]) - new_grp.links.new(grp_in.outputs['AlphaMod'], alpha_mult.inputs[1]) - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_mult.inputs['Color1']) - new_grp.links.new(diffuse_mult.outputs['Color'], lightmap_mult.inputs['Color2']) - new_grp.links.new(diffuse_mult.outputs['Color'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(diffuse_mult.outputs['Color'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(grp_in.outputs['Emissive'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(alpha_mult.outputs[0], alpha_mix.inputs['Fac']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -def make_retro_dynamic_shader(): - new_grp = bpy.data.node_groups.new('RetroDynamicShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest') - dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0) - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1460, 27) - - # Multiply (Lightmap dynamic) - lightmap_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_dynamic.location = (-1174, 158) - lightmap_dynamic.blend_type = 'MULTIPLY' - lightmap_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Diffuse dynamic) - diffuse_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - diffuse_dynamic.location = (-1174, -32) - diffuse_dynamic.blend_type = 'MULTIPLY' - diffuse_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Emissive dynamic) - emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - emissive_dynamic.location = (-1174, -222) - emissive_dynamic.blend_type = 'MULTIPLY' - emissive_dynamic.inputs['Fac'].default_value = 1.0 - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1460, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Group outputs (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], lightmap_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], diffuse_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2']) - new_grp.links.new(lightmap_dynamic.outputs['Color'], lightmap_mult.inputs['Color1']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], lightmap_mult.inputs['Color2']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_mix.inputs['Fac']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -def make_retro_dynamic_alpha_shader(): - new_grp = bpy.data.node_groups.new('RetroDynamicAlphaShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest') - dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0) - dynamic_alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'DynamicAlphaTest') - dynamic_alpha_input.default_value = 1.0 - dynamic_alpha_input.min_value = 0.0 - dynamic_alpha_input.max_value = 1.0 - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1460, 27) - - # Multiply (Lightmap dynamic) - lightmap_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_dynamic.location = (-1174, 158) - lightmap_dynamic.blend_type = 'MULTIPLY' - lightmap_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Diffuse dynamic) - diffuse_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - diffuse_dynamic.location = (-1174, -32) - diffuse_dynamic.blend_type = 'MULTIPLY' - diffuse_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Emissive dynamic) - emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - emissive_dynamic.location = (-1174, -222) - emissive_dynamic.blend_type = 'MULTIPLY' - emissive_dynamic.inputs['Fac'].default_value = 1.0 - - # Multiply (Alpha dynamic) - alpha_dynamic = new_grp.nodes.new('ShaderNodeMath') - alpha_dynamic.location = (-1174, -410) - alpha_dynamic.operation = 'MULTIPLY' - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1460, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], lightmap_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], diffuse_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_dynamic.inputs[0]) - new_grp.links.new(grp_in.outputs['DynamicAlphaTest'], alpha_dynamic.inputs[1]) - new_grp.links.new(lightmap_dynamic.outputs['Color'], lightmap_mult.inputs['Color1']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], lightmap_mult.inputs['Color2']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(diffuse_dynamic.outputs['Color'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(alpha_dynamic.outputs['Value'], alpha_mix.inputs['Fac']) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -def make_retro_dynamic_character_shader(): - new_grp = bpy.data.node_groups.new('RetroDynamicCharacterShader', 'ShaderNodeTree') - surface_output = new_grp.outputs.new('NodeSocketShader', 'Surface') - lightmap_input = new_grp.inputs.new('NodeSocketColor', 'Lightmap') - lightmap_input.default_value = (0.0, 0.0, 0.0, 0.0) - diffuse_input = new_grp.inputs.new('NodeSocketColor', 'Diffuse') - diffuse_input.default_value = (0.0, 0.0, 0.0, 0.0) - emissive_input = new_grp.inputs.new('NodeSocketColor', 'Emissive') - emissive_input.default_value = (0.0, 0.0, 0.0, 0.0) - specular_input = new_grp.inputs.new('NodeSocketColor', 'Specular') - specular_input.default_value = (0.0, 0.0, 0.0, 0.0) - ext_spec_input = new_grp.inputs.new('NodeSocketColor', 'ExtendedSpecular') - ext_spec_input.default_value = (0.0, 0.0, 0.0, 0.0) - reflection_input = new_grp.inputs.new('NodeSocketColor', 'Reflection') - reflection_input.default_value = (0.0, 0.0, 0.0, 0.0) - indirect_tex = new_grp.inputs.new('NodeSocketColor', 'IndirectTex') - indirect_tex.default_value = (0.0, 0.0, 0.0, 0.0) - alpha_input = new_grp.inputs.new('NodeSocketFloatFactor', 'Alpha') - alpha_input.default_value = 1.0 - alpha_input.min_value = 0.0 - alpha_input.max_value = 1.0 - dynamic_input = new_grp.inputs.new('NodeSocketColor', 'DynamicTest') - dynamic_input.default_value = (1.0, 1.0, 1.0, 1.0) - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1460, 27) - - # Multiply (Emissive dynamic) - emissive_dynamic = new_grp.nodes.new('ShaderNodeMixRGB') - emissive_dynamic.location = (-1174, -32) - emissive_dynamic.blend_type = 'MULTIPLY' - emissive_dynamic.inputs['Fac'].default_value = 1.0 - - # New shader model - new_shader_model = new_grp.nodes.new('ShaderNodeValue') - new_shader_model.name = 'NewShaderModel' - new_shader_model.label = 'NewShaderModel' - new_shader_model.location = (-1460, 118) - new_shader_model.outputs[0].default_value = 0.0 - - # Principled BSDF (For new shader model) - principled_bsdf = new_grp.nodes.new('ShaderNodeBsdfPrincipled') - principled_bsdf.location = (-1038, 874) - principled_bsdf.inputs['Metallic'].default_value = 0.5 - - # Invert (for roughness) - invert = new_grp.nodes.new('ShaderNodeInvert') - invert.location = (-1256, 492) - invert.inputs[0].default_value = 1.0 - - # Gamma (for roughness) - gamma = new_grp.nodes.new('ShaderNodeGamma') - gamma.location = (-1256, 640) - gamma.inputs[1].default_value = 10.0 - - # Diffuse BSDF (Multiplies dynamic lighting with diffuse) - diffuse_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - diffuse_bdsf.location = (-945, 293) - - # Mix shader (interpolates Principled and Diffuse BSDF) - new_shader_model_mix1 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix1.location = (-760, 340) - - # Multiply (Multiplies static lightmap with diffuse) - lightmap_mult = new_grp.nodes.new('ShaderNodeMixRGB') - lightmap_mult.location = (-944, 122) - lightmap_mult.blend_type = 'MULTIPLY' - lightmap_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies specular with reflection) - specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - specular_mult.location = (-940, -105) - specular_mult.blend_type = 'MULTIPLY' - specular_mult.inputs['Fac'].default_value = 1.0 - - # Multiply (Multiplies extended specular with reflection) - extended_specular_mult = new_grp.nodes.new('ShaderNodeMixRGB') - extended_specular_mult.location = (-941, -304) - extended_specular_mult.blend_type = 'MULTIPLY' - extended_specular_mult.inputs['Fac'].default_value = 1.0 - - # Add Shader (Adds dynamic diffuse with static diffuse) - diffuse_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - diffuse_add_shader.location = (-587, 209) - - # Mix shader (interpolates resolved reflection with nothing) - new_shader_model_mix2 = new_grp.nodes.new('ShaderNodeMixShader') - new_shader_model_mix2.location = (-512, -38) - - # Add Shader (Adds emissive with resolved reflection) - emissive_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - emissive_add_shader.location = (-320, 8) - - # Add Shader (Adds specular and extended specular reflections) - specular_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - specular_add_shader.location = (-734, -81) - - # Diffuse BDSF (Multiplies extended specular with dynamic lighting) - extended_specular_bdsf = new_grp.nodes.new('ShaderNodeBsdfDiffuse') - extended_specular_bdsf.location = (-738, -280) - - # Add shader (Adds diffuse with all emissive sources) - final_add_shader = new_grp.nodes.new('ShaderNodeAddShader') - final_add_shader.location = (-184, 234) - - # Transparent BDSF (Provides alpha) - transparent_bdsf = new_grp.nodes.new('ShaderNodeBsdfTransparent') - transparent_bdsf.location = (-224, -160) - transparent_bdsf.inputs['Color'].default_value = (1.0, 1.0, 1.0, 1.0) - - # Mix Shader (Applies alpha proportion) - alpha_mix = new_grp.nodes.new('ShaderNodeMixShader') - alpha_mix.location = (-40, -112) - - # Material Output (Final output) - mat_out = new_grp.nodes.new('NodeGroupOutput') - mat_out.location = (150, -88) - - # Links - new_grp.links.new(grp_in.outputs['Emissive'], emissive_dynamic.inputs['Color1']) - new_grp.links.new(grp_in.outputs['DynamicTest'], emissive_dynamic.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Lightmap'], lightmap_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Diffuse'], lightmap_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Diffuse'], diffuse_bdsf.inputs['Color']) - new_grp.links.new(grp_in.outputs['Diffuse'], principled_bsdf.inputs['Base Color']) - new_grp.links.new(emissive_dynamic.outputs['Color'], emissive_add_shader.inputs[0]) - new_grp.links.new(grp_in.outputs['Specular'], specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Specular'], principled_bsdf.inputs['Specular']) - new_grp.links.new(grp_in.outputs['ExtendedSpecular'], extended_specular_mult.inputs['Color1']) - new_grp.links.new(grp_in.outputs['Reflection'], specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Reflection'], extended_specular_mult.inputs['Color2']) - new_grp.links.new(grp_in.outputs['Alpha'], alpha_mix.inputs['Fac']) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix1.inputs[0]) - new_grp.links.new(diffuse_bdsf.outputs['BSDF'], new_shader_model_mix1.inputs[1]) - new_grp.links.new(grp_in.outputs['Specular'], invert.inputs['Color']) - new_grp.links.new(invert.outputs['Color'], gamma.inputs['Color']) - new_grp.links.new(gamma.outputs['Color'], principled_bsdf.inputs['Roughness']) - new_grp.links.new(principled_bsdf.outputs['BSDF'], new_shader_model_mix1.inputs[2]) - new_grp.links.new(new_shader_model_mix1.outputs['Shader'], diffuse_add_shader.inputs[0]) - new_grp.links.new(lightmap_mult.outputs['Color'], diffuse_add_shader.inputs[1]) - new_grp.links.new(specular_mult.outputs['Color'], specular_add_shader.inputs[0]) - new_grp.links.new(extended_specular_mult.outputs['Color'], extended_specular_bdsf.inputs['Color']) - new_grp.links.new(extended_specular_bdsf.outputs['BSDF'], specular_add_shader.inputs[1]) - new_grp.links.new(new_shader_model.outputs['Value'], new_shader_model_mix2.inputs[0]) - new_grp.links.new(specular_add_shader.outputs['Shader'], new_shader_model_mix2.inputs[1]) - new_grp.links.new(new_shader_model_mix2.outputs['Shader'], emissive_add_shader.inputs[1]) - new_grp.links.new(diffuse_add_shader.outputs['Shader'], final_add_shader.inputs[0]) - new_grp.links.new(emissive_add_shader.outputs['Shader'], final_add_shader.inputs[1]) - new_grp.links.new(transparent_bdsf.outputs['BSDF'], alpha_mix.inputs[1]) - new_grp.links.new(final_add_shader.outputs['Shader'], alpha_mix.inputs[2]) - new_grp.links.new(alpha_mix.outputs['Shader'], mat_out.inputs['Surface']) - - -# MP3 / DKCR Material Passes: -# https://wiki.axiodl.com/w/Materials_(Metroid_Prime_3) - -def make_retro_shader_mp3_color(): - new_grp = bpy.data.node_groups.new("__RetroShaderMP3Color", "ShaderNodeTree") - new_grp.use_fake_user = True - input = new_grp.inputs.new("NodeSocketColor", "DIFFC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "DIFBC") - input.default_value = (1.0, 1.0, 1.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "CLRC") - input.default_value = (0.5, 0.5, 0.5, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "CLRA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "TRAN") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLDC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "RFLDA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLV") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LRLD") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LURDC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "LURDA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "INCAC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketInt", "Add INCA") - input.default_value = 0 - input.min_value = 0 - input.max_value = 1 - input = new_grp.inputs.new("NodeSocketFloatFactor", "OPAC") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - new_grp.outputs.new("NodeSocketShader", "Shader") - nodes = {} - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.004" - nodes["Diffuse BSDF.004"] = node - node.label = "" - node.location = (-196.910400390625, -503.60546875) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.009" - nodes["Add Shader.009"] = node - node.label = "" - node.location = (14.618888854980469, -571.516357421875) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.008" - nodes["Add Shader.008"] = node - node.label = "" - node.location = (6.4276123046875, -926.3602905273438) - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.005" - nodes["Diffuse BSDF.005"] = node - node.label = "" - node.location = (-189.85516357421875, -865.79345703125) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.005" - nodes["Mix.005"] = node - node.label = "" - node.location = (-190.5804901123047, -1017.0886840820312) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.004" - nodes["Mix.004"] = node - node.label = "" - node.location = (-381.6676940917969, -870.815673828125) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.006" - nodes["Add Shader.006"] = node - node.label = "" - node.location = (220.7507781982422, -724.6066284179688) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.005" - nodes["Add Shader.005"] = node - node.label = "" - node.location = (218.0698699951172, -528.0934448242188) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.007" - nodes["Add Shader.007"] = node - node.label = "" - node.location = (388.0714416503906, -600.8295288085938) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.002" - nodes["Mix.002"] = node - node.label = "" - node.location = (-192.1793212890625, -281.65264892578125) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.010" - nodes["Add Shader.010"] = node - node.label = "" - node.location = (522.2215576171875, -284.7532653808594) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.001" - nodes["Mix.001"] = node - node.label = "" - node.location = (-198.2812957763672, -13.079503059387207) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.001" - nodes["Diffuse BSDF.001"] = node - node.label = "" - node.location = (-200.4605255126953, 138.9542694091797) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.001" - nodes["Add Shader.001"] = node - node.label = "" - node.location = (-14.161624908447266, 32.61324691772461) - node = new_grp.nodes.new("NodeGroupOutput") - node.name = "Group Output" - nodes["Group Output"] = node - node.label = "" - node.location = (948.8831176757812, -299.1160583496094) - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF.001" - nodes["Transparent BSDF.001"] = node - node.label = "" - node.location = (604.5911254882812, -88.7776870727539) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("ShaderNodeMixShader") - node.name = "Mix Shader" - nodes["Mix Shader"] = node - node.label = "" - node.location = (772.179443359375, -91.1546401977539) - node.inputs[0].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.012" - nodes["Add Shader.012"] = node - node.label = "" - node.location = (776.751953125, -432.8694152832031) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.011" - nodes["Add Shader.011"] = node - node.label = "" - node.location = (779.857177734375, -294.9550476074219) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.006" - nodes["Mix.006"] = node - node.label = "" - node.location = (-192.534912109375, -643.984619140625) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix.003" - nodes["Mix.003"] = node - node.label = "" - node.location = (-374.2341003417969, -515.1140747070312) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMixRGB") - node.name = "Mix" - nodes["Mix"] = node - node.label = "" - node.location = (-500.3056640625, -114.82369995117188) - node.blend_type = "MULTIPLY" - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math" - nodes["Math"] = node - node.label = "" - node.location = (454.39404296875, 96.02081298828125) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.001" - nodes["Math.001"] = node - node.label = "" - node.location = (619.3079223632812, 90.52423095703125) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.002" - nodes["Math.002"] = node - node.label = "" - node.location = (785.3211059570312, 81.7295913696289) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF" - nodes["Transparent BSDF"] = node - node.label = "" - node.location = (597.9944458007812, -480.7802734375) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("NodeGroupInput") - node.name = "Group Input" - nodes["Group Input"] = node - node.label = "" - node.location = (-669.6587524414062, -193.9534149169922) - new_grp.links.new(nodes["Group Input"].outputs[0], nodes["Mix"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[1], nodes["Mix"].inputs[2]) - new_grp.links.new(nodes["Mix"].outputs[0], nodes["Mix.001"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Mix.001"].inputs[2]) - new_grp.links.new(nodes["Mix.001"].outputs[0], nodes["Add Shader.001"].inputs[1]) - new_grp.links.new(nodes["Diffuse BSDF.001"].outputs[0], nodes["Add Shader.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Diffuse BSDF.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Mix.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[7], nodes["Mix.002"].inputs[2]) - new_grp.links.new(nodes["Mix.002"].outputs[0], nodes["Add Shader.005"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Mix.003"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Mix.003"].inputs[2]) - new_grp.links.new(nodes["Mix.003"].outputs[0], nodes["Diffuse BSDF.004"].inputs[0]) - new_grp.links.new(nodes["Diffuse BSDF.004"].outputs[0], nodes["Add Shader.009"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Mix.004"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Mix.004"].inputs[2]) - new_grp.links.new(nodes["Mix.004"].outputs[0], nodes["Diffuse BSDF.005"].inputs[0]) - new_grp.links.new(nodes["Diffuse BSDF.005"].outputs[0], nodes["Add Shader.008"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Add Shader.006"].inputs[0]) - new_grp.links.new(nodes["Add Shader.005"].outputs[0], nodes["Add Shader.007"].inputs[0]) - new_grp.links.new(nodes["Add Shader.006"].outputs[0], nodes["Add Shader.007"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Mix.005"].inputs[2]) - new_grp.links.new(nodes["Mix"].outputs[0], nodes["Mix.005"].inputs[1]) - new_grp.links.new(nodes["Add Shader.008"].outputs[0], nodes["Add Shader.006"].inputs[1]) - new_grp.links.new(nodes["Mix.005"].outputs[0], nodes["Add Shader.008"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Mix.006"].inputs[2]) - new_grp.links.new(nodes["Mix"].outputs[0], nodes["Mix.006"].inputs[1]) - new_grp.links.new(nodes["Add Shader.009"].outputs[0], nodes["Add Shader.005"].inputs[1]) - new_grp.links.new(nodes["Mix.006"].outputs[0], nodes["Add Shader.009"].inputs[1]) - new_grp.links.new(nodes["Add Shader.007"].outputs[0], nodes["Add Shader.010"].inputs[1]) - new_grp.links.new(nodes["Add Shader.001"].outputs[0], nodes["Add Shader.010"].inputs[0]) - new_grp.links.new(nodes["Transparent BSDF"].outputs[0], nodes["Add Shader.012"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[11], nodes["Add Shader.012"].inputs[0]) - new_grp.links.new(nodes["Add Shader.012"].outputs[0], nodes["Add Shader.011"].inputs[1]) - new_grp.links.new(nodes["Add Shader.011"].outputs[0], nodes["Group Output"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[3], nodes["Math"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[13], nodes["Math"].inputs[1]) - new_grp.links.new(nodes["Math"].outputs[0], nodes["Math.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[4], nodes["Math.001"].inputs[1]) - new_grp.links.new(nodes["Math.001"].outputs[0], nodes["Math.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[6], nodes["Math.002"].inputs[0]) - new_grp.links.new(nodes["Math.002"].outputs[0], nodes["Mix Shader"].inputs[0]) - new_grp.links.new(nodes["Transparent BSDF.001"].outputs[0], nodes["Mix Shader"].inputs[1]) - new_grp.links.new(nodes["Add Shader.010"].outputs[0], nodes["Mix Shader"].inputs[2]) - new_grp.links.new(nodes["Mix Shader"].outputs[0], nodes["Add Shader.011"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[12], nodes["Transparent BSDF"].inputs[0]) - - -def make_retro_shader_mp3_bloom(): - new_grp = bpy.data.node_groups.new("__RetroShaderMP3Bloom", "ShaderNodeTree") - new_grp.use_fake_user = True - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFFA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFBA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOL") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOD") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLODB") - input.default_value = 0.5 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "TRAN") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "INCAA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BNIF") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOI") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOIB") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "OPAC") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketInt", "Add INCA") - input.default_value = 0 - input.min_value = 0 - input.max_value = 1 - new_grp.outputs.new("NodeSocketShader", "Shader") - nodes = {} - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.003" - nodes["Math.003"] = node - node.label = "" - node.location = (-131.26889038085938, -228.6888885498047) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math" - nodes["Math"] = node - node.label = "" - node.location = (-501.6487731933594, -144.7719268798828) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.002" - nodes["Math.002"] = node - node.label = "" - node.location = (-328.3370666503906, -209.53160095214844) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("NodeGroupOutput") - node.name = "Group Output" - nodes["Group Output"] = node - node.label = "" - node.location = (1109.7938232421875, -257.2006530761719) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.001" - nodes["Math.001"] = node - node.label = "" - node.location = (129.59579467773438, -299.0679626464844) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeBsdfDiffuse") - node.name = "Diffuse BSDF.002" - nodes["Diffuse BSDF.002"] = node - node.label = "" - node.location = (122.80331420898438, -150.7427520751953) - node.inputs[0].default_value = (0.800000011920929, 0.800000011920929, 0.800000011920929, 1.0) - node.inputs[1].default_value = 0.0 - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.002" - nodes["Add Shader.002"] = node - node.label = "" - node.location = (312.7171325683594, -220.0266571044922) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.005" - nodes["Add Shader.005"] = node - node.label = "" - node.location = (-165.06072998046875, -549.3956298828125) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.006" - nodes["Add Shader.006"] = node - node.label = "" - node.location = (20.3157958984375, -545.8302612304688) - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF.001" - nodes["Transparent BSDF.001"] = node - node.label = "" - node.location = (205.5854034423828, -558.1273803710938) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader.001" - nodes["Add Shader.001"] = node - node.label = "" - node.location = (399.876708984375, -533.2184448242188) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.004" - nodes["Math.004"] = node - node.label = "" - node.location = (-354.23876953125, -508.8504943847656) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeAddShader") - node.name = "Add Shader" - nodes["Add Shader"] = node - node.label = "" - node.location = (875.3080444335938, -248.47450256347656) - node = new_grp.nodes.new("ShaderNodeBsdfTransparent") - node.name = "Transparent BSDF" - nodes["Transparent BSDF"] = node - node.label = "" - node.location = (502.63671875, -341.6871032714844) - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node = new_grp.nodes.new("ShaderNodeMath") - node.name = "Math.006" - nodes["Math.006"] = node - node.label = "" - node.location = (505.8763122558594, -171.7743377685547) - node.operation = "MULTIPLY" - node.inputs[0].default_value = 0.5 - node.inputs[1].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeMixShader") - node.name = "Mix Shader" - nodes["Mix Shader"] = node - node.label = "" - node.location = (682.0885620117188, -169.31057739257812) - node.inputs[0].default_value = 0.5 - node = new_grp.nodes.new("NodeGroupInput") - node.name = "Group Input" - nodes["Group Input"] = node - node.label = "" - node.location = (-669.6587524414062, -193.9534149169922) - new_grp.links.new(nodes["Group Input"].outputs[0], nodes["Math"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[1], nodes["Math"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[3], nodes["Math.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[4], nodes["Math.003"].inputs[1]) - new_grp.links.new(nodes["Math.002"].outputs[0], nodes["Math.003"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Math.002"].inputs[0]) - new_grp.links.new(nodes["Math"].outputs[0], nodes["Math.001"].inputs[0]) - new_grp.links.new(nodes["Diffuse BSDF.002"].outputs[0], nodes["Add Shader.002"].inputs[0]) - new_grp.links.new(nodes["Math.001"].outputs[0], nodes["Add Shader.002"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Math.006"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Math.006"].inputs[0]) - new_grp.links.new(nodes["Math.006"].outputs[0], nodes["Mix Shader"].inputs[0]) - new_grp.links.new(nodes["Transparent BSDF"].outputs[0], nodes["Mix Shader"].inputs[1]) - new_grp.links.new(nodes["Transparent BSDF.001"].outputs[0], nodes["Add Shader.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[6], nodes["Math.004"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[7], nodes["Math.004"].inputs[1]) - new_grp.links.new(nodes["Math.003"].outputs[0], nodes["Math.001"].inputs[1]) - new_grp.links.new(nodes["Math.003"].outputs[0], nodes["Diffuse BSDF.002"].inputs[0]) - new_grp.links.new(nodes["Math.004"].outputs[0], nodes["Add Shader.005"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Add Shader.005"].inputs[1]) - new_grp.links.new(nodes["Add Shader.005"].outputs[0], nodes["Add Shader.006"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Add Shader.006"].inputs[1]) - new_grp.links.new(nodes["Add Shader.006"].outputs[0], nodes["Add Shader.001"].inputs[1]) - new_grp.links.new(nodes["Add Shader"].outputs[0], nodes["Group Output"].inputs[0]) - new_grp.links.new(nodes["Mix Shader"].outputs[0], nodes["Add Shader"].inputs[0]) - new_grp.links.new(nodes["Add Shader.002"].outputs[0], nodes["Mix Shader"].inputs[2]) - new_grp.links.new(nodes["Add Shader.001"].outputs[0], nodes["Add Shader"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[11], nodes["Transparent BSDF.001"].inputs[0]) - - -def make_retro_shader_mp3(): - new_grp = bpy.data.node_groups.new("RetroShaderMP3", "ShaderNodeTree") - new_grp.use_fake_user = True - input = new_grp.inputs.new("NodeSocketColor", "DIFFC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFFA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "DIFBC") - input.default_value = (1.0, 1.0, 1.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "DIFBA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOL") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOD") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLODB") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "CLR") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "CLRA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "TRAN") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLD") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "RFLDA") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "RFLV") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LRLD") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketColor", "LURDC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "LURDA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketColor", "INCAC") - input.default_value = (0.0, 0.0, 0.0, 1.0) - input = new_grp.inputs.new("NodeSocketFloatFactor", "INCAA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketInt", "Add INCA") - input.default_value = 0 - input.min_value = 0 - input.max_value = 1 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BNIF") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOI") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "BLOIB") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "OPAC") - input.default_value = 1.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "XRAYC") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "XRAYA") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - input = new_grp.inputs.new("NodeSocketFloatFactor", "XRBR") - input.default_value = 0.0 - input.min_value = 0.000000 - input.max_value = 1.000000 - nodes = {} - node = new_grp.nodes.new("ShaderNodeMixShader") - node.name = "Mix Shader" - nodes["Mix Shader"] = node - node.label = "" - node.location = (-118.33348846435547, -291.9857482910156) - node.inputs[0].default_value = 0.0 - node = new_grp.nodes.new("ShaderNodeOutputMaterial") - node.name = "Material Output" - nodes["Material Output"] = node - node.label = "" - node.location = (81.25957489013672, -265.6065368652344) - node.inputs[2].default_value = (0.0, 0.0, 0.0) - node = new_grp.nodes.new("ShaderNodeGroup") - node.name = "Group.001" - nodes["Group.001"] = node - node.label = "" - node.location = (-358.6896057128906, -60.17391586303711) - node.node_tree = bpy.data.node_groups["__RetroShaderMP3Color"] - node.inputs[0].default_value = (1.0, 1.0, 1.0, 1.0) - node.inputs[1].default_value = (1.0, 1.0, 1.0, 1.0) - node.inputs[2].default_value = (0.5, 0.5, 0.5, 1.0) - node.inputs[3].default_value = 0.5 - node.inputs[4].default_value = 0.5 - node.inputs[5].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[6].default_value = 0.5 - node.inputs[7].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[8].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[9].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[10].default_value = 0.0 - node.inputs[11].default_value = (0.0, 0.0, 0.0, 1.0) - node.inputs[12].default_value = 0 - node.inputs[13].default_value = 0.5 - node = new_grp.nodes.new("ShaderNodeGroup") - node.name = "Group" - nodes["Group"] = node - node.label = "" - node.location = (-356.9021301269531, -446.9474182128906) - node.node_tree = bpy.data.node_groups["__RetroShaderMP3Bloom"] - node.inputs[0].default_value = 1.0 - node.inputs[1].default_value = 1.0 - node.inputs[2].default_value = 0.0 - node.inputs[3].default_value = 0.0 - node.inputs[4].default_value = 0.5 - node.inputs[5].default_value = 0.5 - node.inputs[6].default_value = 0.0 - node.inputs[7].default_value = 0.0 - node.inputs[8].default_value = 0.0 - node.inputs[9].default_value = 0.0 - node.inputs[10].default_value = 0.5 - node.inputs[11].default_value = 0 - node = new_grp.nodes.new("NodeGroupInput") - node.name = "Group Input" - nodes["Group Input"] = node - node.label = "" - node.location = (-669.6587524414062, -193.9534149169922) - new_grp.links.new(nodes["Group Input"].outputs[0], nodes["Group.001"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[1], nodes["Group"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[3], nodes["Group"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[4], nodes["Group"].inputs[2]) - new_grp.links.new(nodes["Group Input"].outputs[5], nodes["Group"].inputs[3]) - new_grp.links.new(nodes["Group Input"].outputs[6], nodes["Group"].inputs[4]) - new_grp.links.new(nodes["Group Input"].outputs[17], nodes["Group"].inputs[6]) - new_grp.links.new(nodes["Group Input"].outputs[19], nodes["Group"].inputs[7]) - new_grp.links.new(nodes["Group Input"].outputs[20], nodes["Group"].inputs[8]) - new_grp.links.new(nodes["Group Input"].outputs[2], nodes["Group.001"].inputs[1]) - new_grp.links.new(nodes["Group Input"].outputs[7], nodes["Group.001"].inputs[2]) - new_grp.links.new(nodes["Group Input"].outputs[10], nodes["Group.001"].inputs[5]) - new_grp.links.new(nodes["Group Input"].outputs[12], nodes["Group.001"].inputs[7]) - new_grp.links.new(nodes["Group Input"].outputs[13], nodes["Group.001"].inputs[8]) - new_grp.links.new(nodes["Group Input"].outputs[14], nodes["Group.001"].inputs[9]) - new_grp.links.new(nodes["Group Input"].outputs[15], nodes["Group.001"].inputs[10]) - new_grp.links.new(nodes["Group Input"].outputs[16], nodes["Group.001"].inputs[11]) - new_grp.links.new(nodes["Group.001"].outputs[0], nodes["Mix Shader"].inputs[1]) - new_grp.links.new(nodes["Group"].outputs[0], nodes["Mix Shader"].inputs[2]) - new_grp.links.new(nodes["Mix Shader"].outputs[0], nodes["Material Output"].inputs[0]) - new_grp.links.new(nodes["Group Input"].outputs[21], nodes["Group"].inputs[9]) - new_grp.links.new(nodes["Group Input"].outputs[8], nodes["Group.001"].inputs[3]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Group.001"].inputs[4]) - new_grp.links.new(nodes["Group Input"].outputs[11], nodes["Group.001"].inputs[6]) - new_grp.links.new(nodes["Group Input"].outputs[22], nodes["Group.001"].inputs[13]) - new_grp.links.new(nodes["Group Input"].outputs[9], nodes["Group"].inputs[5]) - new_grp.links.new(nodes["Group Input"].outputs[22], nodes["Group"].inputs[10]) - new_grp.links.new(nodes["Group Input"].outputs[18], nodes["Group.001"].inputs[12]) - new_grp.links.new(nodes["Group Input"].outputs[18], nodes["Group"].inputs[11]) - - -ROOT_SHADER_GROUPS = ( - make_retro_shader, - make_retro_dynamic_shader, - make_retro_dynamic_alpha_shader, - make_retro_dynamic_character_shader, - make_retro_shader_mp3_color, - make_retro_shader_mp3_bloom, - make_retro_shader_mp3 -) - - -# UV animation nodes: -# https://wiki.axiodl.com/w/Materials_(Metroid_Prime)#UV_Animations - -# 0 - Modelview Inverse (zero translation) -def make_uva0(): - new_grp = bpy.data.node_groups.new('RetroUVMode0NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-100, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (1000, 0) - - # Vector Transform to bring world space into camera space - vec_xf = new_grp.nodes.new('ShaderNodeVectorTransform') - vec_xf.location = (100, 0) - vec_xf.vector_type = 'NORMAL' - vec_xf.convert_from = 'WORLD' - vec_xf.convert_to = 'CAMERA' - - # UV scale (to match GameCube's UV-coordinate space) - uv_scale = new_grp.nodes.new('ShaderNodeMapping') - uv_scale.location = (400, -400) - uv_scale.vector_type = 'TEXTURE' - uv_scale.inputs['Scale'].default_value = (2.0, 2.0, 0.0) - uv_scale.inputs['Location'].default_value = (1.0, 1.0, 0.0) - - # Links - new_grp.links.new(grp_in.outputs[0], vec_xf.inputs[0]) - new_grp.links.new(vec_xf.outputs[0], uv_scale.inputs[0]) - new_grp.links.new(uv_scale.outputs[0], grp_out.inputs[0]) - - -# 1 - Modelview Inverse -def make_uva1(): - new_grp = bpy.data.node_groups.new('RetroUVMode1NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-300, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (500, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0]) - - -# 2 - UV Scroll -def make_uva2(): - new_grp = bpy.data.node_groups.new('RetroUVMode2Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketVector', 'Offset') - new_grp.inputs.new('NodeSocketVector', 'Scale') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-457, 22) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (500, 0) - - # Mapping - mapping = new_grp.nodes.new('ShaderNodeMapping') - mapping.location = (-235, 125) - for drv in mapping.inputs['Scale'].driver_add('default_value'): - drv.driver.expression = 'frame/60' - - # Adder1 - adder1 = new_grp.nodes.new('ShaderNodeVectorMath') - adder1.operation = 'ADD' - adder1.location = (100, 0) - - # Adder2 - adder2 = new_grp.nodes.new('ShaderNodeVectorMath') - adder2.operation = 'ADD' - adder2.location = (100, 200) - - # Links - new_grp.links.new(grp_in.outputs[0], adder2.inputs[0]) - new_grp.links.new(grp_in.outputs[1], adder1.inputs[0]) - new_grp.links.new(grp_in.outputs[2], mapping.inputs[0]) - new_grp.links.new(mapping.outputs[0], adder1.inputs[1]) - new_grp.links.new(adder1.outputs[0], adder2.inputs[1]) - new_grp.links.new(adder2.outputs[0], grp_out.inputs[0]) - - -# 3 - Rotation -def make_uva3(): - new_grp = bpy.data.node_groups.new('RetroUVMode3Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Offset') - new_grp.inputs.new('NodeSocketFloat', 'Scale') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-100, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (700, 0) - - # Adder1 - add1 = new_grp.nodes.new('ShaderNodeMath') - add1.operation = 'ADD' - add1.location = (500, 0) - - # Multiply - mult = new_grp.nodes.new('ShaderNodeMath') - mult.operation = 'MULTIPLY' - mult.location = (230, -112) - drv = mult.inputs[1].driver_add('default_value') - drv.driver.expression = 'frame/60' - - # Links - new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0]) - new_grp.links.new(grp_in.outputs[1], add1.inputs[0]) - new_grp.links.new(grp_in.outputs[2], mult.inputs[0]) - new_grp.links.new(mult.outputs[0], add1.inputs[1]) - - -# 4 - Horizontal Filmstrip Animation -def make_uva4(): - new_grp = bpy.data.node_groups.new('RetroUVMode4Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Scale') - new_grp.inputs.new('NodeSocketFloat', 'NumFrames') - new_grp.inputs.new('NodeSocketFloat', 'Step') - new_grp.inputs.new('NodeSocketFloat', 'Offset') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1000, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (800, 0) - - # Multiply1 - mult1 = new_grp.nodes.new('ShaderNodeMath') - mult1.operation = 'MULTIPLY' - mult1.location = (-800, 0) - - # Multiply2 - mult2 = new_grp.nodes.new('ShaderNodeMath') - mult2.operation = 'MULTIPLY' - mult2.location = (-600, 0) - - # Modulo - mod1 = new_grp.nodes.new('ShaderNodeMath') - mod1.operation = 'MODULO' - mod1.inputs[1].default_value = 1.0 - mod1.location = (-400, 0) - - # Multiply3 - mult3 = new_grp.nodes.new('ShaderNodeMath') - mult3.operation = 'MULTIPLY' - mult3.location = (-200, 0) - - # Multiply4 - mult4 = new_grp.nodes.new('ShaderNodeMath') - mult4.operation = 'MULTIPLY' - mult4.location = (0, 0) - - # Mapping - map1 = new_grp.nodes.new('ShaderNodeMapping') - map1.inputs['Scale'].default_value = (1.0, 0.0, 0.0) - map1.location = (200, 0) - - # Add - add1 = new_grp.nodes.new('ShaderNodeVectorMath') - add1.operation = 'ADD' - add1.location = (600, 0) - - # Timing Add - time_add = new_grp.nodes.new('ShaderNodeMath') - time_add.operation = 'ADD' - time_add.location = (-802, -180) - drv = time_add.inputs[1].driver_add('default_value') - drv.driver.expression = 'frame/60' - - # Floor - floor = new_grp.nodes.new('ShaderNodeMath') - floor.operation = 'FLOOR' - floor.location = (-204, -180) - floor.inputs[1].default_value = 0.0 - - # Links - new_grp.links.new(grp_in.outputs[0], add1.inputs[1]) - new_grp.links.new(grp_in.outputs[1], mult1.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult3.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult4.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult1.inputs[0]) - new_grp.links.new(grp_in.outputs[4], time_add.inputs[0]) - new_grp.links.new(time_add.outputs[0], mult2.inputs[1]) - new_grp.links.new(mult1.outputs[0], mult2.inputs[0]) - new_grp.links.new(mult2.outputs[0], mod1.inputs[0]) - new_grp.links.new(mod1.outputs[0], mult3.inputs[0]) - new_grp.links.new(mult3.outputs[0], floor.inputs[0]) - new_grp.links.new(floor.outputs[0], mult4.inputs[0]) - new_grp.links.new(mult4.outputs[0], map1.inputs[0]) - new_grp.links.new(map1.outputs[0], add1.inputs[0]) - new_grp.links.new(add1.outputs[0], grp_out.inputs[0]) - - -# 5 - Vertical Filmstrip Animation -def make_uva5(): - new_grp = bpy.data.node_groups.new('RetroUVMode5Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Scale') - new_grp.inputs.new('NodeSocketFloat', 'NumFrames') - new_grp.inputs.new('NodeSocketFloat', 'Step') - new_grp.inputs.new('NodeSocketFloat', 'Offset') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-1000, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (800, 0) - - # Multiply1 - mult1 = new_grp.nodes.new('ShaderNodeMath') - mult1.operation = 'MULTIPLY' - mult1.location = (-800, 0) - - # Multiply2 - mult2 = new_grp.nodes.new('ShaderNodeMath') - mult2.operation = 'MULTIPLY' - mult2.location = (-600, 0) - - # Modulo - mod1 = new_grp.nodes.new('ShaderNodeMath') - mod1.operation = 'MODULO' - mod1.inputs[1].default_value = 1.0 - mod1.location = (-400, 0) - - # Multiply3 - mult3 = new_grp.nodes.new('ShaderNodeMath') - mult3.operation = 'MULTIPLY' - mult3.location = (-200, 0) - - # Multiply4 - mult4 = new_grp.nodes.new('ShaderNodeMath') - mult4.operation = 'MULTIPLY' - mult4.location = (0, 0) - - # Mapping - map1 = new_grp.nodes.new('ShaderNodeMapping') - map1.inputs['Scale'].default_value = (0.0, 1.0, 0.0) - map1.location = (200, 0) - - # Add - add1 = new_grp.nodes.new('ShaderNodeVectorMath') - add1.operation = 'ADD' - add1.location = (600, 0) - - # Timing Add - time_add = new_grp.nodes.new('ShaderNodeMath') - time_add.operation = 'ADD' - time_add.location = (-802, -180) - drv = time_add.inputs[1].driver_add('default_value') - drv.driver.expression = 'frame/60' - - # Floor - floor = new_grp.nodes.new('ShaderNodeMath') - floor.operation = 'FLOOR' - floor.location = (-204, -180) - floor.inputs[1].default_value = 0.0 - - # Links - new_grp.links.new(grp_in.outputs[0], add1.inputs[1]) - new_grp.links.new(grp_in.outputs[1], mult1.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult3.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult4.inputs[1]) - new_grp.links.new(grp_in.outputs[3], mult1.inputs[0]) - new_grp.links.new(grp_in.outputs[4], time_add.inputs[0]) - new_grp.links.new(time_add.outputs[0], mult2.inputs[1]) - new_grp.links.new(mult1.outputs[0], mult2.inputs[0]) - new_grp.links.new(mult2.outputs[0], mod1.inputs[0]) - new_grp.links.new(mod1.outputs[0], mult3.inputs[0]) - new_grp.links.new(mult3.outputs[0], floor.inputs[0]) - new_grp.links.new(floor.outputs[0], mult4.inputs[0]) - new_grp.links.new(mult4.outputs[0], map1.inputs[0]) - new_grp.links.new(map1.outputs[0], add1.inputs[0]) - new_grp.links.new(add1.outputs[0], grp_out.inputs[0]) - - -# 6 - Model Matrix -def make_uva6(): - new_grp = bpy.data.node_groups.new('RetroUVMode6NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-100, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (300, 0) - - # Geometry input - geom_in = new_grp.nodes.new('ShaderNodeTexCoord') - geom_in.location = (-300, 0) - - # Adder1 - adder1 = new_grp.nodes.new('ShaderNodeVectorMath') - adder1.operation = 'ADD' - adder1.location = (100, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], adder1.inputs[0]) - new_grp.links.new(geom_in.outputs['Object'], adder1.inputs[1]) - new_grp.links.new(adder1.outputs[0], grp_out.inputs[0]) - - -# 7 - Mode Who Must Not Be Named -def make_uva7(): - new_grp = bpy.data.node_groups.new('RetroUVMode7NodeN', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'ParamA') - new_grp.inputs.new('NodeSocketFloat', 'ParamB') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-800, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (0, 0) - - # Geometry input - geom_in = new_grp.nodes.new('ShaderNodeTexCoord') - geom_in.location = (-1000, 0) - - # View flip - view_flip = new_grp.nodes.new('ShaderNodeMapping') - view_flip.location = (-800, -150) - view_flip.vector_type = 'TEXTURE' - view_flip.inputs['Scale'].default_value = (-1.0, -1.0, 1.0) - - # Separate - sep1 = new_grp.nodes.new('ShaderNodeSeparateRGB') - sep1.location = (-400, -200) - - # Add1 - add1 = new_grp.nodes.new('ShaderNodeMath') - add1.operation = 'ADD' - add1.location = (-200, -200) - - # Multiply1 - mult1 = new_grp.nodes.new('ShaderNodeMath') - mult1.operation = 'MULTIPLY' - mult1.inputs[1].default_value = 0.025 - mult1.location = (0, -200) - - # Multiply2 - mult2 = new_grp.nodes.new('ShaderNodeMath') - mult2.operation = 'MULTIPLY' - mult2.location = (200, -200) - - # Multiply3 - mult3 = new_grp.nodes.new('ShaderNodeMath') - mult3.operation = 'MULTIPLY' - mult3.inputs[1].default_value = 0.05 - mult3.location = (0, -400) - - # Multiply4 - mult4 = new_grp.nodes.new('ShaderNodeMath') - mult4.operation = 'MULTIPLY' - mult4.location = (200, -400) - - # Combine1 - comb1 = new_grp.nodes.new('ShaderNodeCombineRGB') - comb1.location = (400, -300) - - # Combine2 - comb2 = new_grp.nodes.new('ShaderNodeCombineRGB') - comb2.location = (-600, 0) - - # Multiply5 - mult5 = new_grp.nodes.new('ShaderNodeMixRGB') - mult5.blend_type = 'MULTIPLY' - mult5.inputs[0].default_value = 1.0 - mult5.location = (-400, 0) - - # Add2 - add2 = new_grp.nodes.new('ShaderNodeVectorMath') - add2.operation = 'ADD' - add2.location = (-200, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], add2.inputs[0]) - new_grp.links.new(geom_in.outputs['Window'], view_flip.inputs[0]) - new_grp.links.new(view_flip.outputs[0], sep1.inputs[0]) - new_grp.links.new(grp_in.outputs[1], comb2.inputs[0]) - new_grp.links.new(grp_in.outputs[1], comb2.inputs[1]) - new_grp.links.new(grp_in.outputs[1], comb2.inputs[2]) - new_grp.links.new(comb2.outputs[0], mult5.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult2.inputs[1]) - new_grp.links.new(grp_in.outputs[2], mult4.inputs[1]) - new_grp.links.new(sep1.outputs[0], add1.inputs[0]) - new_grp.links.new(sep1.outputs[1], add1.inputs[1]) - new_grp.links.new(sep1.outputs[2], mult3.inputs[0]) - new_grp.links.new(add1.outputs[0], mult1.inputs[0]) - new_grp.links.new(mult1.outputs[0], mult2.inputs[0]) - new_grp.links.new(mult2.outputs[0], comb1.inputs[0]) - new_grp.links.new(mult3.outputs[0], mult4.inputs[0]) - new_grp.links.new(mult4.outputs[0], comb1.inputs[1]) - new_grp.links.new(comb1.outputs[0], mult5.inputs[2]) - new_grp.links.new(mult5.outputs[0], add2.inputs[1]) - new_grp.links.new(add2.outputs[0], grp_out.inputs[0]) - - -# 8 - Mode 8 -def make_uva8(): - new_grp = bpy.data.node_groups.new('RetroUVMode8Node', 'ShaderNodeTree') - new_grp.inputs.new('NodeSocketVector', 'UV In') - new_grp.inputs.new('NodeSocketFloat', 'Param1') - new_grp.inputs.new('NodeSocketFloat', 'Param2') - new_grp.inputs.new('NodeSocketFloat', 'Param3') - new_grp.inputs.new('NodeSocketFloat', 'Param4') - new_grp.inputs.new('NodeSocketFloat', 'Param5') - new_grp.inputs.new('NodeSocketFloat', 'Param6') - new_grp.inputs.new('NodeSocketFloat', 'Param7') - new_grp.inputs.new('NodeSocketFloat', 'Param8') - new_grp.inputs.new('NodeSocketFloat', 'Param9') - new_grp.outputs.new('NodeSocketVector', 'UV Out') - new_grp.use_fake_user = True - - # Group inputs - grp_in = new_grp.nodes.new('NodeGroupInput') - grp_in.location = (-800, 0) - - # Group outputs - grp_out = new_grp.nodes.new('NodeGroupOutput') - grp_out.location = (0, 0) - - # Links - new_grp.links.new(grp_in.outputs[0], grp_out.inputs[0]) - - -UV_ANIMATION_GROUPS = ( - make_uva0, - make_uva1, - make_uva2, - make_uva3, - make_uva4, - make_uva5, - make_uva6, - make_uva7, - make_uva8 -) - - -def make_master_shader_library(): - make_additive_output() - make_blend_opaque_output() - for shad in ROOT_SHADER_GROUPS: - shad() - for uva in UV_ANIMATION_GROUPS: - uva() diff --git a/DataSpec/CMakeLists.txt b/DataSpec/CMakeLists.txt deleted file mode 100644 index 0acaa2640..000000000 --- a/DataSpec/CMakeLists.txt +++ /dev/null @@ -1,91 +0,0 @@ -# Assembles a source/header pair list for use in a DNA library -macro(make_dnalist) - file(RELATIVE_PATH subdir "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_LIST_DIR}") - set(CMAKE_CURRENT_LIST_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${subdir}") - file(MAKE_DIRECTORY "${CMAKE_CURRENT_LIST_BINARY_DIR}") - foreach (type ${ARGN}) - get_filename_component(dir ${type} DIRECTORY) - if (dir) - file(MAKE_DIRECTORY "${CMAKE_CURRENT_LIST_BINARY_DIR}/${dir}") - set(dir "${dir}/") - endif () - get_filename_component(name ${type} NAME) - list(APPEND DNA_SOURCES "${subdir}/${dir}atdna_${name}.cpp") - list(APPEND DNA_HEADERS "${subdir}/${dir}${name}.hpp") - endforeach () -endmacro() - -# Assembles source files together for the main DataSpecCommon library -macro(dataspec_add_list rel_path a_list) - unset(tmp_list) - foreach (path IN LISTS ${a_list}) - if (IS_ABSOLUTE ${path}) - list(APPEND tmp_list "${path}") - else () - list(APPEND tmp_list "${rel_path}/${path}") - endif () - endforeach (path) - set(${a_list} "${tmp_list}") -endmacro(dataspec_add_list) - -# Each game's DNA library -unset(DNA_SOURCES) -unset(DNA_HEADERS) -include(DNACommon/CMakeLists.txt) -include(DNAMP1/CMakeLists.txt) -include(DNAMP2/CMakeLists.txt) -include(DNAMP3/CMakeLists.txt) - -# Embed master shader script -bintoc(RetroMasterShader.cpp Blender/RetroMasterShader.py RETRO_MASTER_SHADER) - -# Download asset name databases -add_custom_command(OUTPUT AssetNameMap32.bin COMMAND ${CMAKE_COMMAND} ARGS -P - ${CMAKE_CURRENT_SOURCE_DIR}/AssetMap32Download.cmake) -bintoc_compress(AssetNameMap32.cpp ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap32.bin ASSET_NAME_MP32) - -add_custom_command(OUTPUT AssetNameMap64.bin COMMAND ${CMAKE_COMMAND} ARGS -P - ${CMAKE_CURRENT_SOURCE_DIR}/AssetMap64Download.cmake) -bintoc_compress(AssetNameMap64.cpp ${CMAKE_CURRENT_BINARY_DIR}/AssetNameMap64.bin ASSET_NAME_MP64) - -# Each game's DataSpec implementation -add_library(RetroDataSpec - SpecBase.cpp - ${DNACOMMON_SOURCES} - SpecMP1.cpp - ${DNAMP1_SOURCES} - ${ScriptObjectsMP1_SOURCES} - ${DNAMP1_SFX_SOURCES} - SpecMP2.cpp - ${DNAMP2_SOURCES} - SpecMP3.cpp - ${DNAMP3_SOURCES} - Blender/BlenderSupport.hpp - Blender/BlenderSupport.cpp - Blender/RetroMasterShader.py - AssetNameMap.hpp - AssetNameMap.cpp - RetroMasterShader.cpp) -add_library(AssetNameMap - AssetNameMap32.bin AssetNameMap32.cpp - AssetNameMap64.bin AssetNameMap64.cpp) -add_library(AssetNameMapNull - AssetNameMapNull.cpp) - -get_target_property(HECL_INCLUDES hecl-full INCLUDE_DIRECTORIES) -target_include_directories(RetroDataSpec PUBLIC ${HECL_INCLUDES} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_SOURCE_DIR}) -target_link_libraries(RetroDataSpec PUBLIC amuse zeus nod squish ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} lzokay logvisor) -if (COMMAND add_sanitizers) - add_sanitizers(RetroDataSpec) -endif () - -# Resolve all DNA sources into target -list(LENGTH DNA_SOURCES count) -math(EXPR count "${count}-1") -foreach (i RANGE ${count}) - list(GET DNA_SOURCES ${i} src) - list(GET DNA_HEADERS ${i} header) - target_atdna(RetroDataSpec ${src} ${header}) -endforeach () - -add_custom_target(genexdebug COMMAND ${CMAKE_COMMAND} -E echo "$") diff --git a/DataSpec/DNACommon/ANCS.cpp b/DataSpec/DNACommon/ANCS.cpp deleted file mode 100644 index 13e5f67f3..000000000 --- a/DataSpec/DNACommon/ANCS.cpp +++ /dev/null @@ -1,282 +0,0 @@ -#include "DataSpec/DNACommon/ANCS.hpp" - -#include "DataSpec/DNACommon/CMDL.hpp" -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP1/ANCS.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP2/ANCS.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" -#include "DataSpec/DNAMP3/CHAR.hpp" - -#include - -namespace DataSpec::DNAANCS { - -template -bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, - std::function fileChanged, bool force) { - auto& conn = btok.getBlenderConnection(); - /* Extract character CMDL/CSKR/CINF first */ - std::vector> chResInfo; - ancs.getCharacterResInfo(chResInfo); - for (const auto& info : chResInfo) { - const nod::Node* node; - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - if (force || cmdlPath.isNone()) { - cmdlPath.makeDirChain(false); - if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh)) - return false; - - std::string bestName = pakRouter.getBestEntryName(*cmdlE); - fileChanged(bestName.c_str()); - - typename ANCSDNA::CSKRType cskr; - pakRouter.lookupAndReadDNA(info.cskr, cskr); - typename ANCSDNA::CINFType cinf; - pakRouter.lookupAndReadDNA(info.cinf, cinf); - using RigPair = std::pair, - std::pair>; - RigPair rigPair({info.cskr, &cskr}, {info.cinf, &cinf}); - - PAKEntryReadStream rs = cmdlE->beginReadStream(*node); - DNACMDL::ReadCMDLToBlender( - conn, rs, pakRouter, *cmdlE, dataspec, rigPair); - - conn.saveBlend(); - } - } - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(info.cinf, &node, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - if (cinfPath.getPathType() == hecl::ProjectPath::Type::None) { - PAKEntryReadStream rs = cinfE->beginReadStream(*node); - ANCSDNA::CINFType::Extract(dataspec, rs, cinfPath, pakRouter, *cinfE, false, btok, fileChanged); - } - } - } - - /* Extract attachment CMDL/CSKR/CINFs first */ - auto attRange = pakRouter.lookupCharacterAttachmentRigs(entry.id); - for (auto it = attRange.first; it != attRange.second; ++it) { - auto cinfid = it->second.first.cinf; - auto cmdlid = it->second.first.cmdl; - - const nod::Node* node; - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, &node, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - if (force || cmdlPath.isNone()) { - cmdlPath.makeDirChain(false); - if (!conn.createBlend(cmdlPath, hecl::blender::BlendType::Mesh)) { - return false; - } - - std::string bestName = pakRouter.getBestEntryName(*cmdlE); - fileChanged(bestName.c_str()); - - const auto* rp = pakRouter.lookupCMDLRigPair(cmdlid); - typename ANCSDNA::CSKRType cskr; - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - typename ANCSDNA::CINFType cinf; - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - using RigPair = std::pair, - std::pair>; - RigPair rigPair({rp->cskr, &cskr}, {rp->cinf, &cinf}); - - PAKEntryReadStream rs = cmdlE->beginReadStream(*node); - DNACMDL::ReadCMDLToBlender( - conn, rs, pakRouter, *cmdlE, dataspec, rigPair); - - conn.saveBlend(); - } - } - if (cinfid.isValid()) { - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(cinfid, &node, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - if (cinfPath.getPathType() == hecl::ProjectPath::Type::None) { - PAKEntryReadStream rs = cinfE->beginReadStream(*node); - ANCSDNA::CINFType::Extract(dataspec, rs, cinfPath, pakRouter, *cinfE, false, btok, fileChanged); - } - } - } - } - - std::string bestName = pakRouter.getBestEntryName(entry); - fileChanged(bestName.c_str()); - - /* Establish ANCS blend */ - if (!conn.createBlend(outPath, hecl::blender::BlendType::Actor)) - return false; - - std::string firstName; - typename ANCSDNA::CINFType firstCinf; - { - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os.format(FMT_STRING("import bpy\n" - "from mathutils import Vector\n" - "bpy.context.scene.name = '{}'\n" - "bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "actor_data = bpy.context.scene.hecl_sact_data\n" - "arm_obj = None\n"), - pakRouter.getBestEntryName(entry)); - - std::unordered_set cinfsDone; - for (const auto& info : chResInfo) { - /* Provide data to add-on */ - os.format(FMT_STRING("actor_subtype = actor_data.subtypes.add()\n" - "actor_subtype.name = '{}'\n\n"), - info.name); - - /* Build CINF if needed */ - if (cinfsDone.find(info.cinf) == cinfsDone.end()) { - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(info.cinf, nullptr, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - os.linkArmature(cinfPath.getAbsolutePath(), fmt::format(FMT_STRING("CINF_{}"), info.cinf)); - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n"; - } - if (cinfsDone.empty()) { - firstName = ANCSDNA::CINFType::GetCINFArmatureName(info.cinf); - pakRouter.lookupAndReadDNA(info.cinf, firstCinf); - } - cinfsDone.insert(info.cinf); - } - os.format(FMT_STRING("arm_obj = bpy.data.objects['CINF_{}']\n"), info.cinf); - os << "actor_subtype.linked_armature = arm_obj.name\n"; - - /* Link CMDL */ - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, nullptr, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - /* Attach CMDL to CINF */ - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = arm_obj\n" - "obj.parent_type = 'ARMATURE'\n" - "actor_subtype.linked_mesh = obj.name\n\n"; - } - - /* Link overlays */ - for (const auto& overlay : info.overlays) { - os << "overlay = actor_subtype.overlays.add()\n"; - os.format(FMT_STRING("overlay.name = '{}'\n"), overlay.first); - - /* Link CMDL */ - if (const typename PAKRouter::EntryType* cmdlE = - pakRouter.lookupEntry(overlay.second.first, nullptr, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - /* Attach CMDL to CINF */ - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = arm_obj\n" - "obj.parent_type = 'ARMATURE'\n" - "overlay.linked_mesh = obj.name\n\n"; - } - } - } - - /* Link attachments */ - for (auto it = attRange.first; it != attRange.second; ++it) { - os << "attachment = actor_data.attachments.add()\n"; - os.format(FMT_STRING("attachment.name = '{}'\n"), it->second.second); - - auto cinfid = it->second.first.cinf; - auto cmdlid = it->second.first.cmdl; - - if (cinfid.isValid()) { - /* Build CINF if needed */ - if (cinfsDone.find(cinfid) == cinfsDone.end()) { - if (const typename PAKRouter::EntryType* cinfE = pakRouter.lookupEntry(cinfid, nullptr, true, false)) { - hecl::ProjectPath cinfPath = pakRouter.getWorking(cinfE); - os.linkArmature(cinfPath.getAbsolutePath(), fmt::format(FMT_STRING("CINF_{}"), cinfid)); - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n"; - } - if (cinfsDone.empty()) { - firstName = ANCSDNA::CINFType::GetCINFArmatureName(cinfid); - pakRouter.lookupAndReadDNA(cinfid, firstCinf); - } - cinfsDone.insert(cinfid); - } - os.format(FMT_STRING("arm_obj = bpy.data.objects['CINF_{}']\n"), cinfid); - os << "attachment.linked_armature = arm_obj.name\n"; - } - - /* Link CMDL */ - if (const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(cmdlid, nullptr, true, false)) { - hecl::ProjectPath cmdlPath = pakRouter.getWorking(cmdlE); - os.linkMesh(cmdlPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - /* Attach CMDL to CINF */ - os << "if obj.name not in bpy.context.scene.objects:\n" - " bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = arm_obj\n" - "obj.parent_type = 'ARMATURE'\n" - "attachment.linked_mesh = obj.name\n\n"; - } - } - } - - { - hecl::blender::DataStream ds = conn.beginData(); - std::unordered_map matrices = ds.getBoneMatrices(firstName); - ds.close(); - DNAANIM::RigInverter inverter(firstCinf, matrices); - - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "actor_data = bpy.context.scene.hecl_sact_data\n"; - - /* Get animation primitives */ - std::map> animResInfo; - ancs.getAnimationResInfo(&pakRouter, animResInfo); - for (const auto& id : animResInfo) { - typename ANCSDNA::ANIMType anim; - if (pakRouter.lookupAndReadDNA(id.second.animId, anim, true)) { - os.format(FMT_STRING("act = bpy.data.actions.new('{}')\n" - "act.use_fake_user = True\n" - "act.anim_id = '{}'\n"), - id.second.name, id.second.animId); - anim.sendANIMToBlender(os, inverter, id.second.additive); - } - - os.format(FMT_STRING("actor_action = actor_data.actions.add()\n" - "actor_action.name = '{}'\n"), - id.second.name); - - /* Extract EVNT if present */ - anim.extractEVNT(id.second, outPath, pakRouter, force); - } - } - conn.saveBlend(); - return true; -} - -template bool -ReadANCSToBlender, DNAMP1::ANCS, DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>( - hecl::blender::Token& btok, const DNAMP1::ANCS& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, - const SpecBase& dataspec, std::function fileChanged, bool force); -template bool -ReadANCSToBlender, DNAMP2::ANCS, DNAMP2::MaterialSet, DNACMDL::SurfaceHeader_2, 4>( - hecl::blender::Token& btok, const DNAMP2::ANCS& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, - const SpecBase& dataspec, std::function fileChanged, bool force); -template bool -ReadANCSToBlender, DNAMP3::CHAR, DNAMP3::MaterialSet, DNACMDL::SurfaceHeader_3, 4>( - hecl::blender::Token& btok, const DNAMP3::CHAR& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, - const SpecBase& dataspec, std::function fileChanged, bool force); - -} // namespace DataSpec::DNAANCS diff --git a/DataSpec/DNACommon/ANCS.hpp b/DataSpec/DNACommon/ANCS.hpp deleted file mode 100644 index 48e89b69f..000000000 --- a/DataSpec/DNACommon/ANCS.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#include "athena/Types.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -struct SpecBase; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAANCS { - -using Actor = hecl::blender::Actor; -using Armature = Actor::ActorArmature; -using Action = hecl::blender::Action; - -template -struct CharacterResInfo { - std::string name; - IDTYPE cmdl; - IDTYPE cskr; - IDTYPE cinf; - std::vector>> overlays; -}; - -template -struct AnimationResInfo { - std::string name; - IDTYPE animId; - IDTYPE evntId; - bool additive; -}; - -template -bool ReadANCSToBlender(hecl::blender::Token& btok, const ANCSDNA& ancs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, - std::function fileChanged, bool force = false); - -} // namespace DataSpec::DNAANCS diff --git a/DataSpec/DNACommon/ANIM.cpp b/DataSpec/DNACommon/ANIM.cpp deleted file mode 100644 index 42079d125..000000000 --- a/DataSpec/DNACommon/ANIM.cpp +++ /dev/null @@ -1,462 +0,0 @@ -#include "DataSpec/DNACommon/ANIM.hpp" - -#include -#include -#include - -#include -#include -#include - -#define DUMP_KEYS 0 - -#if DUMP_KEYS -#include -#include -#endif - -namespace DataSpec::DNAANIM { - -size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector& channels) { - size_t bitsPerKeyFrame = 0; - for (const Channel& chan : channels) { - switch (chan.type) { - case Channel::Type::Rotation: - bitsPerKeyFrame += 1; - [[fallthrough]]; - case Channel::Type::Translation: - case Channel::Type::Scale: - bitsPerKeyFrame += chan.q[0]; - bitsPerKeyFrame += chan.q[1]; - bitsPerKeyFrame += chan.q[2]; - break; - case Channel::Type::KfHead: - bitsPerKeyFrame += 1; - break; - case Channel::Type::RotationMP3: - bitsPerKeyFrame += chan.q[0]; - bitsPerKeyFrame += chan.q[1]; - bitsPerKeyFrame += chan.q[2]; - bitsPerKeyFrame += chan.q[3]; - break; - default: - break; - } - } - return (bitsPerKeyFrame * keyFrameCount + 31) / 32 * 4; -} - -static QuantizedRot QuantizeRotation(const Value& quat, atUint32 div) { - float q = float(div) / (M_PIF / 2.0f); - zeus::simd_floats f(quat.simd); - assert(std::abs(f[1]) <= 1.f && "Out of range quat X component"); - assert(std::abs(f[2]) <= 1.f && "Out of range quat Y component"); - assert(std::abs(f[3]) <= 1.f && "Out of range quat Z component"); - return {{ - atInt32(std::asin(f[1]) * q), - atInt32(std::asin(f[2]) * q), - atInt32(std::asin(f[3]) * q), - }, - (f[0] < 0.f)}; -} - -static Value DequantizeRotation(const QuantizedRot& v, atUint32 div) { - float q = (M_PIF / 2.0f) / float(div); - athena::simd_floats f = { - 0.0f, - std::sin(v.v[0] * q), - std::sin(v.v[1] * q), - std::sin(v.v[2] * q), - }; - f[0] = std::sqrt(std::max((1.0f - (f[1] * f[1] + f[2] * f[2] + f[3] * f[3])), 0.0f)); - f[0] = v.w ? -f[0] : f[0]; - Value retval; - retval.simd.copy_from(f); - return retval; -} - -static Value DequantizeRotation_3(const QuantizedRot& v, atUint32 div) { - float q = 1.0f / float(div); - athena::simd_floats f = { - 0.0f, - v.v[0] * q, - v.v[1] * q, - v.v[2] * q, - }; - f[0] = std::sqrt(std::max((1.0f - (f[1] * f[1] + f[2] * f[2] + f[3] * f[3])), 0.0f)); - f[0] = v.w ? -f[0] : f[0]; - Value retval; - retval.simd.copy_from(f); - return retval; -} - -bool BitstreamReader::dequantizeBit(const atUint8* data) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - atUint32 tempBuf = hecl::SBig(*reinterpret_cast(data + byteCur)) >> bitRem; - - /* That's it */ - m_bitCur += 1; - return tempBuf & 0x1; -} - -atInt32 BitstreamReader::dequantize(const atUint8* data, atUint8 q) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - atUint32 tempBuf = hecl::SBig(*reinterpret_cast(data + byteCur)) >> bitRem; - - /* If this shift underflows the value, buffer the next 32 bits */ - /* And tack onto shifted buffer */ - if ((bitRem + q) > 32) { - atUint32 tempBuf2 = hecl::SBig(*reinterpret_cast(data + byteCur + 4)); - tempBuf |= (tempBuf2 << (32 - bitRem)); - } - - /* Mask it */ - atUint32 mask = (1 << q) - 1; - tempBuf &= mask; - - /* Sign extend */ - atUint32 sign = (tempBuf >> (q - 1)) & 0x1; - if (sign) - tempBuf |= ~0u << q; - - /* Return delta value */ - m_bitCur += q; - return atInt32(tempBuf); -} - -std::vector> BitstreamReader::read(const atUint8* data, size_t keyFrameCount, - const std::vector& channels, atUint32 rotDiv, - float transMult, float scaleMult) { - m_bitCur = 0; - std::vector> chanKeys; - std::vector chanAccum; - chanKeys.reserve(channels.size()); - chanAccum.reserve(channels.size()); - for (const Channel& chan : channels) { - chanAccum.push_back(chan.i); - - chanKeys.emplace_back(); - std::vector& keys = chanKeys.back(); - keys.reserve(keyFrameCount); - switch (chan.type) { - case Channel::Type::Rotation: { - QuantizedRot qr = {{chan.i[0], chan.i[1], chan.i[2]}, false}; - keys.emplace_back(DequantizeRotation(qr, rotDiv)); - break; - } - case Channel::Type::Translation: { - keys.push_back({chan.i[0] * transMult, chan.i[1] * transMult, chan.i[2] * transMult}); - break; - } - case Channel::Type::Scale: { - keys.push_back({chan.i[0] * scaleMult, chan.i[1] * scaleMult, chan.i[2] * scaleMult}); - break; - } - case Channel::Type::KfHead: { - break; - } - case Channel::Type::RotationMP3: { - QuantizedRot qr = {{chan.i[1], chan.i[2], chan.i[3]}, bool(chan.i[0] & 0x1)}; - keys.emplace_back(DequantizeRotation_3(qr, rotDiv)); - break; - } - default: - break; - } - } - - for (size_t f = 0; f < keyFrameCount; ++f) { -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("\nFRAME {} {} {}\n"), f, (m_bitCur / 32) * 4, m_bitCur % 32); - int lastId = -1; -#endif - auto kit = chanKeys.begin(); - auto ait = chanAccum.begin(); - for (const Channel& chan : channels) { -#if DUMP_KEYS - if (chan.id != lastId) { - lastId = chan.id; - std::fputc('\n', stderr); - } -#endif - QuantizedValue& p = *ait; - switch (chan.type) { - case Channel::Type::Rotation: { - bool wBit = dequantizeBit(data); - p[0] += dequantize(data, chan.q[0]); - p[1] += dequantize(data, chan.q[1]); - p[2] += dequantize(data, chan.q[2]); - QuantizedRot qr = {{p[0], p[1], p[2]}, wBit}; - kit->emplace_back(DequantizeRotation(qr, rotDiv)); -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("{} R: {} {} {} {}\t"), chan.id, wBit, p[0], p[1], p[2]); -#endif - break; - } - case Channel::Type::Translation: { - atInt32 val1 = dequantize(data, chan.q[0]); - p[0] += val1; - atInt32 val2 = dequantize(data, chan.q[1]); - p[1] += val2; - atInt32 val3 = dequantize(data, chan.q[2]); - p[2] += val3; - kit->push_back({p[0] * transMult, p[1] * transMult, p[2] * transMult}); -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("{} T: {} {} {}\t"), chan.id, p[0], p[1], p[2]); -#endif - break; - } - case Channel::Type::Scale: { - p[0] += dequantize(data, chan.q[0]); - p[1] += dequantize(data, chan.q[1]); - p[2] += dequantize(data, chan.q[2]); - kit->push_back({p[0] * scaleMult, p[1] * scaleMult, p[2] * scaleMult}); -#if DUMP_KEYS - fmt::print(stderr, FMT_STRING("{} S: {} {} {}\t"), chan.id, p[0], p[1], p[2]); -#endif - break; - } - case Channel::Type::KfHead: { - dequantizeBit(data); - break; - } - case Channel::Type::RotationMP3: { - atInt32 val1 = dequantize(data, chan.q[0]); - p[0] += val1; - atInt32 val2 = dequantize(data, chan.q[1]); - p[1] += val2; - atInt32 val3 = dequantize(data, chan.q[2]); - p[2] += val3; - atInt32 val4 = dequantize(data, chan.q[3]); - p[3] += val4; - QuantizedRot qr = {{p[1], p[2], p[3]}, bool(p[0] & 0x1)}; - kit->emplace_back(DequantizeRotation_3(qr, rotDiv)); - break; - } - default: - break; - } - ++kit; - ++ait; - } -#if DUMP_KEYS - std::fputc('\n', stderr); -#endif - } - - return chanKeys; -} - -void BitstreamWriter::quantizeBit(atUint8* data, bool val) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - *(atUint32*)(data + byteCur) = hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (val << bitRem)); - - m_bitCur += 1; -} - -void BitstreamWriter::quantize(atUint8* data, atUint8 q, atInt32 val) { - atUint32 byteCur = (m_bitCur / 32) * 4; - atUint32 bitRem = m_bitCur % 32; - - atUint32 masked = val & ((1 << q) - 1); - assert(((((val >> 31) & 0x1) == 0x1) || (((masked >> (q - 1)) & 0x1) == 0)) && "Twos compliment fail"); - - /* Fill 32 bit buffer with region containing bits */ - /* Make them least significant */ - *(atUint32*)(data + byteCur) = hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur)) | (masked << bitRem)); - - /* If this shift underflows the value, buffer the next 32 bits */ - /* And tack onto shifted buffer */ - if ((bitRem + q) > 32) { - *(atUint32*)(data + byteCur + 4) = - hecl::SBig(hecl::SBig(*(atUint32*)(data + byteCur + 4)) | (masked >> (32 - bitRem))); - } - - m_bitCur += q; -} - -std::unique_ptr BitstreamWriter::write(const std::vector>& chanKeys, size_t keyFrameCount, - std::vector& channels, atUint32 quantRange, - atUint32& rotDivOut, float& transMultOut, float& scaleMultOut, - size_t& sizeOut) { - m_bitCur = 0; - rotDivOut = quantRange; /* Normalized range of values */ - float quantRangeF = float(quantRange); - - /* Pre-pass to calculate translation multiplier */ - float maxTransDelta = 0.0f; - float maxScaleDelta = 0.0f; - auto kit = chanKeys.begin(); - for (Channel& chan : channels) { - switch (chan.type) { - case Channel::Type::Translation: { - zeus::simd lastVal = {}; - for (auto it = kit->begin(); it != kit->end(); ++it) { - const Value* key = &*it; - zeus::simd_floats f(key->simd - lastVal); - lastVal = key->simd; - maxTransDelta = std::max(maxTransDelta, std::fabs(f[0])); - maxTransDelta = std::max(maxTransDelta, std::fabs(f[1])); - maxTransDelta = std::max(maxTransDelta, std::fabs(f[2])); - } - break; - } - case Channel::Type::Scale: { - zeus::simd lastVal = {}; - for (auto it = kit->begin(); it != kit->end(); ++it) { - const Value* key = &*it; - zeus::simd_floats f(key->simd - lastVal); - lastVal = key->simd; - maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[0])); - maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[1])); - maxScaleDelta = std::max(maxScaleDelta, std::fabs(f[2])); - } - break; - } - default: - break; - } - ++kit; - } - transMultOut = maxTransDelta / quantRangeF + FLT_EPSILON; - scaleMultOut = maxScaleDelta / quantRangeF + FLT_EPSILON; - - /* Output channel inits */ - std::vector initVals; - initVals.reserve(channels.size()); - kit = chanKeys.begin(); - for (Channel& chan : channels) { - chan.q[0] = 1; - chan.q[1] = 1; - chan.q[2] = 1; - switch (chan.type) { - case Channel::Type::Rotation: { - QuantizedRot qr = QuantizeRotation((*kit)[0], rotDivOut); - chan.i = qr.v; - initVals.push_back(chan.i); - break; - } - case Channel::Type::Translation: { - zeus::simd_floats f((*kit)[0].simd); - chan.i = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)}; - initVals.push_back(chan.i); - break; - } - case Channel::Type::Scale: { - zeus::simd_floats f((*kit)[0].simd); - chan.i = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)}; - initVals.push_back(chan.i); - break; - } - default: - break; - } - ++kit; - } - - /* Pre-pass to analyze quantization factors for channels */ - std::vector lastVals = initVals; - kit = chanKeys.begin(); - auto vit = lastVals.begin(); - for (Channel& chan : channels) { - QuantizedValue& last = *vit++; - switch (chan.type) { - case Channel::Type::Rotation: { - for (auto it = kit->begin() + 1; it != kit->end(); ++it) { - QuantizedRot qrCur = QuantizeRotation(*it, rotDivOut); - chan.q[0] = std::max(chan.q[0], atUint8(qrCur.v.qFrom(last, 0))); - chan.q[1] = std::max(chan.q[1], atUint8(qrCur.v.qFrom(last, 1))); - chan.q[2] = std::max(chan.q[2], atUint8(qrCur.v.qFrom(last, 2))); - last = qrCur.v; - } - break; - } - case Channel::Type::Translation: { - for (auto it = kit->begin() + 1; it != kit->end(); ++it) { - zeus::simd_floats f(it->simd); - QuantizedValue cur = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)}; - chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0))); - chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1))); - chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2))); - last = cur; - } - break; - } - case Channel::Type::Scale: { - for (auto it = kit->begin() + 1; it != kit->end(); ++it) { - zeus::simd_floats f(it->simd); - QuantizedValue cur = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)}; - chan.q[0] = std::max(chan.q[0], atUint8(cur.qFrom(last, 0))); - chan.q[1] = std::max(chan.q[1], atUint8(cur.qFrom(last, 1))); - chan.q[2] = std::max(chan.q[2], atUint8(cur.qFrom(last, 2))); - last = cur; - } - break; - } - default: - break; - } - ++kit; - } - - /* Generate Bitstream */ - sizeOut = ComputeBitstreamSize(keyFrameCount, channels); - std::unique_ptr newData(new atUint8[sizeOut]); - memset(newData.get(), 0, sizeOut); - - lastVals = initVals; - for (size_t frame = 0; frame < keyFrameCount; ++frame) { - kit = chanKeys.begin(); - vit = lastVals.begin(); - for (const Channel& chan : channels) { - const Value& val = (*kit++)[frame + 1]; - QuantizedValue& last = *vit++; - switch (chan.type) { - case Channel::Type::Rotation: { - QuantizedRot qrCur = QuantizeRotation(val, rotDivOut); - quantizeBit(newData.get(), qrCur.w); - quantize(newData.get(), chan.q[0], qrCur.v[0] - last.v[0]); - quantize(newData.get(), chan.q[1], qrCur.v[1] - last.v[1]); - quantize(newData.get(), chan.q[2], qrCur.v[2] - last.v[2]); - last = qrCur.v; - break; - } - case Channel::Type::Translation: { - zeus::simd_floats f(val.simd); - QuantizedValue cur = {atInt32(f[0] / transMultOut), atInt32(f[1] / transMultOut), atInt32(f[2] / transMultOut)}; - quantize(newData.get(), chan.q[0], cur[0] - last[0]); - quantize(newData.get(), chan.q[1], cur[1] - last[1]); - quantize(newData.get(), chan.q[2], cur[2] - last[2]); - last = cur; - break; - } - case Channel::Type::Scale: { - zeus::simd_floats f(val.simd); - QuantizedValue cur = {atInt32(f[0] / scaleMultOut), atInt32(f[1] / scaleMultOut), atInt32(f[2] / scaleMultOut)}; - quantize(newData.get(), chan.q[0], cur[0] - last[0]); - quantize(newData.get(), chan.q[1], cur[1] - last[1]); - quantize(newData.get(), chan.q[2], cur[2] - last[2]); - last = cur; - break; - } - default: - break; - } - } - } - return newData; -} - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/ANIM.hpp b/DataSpec/DNACommon/ANIM.hpp deleted file mode 100644 index 903fda326..000000000 --- a/DataSpec/DNACommon/ANIM.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include - -namespace DataSpec::DNAANIM { - -struct Value { - athena::simd simd; - Value() = default; - Value(const athena::simd& s) : simd(s) {} - Value(const atVec3f& v) : simd(v.simd) {} - Value(const atVec4f& v) : simd(v.simd) {} - Value(float x, float y, float z) : simd(x, y, z, 0.f) {} - Value(float w, float x, float y, float z) : simd(w, x, y, z) {} -}; -struct QuantizedValue { - atInt32 v[4]; - atInt32& operator[](size_t idx) { return v[idx]; } - atInt32 operator[](size_t idx) const { return v[idx]; } - - int qFrom(const QuantizedValue& other, size_t idx) const { - atInt32 delta = v[idx] - other.v[idx]; - atInt32 absDelta = std::abs(delta); - if (absDelta == 0) - return 1; - int ret = int(std::ceil(std::log2(absDelta))) + 1; - if (delta > 0 && (delta >> (ret - 1))) - ++ret; - assert(ret <= 24 && "Bad q value"); - return ret; - } -}; -struct QuantizedRot { - QuantizedValue v; - bool w; -}; -struct Channel { - enum class Type { Rotation, Translation, Scale, KfHead, RotationMP3 } type; - atInt32 id = -1; - QuantizedValue i = {}; - atUint8 q[4] = {}; -}; - -size_t ComputeBitstreamSize(size_t keyFrameCount, const std::vector& channels); - -class BitstreamReader { - size_t m_bitCur; - atInt32 dequantize(const atUint8* data, atUint8 q); - bool dequantizeBit(const atUint8* data); - -public: - std::vector> read(const atUint8* data, size_t keyFrameCount, const std::vector& channels, - atUint32 rotDiv, float transMult, float scaleMult); -}; - -class BitstreamWriter { - size_t m_bitCur; - void quantize(atUint8* data, atUint8 q, atInt32 val); - void quantizeBit(atUint8* data, bool val); - -public: - std::unique_ptr write(const std::vector>& chanKeys, size_t keyFrameCount, - std::vector& channels, atUint32 quantRange, atUint32& rotDivOut, - float& transMultOut, float& scaleMultOut, size_t& sizeOut); -}; - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/AROTBuilder.cpp b/DataSpec/DNACommon/AROTBuilder.cpp deleted file mode 100644 index bd014635e..000000000 --- a/DataSpec/DNACommon/AROTBuilder.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include "AROTBuilder.hpp" - -#include -#include - -#include "hecl/Blender/Connection.hpp" -#include "PATH.hpp" - -namespace DataSpec { -logvisor::Module Log("AROTBuilder"); - -constexpr s32 AROT_MAX_LEVEL = 10; -constexpr s32 AROT_MIN_MODELS = 8; -constexpr s32 COLLISION_MIN_NODE_TRIANGLES = 8; -constexpr s32 PATH_MIN_NODE_REGIONS = 16; -constexpr float AROT_MIN_SUBDIV = 8.f; - -static zeus::CAABox SplitAABB(const zeus::CAABox& aabb, int i) { - zeus::CAABox pos, neg; - aabb.splitZ(neg, pos); - if (i & 4) { - zeus::CAABox(pos).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } - } else { - zeus::CAABox(neg).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - return pos; - else - return neg; - } - } -} - -void AROTBuilder::Node::mergeSets(int a, int b) { - childNodes[a].childIndices.insert(childNodes[b].childIndices.cbegin(), childNodes[b].childIndices.cend()); - childNodes[b].childIndices = childNodes[a].childIndices; -} - -bool AROTBuilder::Node::compareSets(int a, int b) const { - return childNodes[a].childIndices != childNodes[b].childIndices; -} - -void AROTBuilder::Node::addChild(int level, int minChildren, const std::vector& triBoxes, - const zeus::CAABox& curAABB, BspNodeType& typeOut) { - /* Gather intersecting faces */ - for (size_t i = 0; i < triBoxes.size(); ++i) - if (triBoxes[i].intersects(curAABB)) - childIndices.insert(i); - - zeus::CVector3f extents = curAABB.extents(); - - /* Return early if empty, triangle intersection below performance threshold, or at max level */ - if (childIndices.empty()) { - typeOut = BspNodeType::Invalid; - return; - } else if (childIndices.size() < minChildren || level == AROT_MAX_LEVEL || - std::max(extents.x(), std::max(extents.y(), extents.z())) < AROT_MIN_SUBDIV) { - typeOut = BspNodeType::Leaf; - return; - } - - /* Subdivide */ - typeOut = BspNodeType::Branch; - childNodes.resize(8); - for (int i = 0; i < 8; ++i) { - BspNodeType chType; - childNodes[i].addChild(level + 1, minChildren, triBoxes, SplitAABB(curAABB, i), chType); - flags |= int(chType) << (i * 2); - } - - /* Unsubdivide minimum axis dimensions */ - if (extents.x() < AROT_MIN_SUBDIV) { - mergeSets(0, 1); - mergeSets(4, 5); - mergeSets(2, 3); - mergeSets(6, 7); - } - if (extents.y() < AROT_MIN_SUBDIV) { - mergeSets(0, 2); - mergeSets(1, 3); - mergeSets(4, 6); - mergeSets(5, 7); - } - if (extents.z() < AROT_MIN_SUBDIV) { - mergeSets(0, 4); - mergeSets(1, 5); - mergeSets(2, 6); - mergeSets(3, 7); - } - - /* Unsubdivide */ - compSubdivs = 0; - if (compareSets(0, 1) || compareSets(4, 5) || compareSets(2, 3) || compareSets(6, 7)) - compSubdivs |= 0x1; - if (compareSets(0, 2) || compareSets(1, 3) || compareSets(4, 6) || compareSets(5, 7)) - compSubdivs |= 0x2; - if (compareSets(0, 4) || compareSets(1, 5) || compareSets(2, 6) || compareSets(3, 7)) - compSubdivs |= 0x4; - - if (!compSubdivs) { - typeOut = BspNodeType::Leaf; - childNodes = std::vector(); - flags = 0; - } -} - -size_t AROTBuilder::BitmapPool::addIndices(const std::set& indices) { - for (size_t i = 0; i < m_pool.size(); ++i) - if (m_pool[i] == indices) - return i; - m_pool.push_back(indices); - return m_pool.size() - 1; -} - -constexpr std::array AROTChildCounts{ - 0, 2, 2, 4, 2, 4, 4, 8, -}; - -void AROTBuilder::Node::nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff) { - sz += 1; - poolIdx = bmpPool.addIndices(childIndices); - if (poolIdx > 65535) - Log.report(logvisor::Fatal, FMT_STRING("AROT bitmap exceeds 16-bit node addressing; area too complex")); - - uint32_t childCount = AROTChildCounts[compSubdivs]; - nodeOff = curOff; - nodeSz = childCount * 2 + 4; - curOff += nodeSz; - if (childNodes.size()) { - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].nodeCount(sz, idxRefs, bmpPool, curOff); - } - } - } - idxRefs += childCount; - } -} - -void AROTBuilder::Node::writeIndirectionTable(athena::io::MemoryWriter& w) { - w.writeUint32Big(nodeOff); - if (childNodes.size()) { - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].writeIndirectionTable(w); - } - } - } - } -} - -void AROTBuilder::Node::writeNodes(athena::io::MemoryWriter& w, int nodeIdx) { - w.writeUint16Big(poolIdx); - w.writeUint16Big(compSubdivs); - - if (childNodes.size()) { - int curIdx = nodeIdx + 1; - if (curIdx > 65535) - Log.report(logvisor::Fatal, FMT_STRING("AROT node exceeds 16-bit node addressing; area too complex")); - - std::array childIndices; - - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - w.writeUint16Big(curIdx); - childIndices[idx] = curIdx; - childNodes[idx].advanceIndex(curIdx); - } - } - } - - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].writeNodes(w, childIndices[idx]); - } - } - } - } -} - -void AROTBuilder::Node::advanceIndex(int& nodeIdx) { - ++nodeIdx; - if (childNodes.size()) { - for (int k = 0; k < 1 + ((compSubdivs & 0x4) != 0); ++k) { - for (int j = 0; j < 1 + ((compSubdivs & 0x2) != 0); ++j) { - for (int i = 0; i < 1 + ((compSubdivs & 0x1) != 0); ++i) { - int idx = k * 4 + j * 2 + i; - childNodes[idx].advanceIndex(nodeIdx); - } - } - } - } -} - -void AROTBuilder::Node::colSize(size_t& totalSz) { - if (childIndices.size()) { - nodeOff = totalSz; - if (childNodes.empty()) { - totalSz += 26 + childIndices.size() * 2; - } else { - totalSz += 36; - for (int i = 0; i < 8; ++i) - childNodes[i].colSize(totalSz); - } - } -} - -void AROTBuilder::Node::writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB) { - if (childIndices.size()) { - if (childNodes.empty()) { - float* aabbOut = reinterpret_cast(ptr); - aabbOut[0] = hecl::SBig(curAABB.min[0]); - aabbOut[1] = hecl::SBig(curAABB.min[1]); - aabbOut[2] = hecl::SBig(curAABB.min[2]); - aabbOut[3] = hecl::SBig(curAABB.max[0]); - aabbOut[4] = hecl::SBig(curAABB.max[1]); - aabbOut[5] = hecl::SBig(curAABB.max[2]); - athena::io::MemoryWriter w(ptr + 24, INT32_MAX); - w.writeUint16Big(childIndices.size()); - for (int idx : childIndices) - w.writeUint16Big(idx); - ptr += 26 + childIndices.size() * 2; - } else { - uint16_t* pflags = reinterpret_cast(ptr); - uint32_t* offsets = reinterpret_cast(ptr + 4); - memset(pflags, 0, sizeof(uint32_t) * 9); - for (int i = 0; i < 8; ++i) { - const Node& chNode = childNodes[i]; - BspNodeType type = BspNodeType((flags >> (i * 2)) & 0x3); - if (type != BspNodeType::Invalid) - offsets[i] = hecl::SBig(uint32_t(chNode.nodeOff - nodeOff - 36)); - } - - *pflags = hecl::SBig(flags); - ptr += 36; - - for (int i = 0; i < 8; ++i) - childNodes[i].writeColNodes(ptr, SplitAABB(curAABB, i)); - } - } -} - -void AROTBuilder::Node::pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount) { - ++nodeCount; - if (childNodes.empty()) { - lookupCount += childIndices.size(); - } else { - for (int i = 0; i < 8; ++i) - childNodes[i].pathCountNodesAndLookups(nodeCount, lookupCount); - } -} - -template -void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB) { - if (childNodes.empty()) { - auto& n = path.octree.emplace_back(); - n.isLeaf = 1; - n.aabb[0] = curAABB.min; - n.aabb[1] = curAABB.max; - n.centroid = curAABB.center(); - std::fill(std::begin(n.children), std::end(n.children), 0xFFFFFFFF); - n.regionCount = childIndices.size(); - n.regionStart = path.octreeRegionLookup.size(); - for (int r : childIndices) - path.octreeRegionLookup.push_back(r); - } else { - std::array children; - for (size_t i = 0; i < children.size(); ++i) { - /* Head recursion (first node will be a leaf) */ - childNodes[i].pathWrite(path, SplitAABB(curAABB, static_cast(i))); - children[i] = path.octree.size() - 1; - } - - auto& n = path.octree.emplace_back(); - n.isLeaf = 0; - n.aabb[0] = curAABB.min; - n.aabb[1] = curAABB.max; - n.centroid = curAABB.center(); - std::copy(children.cbegin(), children.cend(), std::begin(n.children)); - n.regionCount = 0; - n.regionStart = 0; - } -} - -template void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); -template void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); -template void AROTBuilder::Node::pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); - -void AROTBuilder::build(std::vector>& secs, const zeus::CAABox& fullAabb, - const std::vector& meshAabbs, const std::vector& meshes) { - /* Recursively split */ - BspNodeType rootType; - rootNode.addChild(0, AROT_MIN_MODELS, meshAabbs, fullAabb, rootType); - - /* Calculate indexing metrics */ - size_t totalNodeCount = 0; - size_t idxRefCount = 0; - size_t curOff = 0; - rootNode.nodeCount(totalNodeCount, idxRefCount, bmpPool, curOff); - size_t bmpWordCount = ROUND_UP_32(meshes.size()) / 32; - size_t arotSz = 64 + bmpWordCount * bmpPool.m_pool.size() * 4 + totalNodeCount * 8 + idxRefCount * 2; - - /* Write header */ - secs.emplace_back(arotSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - w.writeUint32Big('AROT'); - w.writeUint32Big(1); - w.writeUint32Big(bmpPool.m_pool.size()); - w.writeUint32Big(meshes.size()); - w.writeUint32Big(totalNodeCount); - w.writeVec3fBig(fullAabb.min); - w.writeVec3fBig(fullAabb.max); - w.seekAlign32(); - - /* Write bitmap */ - std::vector bmpWords; - bmpWords.reserve(bmpWordCount); - for (const std::set& bmp : bmpPool.m_pool) { - bmpWords.clear(); - bmpWords.resize(bmpWordCount); - - auto bmpIt = bmp.cbegin(); - if (bmpIt != bmp.cend()) { - int curIdx = 0; - for (size_t word = 0; word < bmpWordCount; ++word) { - for (u32 b = 0; b < 32; ++b) { - if (*bmpIt == curIdx) { - bmpWords[word] |= 1U << b; - ++bmpIt; - if (bmpIt == bmp.cend()) { - break; - } - } - ++curIdx; - } - if (bmpIt == bmp.cend()) { - break; - } - } - } - - for (uint32_t word : bmpWords) - w.writeUint32Big(word); - } - - /* Write the rest */ - rootNode.writeIndirectionTable(w); - rootNode.writeNodes(w, 0); -} - -std::pair, uint32_t> AROTBuilder::buildCol(const ColMesh& mesh, BspNodeType& rootOut) { - /* Accumulate total AABB */ - zeus::CAABox fullAABB; - for (const auto& vert : mesh.verts) - fullAABB.accumulateBounds(zeus::CVector3f(vert)); - - /* Predetermine triangle AABBs */ - std::vector triBoxes; - triBoxes.reserve(mesh.trianges.size()); - for (const ColMesh::Triangle& tri : mesh.trianges) { - zeus::CAABox& aabb = triBoxes.emplace_back(); - for (const u32 edgeIdx : tri.edges) { - const ColMesh::Edge& edge = mesh.edges[edgeIdx]; - for (const u32 vertIdx : edge.verts) { - const auto& vert = mesh.verts[vertIdx]; - aabb.accumulateBounds(zeus::CVector3f(vert)); - } - } - } - - /* Recursively split */ - rootNode.addChild(0, COLLISION_MIN_NODE_TRIANGLES, triBoxes, fullAABB, rootOut); - - /* Calculate offsets and write out */ - size_t totalSize = 0; - rootNode.colSize(totalSize); - std::unique_ptr ret(new uint8_t[totalSize]); - uint8_t* ptr = ret.get(); - rootNode.writeColNodes(ptr, fullAABB); - - return {std::move(ret), totalSize}; -} - -template -void AROTBuilder::buildPath(DNAPATH::PATH& path) { - /* Accumulate total AABB and gather region boxes */ - std::vector regionBoxes; - regionBoxes.reserve(path.regions.size()); - zeus::CAABox fullAABB; - for (const auto& r : path.regions) - fullAABB.accumulateBounds(regionBoxes.emplace_back(r.aabb[0], r.aabb[1])); - - /* Recursively split */ - BspNodeType dontCare; - rootNode.addChild(0, PATH_MIN_NODE_REGIONS, regionBoxes, fullAABB, dontCare); - - /* Write out */ - size_t nodeCount = 0; - size_t lookupCount = 0; - rootNode.pathCountNodesAndLookups(nodeCount, lookupCount); - path.octreeNodeCount = nodeCount; - path.octree.reserve(nodeCount); - path.octreeRegionLookupCount = lookupCount; - path.octreeRegionLookup.reserve(lookupCount); - rootNode.pathWrite(path, fullAABB); -} - -template void AROTBuilder::buildPath(DNAPATH::PATH& path); -template void AROTBuilder::buildPath(DNAPATH::PATH& path); -template void AROTBuilder::buildPath(DNAPATH::PATH& path); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/AROTBuilder.hpp b/DataSpec/DNACommon/AROTBuilder.hpp deleted file mode 100644 index d578c0567..000000000 --- a/DataSpec/DNACommon/AROTBuilder.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "DNACommon.hpp" -#include "DeafBabe.hpp" -#include "zeus/CAABox.hpp" -#include "CMDL.hpp" -#include - -namespace DataSpec { -namespace DNAPATH { -template -struct PATH; -} - -struct AROTBuilder { - using ColMesh = hecl::blender::ColMesh; - - struct BitmapPool { - std::vector> m_pool; - size_t addIndices(const std::set& indices); - } bmpPool; - - struct Node { - std::vector childNodes; - std::set childIndices; - size_t poolIdx = 0; - uint16_t flags = 0; - uint16_t compSubdivs = 0; - - size_t nodeOff = 0; - size_t nodeSz = 4; - - void addChild(int level, int minChildren, const std::vector& triBoxes, const zeus::CAABox& curAABB, - BspNodeType& typeOut); - void mergeSets(int a, int b); - bool compareSets(int a, int b) const; - void nodeCount(size_t& sz, size_t& idxRefs, BitmapPool& bmpPool, size_t& curOff); - void writeIndirectionTable(athena::io::MemoryWriter& w); - void writeNodes(athena::io::MemoryWriter& w, int nodeIdx); - void advanceIndex(int& nodeIdx); - - void colSize(size_t& totalSz); - void writeColNodes(uint8_t*& ptr, const zeus::CAABox& curAABB); - - void pathCountNodesAndLookups(size_t& nodeCount, size_t& lookupCount); - template - void pathWrite(DNAPATH::PATH& path, const zeus::CAABox& curAABB); - } rootNode; - - void build(std::vector>& secs, const zeus::CAABox& fullAabb, - const std::vector& meshAabbs, const std::vector& meshes); - std::pair, uint32_t> buildCol(const ColMesh& mesh, BspNodeType& rootOut); - template - void buildPath(DNAPATH::PATH& path); -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/ATBL.cpp b/DataSpec/DNACommon/ATBL.cpp deleted file mode 100644 index 38757305e..000000000 --- a/DataSpec/DNACommon/ATBL.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "DataSpec/DNACommon/ATBL.hpp" - -#include -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -#include -#include -#include -#include - -#include - -namespace DataSpec::DNAAudio { - -bool ATBL::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - uint32_t idxCount = rs.readUint32Big(); - athena::io::YAMLDocWriter w("ATBL"); - for (uint32_t i = 0; i < idxCount; ++i) { - uint16_t idx = rs.readUint16Big(); - if (idx == 0xffff) - continue; - w.writeUint16(fmt::format(FMT_STRING("0x{:04X}"), i), idx); - } - - athena::io::FileWriter fw(outPath.getAbsolutePath()); - w.finish(&fw); - - return true; -} - -bool ATBL::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - athena::io::FileReader r(inPath.getAbsolutePath()); - if (r.hasError()) - return false; - - athena::io::YAMLDocReader dr; - if (!dr.parse(&r)) - return false; - - unsigned long maxI = 0; - for (const auto& pair : dr.getRootNode()->m_mapChildren) { - unsigned long i = strtoul(pair.first.c_str(), nullptr, 0); - maxI = std::max(maxI, i); - } - - std::vector vecOut(maxI + 1, 0xffff); - for (const auto& pair : dr.getRootNode()->m_mapChildren) { - unsigned long i = strtoul(pair.first.c_str(), nullptr, 0); - vecOut[i] = hecl::SBig(uint16_t(strtoul(pair.second->m_scalarString.c_str(), nullptr, 0))); - } - - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - w.writeUint32Big(uint32_t(vecOut.size())); - w.writeBytes(vecOut.data(), vecOut.size() * 2); - - return true; -} - -} // namespace DataSpec::DNAAudio diff --git a/DataSpec/DNACommon/ATBL.hpp b/DataSpec/DNACommon/ATBL.hpp deleted file mode 100644 index bcd5abef4..000000000 --- a/DataSpec/DNACommon/ATBL.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAAudio { - -class ATBL { -public: - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAAudio diff --git a/DataSpec/DNACommon/BabeDead.cpp b/DataSpec/DNACommon/BabeDead.cpp deleted file mode 100644 index ff9b01526..000000000 --- a/DataSpec/DNACommon/BabeDead.cpp +++ /dev/null @@ -1,161 +0,0 @@ -#include "DataSpec/DNACommon/BabeDead.hpp" - -#include "DataSpec/DNAMP1/MREA.hpp" -#include "DataSpec/DNAMP3/MREA.hpp" - -#include - -#include -#include -#include - -#include - -namespace DataSpec { - -template -void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l) { - switch (light.lightType) { - case BabeDeadLight::LightType::LocalAmbient: - case BabeDeadLight::LightType::LocalAmbient2: - os.format(FMT_STRING("bg_node.inputs[0].default_value = ({},{},{},1.0)\n" - "bg_node.inputs[1].default_value = {}\n"), - light.color.simd[0], light.color.simd[1], light.color.simd[2], light.q / 8.f); - return; - case BabeDeadLight::LightType::Directional: - os.format(FMT_STRING("lamp = bpy.data.lights.new('LAMP_{:01d}_{:03d}', 'SUN')\n" - "lamp.color = ({},{},{})\n" - "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" - "lamp_obj.rotation_mode = 'QUATERNION'\n" - "lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector(({},{},{})))\n" - "lamp.use_shadow = {}\n" - "\n"), - s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], light.direction.simd[0], - light.direction.simd[1], light.direction.simd[2], light.castShadows ? "True" : "False"); - return; - case BabeDeadLight::LightType::Custom: - os.format(FMT_STRING("lamp = bpy.data.lights.new('LAMP_{:01d}_{:03d}', 'POINT')\n" - "lamp.color = ({},{},{})\n" - "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" - "lamp.shadow_soft_size = 1.0\n" - "lamp.use_shadow = {}\n" - "\n"), - s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], - light.castShadows ? "True" : "False"); - break; - case BabeDeadLight::LightType::Spot: - case BabeDeadLight::LightType::Spot2: - os.format(FMT_STRING("lamp = bpy.data.lights.new('LAMP_{:01d}_{:03d}', 'SPOT')\n" - "lamp.color = ({},{},{})\n" - "lamp.spot_size = {:.6g}\n" - "lamp_obj = bpy.data.objects.new(lamp.name, lamp)\n" - "lamp_obj.rotation_mode = 'QUATERNION'\n" - "lamp_obj.rotation_quaternion = Vector((0,0,-1)).rotation_difference(Vector(({},{},{})))\n" - "lamp.shadow_soft_size = 0.5\n" - "lamp.use_shadow = {}\n" - "\n"), - s, l, light.color.simd[0], light.color.simd[1], light.color.simd[2], zeus::degToRad(light.spotCutoff), - light.direction.simd[0], light.direction.simd[1], light.direction.simd[2], - light.castShadows ? "True" : "False"); - break; - default: - return; - } - - os.format(FMT_STRING("lamp.retro_layer = {}\n" - "lamp.retro_origtype = {}\n" - "lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n" - "lamp.constant_coefficient = 0\n" - "lamp.use_nodes = True\n" - "falloff_node = lamp.node_tree.nodes.new('ShaderNodeLightFalloff')\n" - "lamp.energy = 0.0\n" - "falloff_node.inputs[0].default_value = {}\n" - "hue_sat_node = lamp.node_tree.nodes.new('ShaderNodeHueSaturation')\n" - "hue_sat_node.inputs[1].default_value = 1.25\n" - "hue_sat_node.inputs[4].default_value = ({},{},{},1.0)\n" - "lamp.node_tree.links.new(hue_sat_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[0])\n" - "lamp_obj.location = ({},{},{})\n" - "bpy.context.scene.collection.objects.link(lamp_obj)\n" - "\n"), - s, unsigned(light.lightType), light.q / 8.f, light.color.simd[0], light.color.simd[1], light.color.simd[2], - light.position.simd[0], light.position.simd[1], light.position.simd[2]); - - switch (light.falloff) { - case BabeDeadLight::Falloff::Constant: - os << "falloff_node.inputs[0].default_value *= 150.0\n" - "lamp.node_tree.links.new(falloff_node.outputs[2], lamp.node_tree.nodes['Emission'].inputs[1])\n"; - if (light.q > FLT_EPSILON) - os.format(FMT_STRING("lamp.constant_coefficient = 2.0 / {}\n"), light.q); - break; - case BabeDeadLight::Falloff::Linear: - os << "lamp.node_tree.links.new(falloff_node.outputs[1], lamp.node_tree.nodes['Emission'].inputs[1])\n"; - if (light.q > FLT_EPSILON) - os.format(FMT_STRING("lamp.linear_coefficient = 250 / {}\n"), light.q); - break; - case BabeDeadLight::Falloff::Quadratic: - os << "lamp.node_tree.links.new(falloff_node.outputs[0], lamp.node_tree.nodes['Emission'].inputs[1])\n"; - if (light.q > FLT_EPSILON) - os.format(FMT_STRING("lamp.quadratic_coefficient = 25000 / {}\n"), light.q); - break; - default: - break; - } -} - -template void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, - const DNAMP1::MREA::BabeDeadLight& light, - unsigned s, unsigned l); -template void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, - const DNAMP3::MREA::BabeDeadLight& light, - unsigned s, unsigned l); - -template -void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn) { - using InterType = hecl::blender::Light::Type; - switch (lightIn.type) { - case InterType::Ambient: - lightOut.lightType = BabeDeadLight::LightType::LocalAmbient; - break; - case InterType::Directional: - lightOut.lightType = BabeDeadLight::LightType::Directional; - break; - case InterType::Custom: - default: - lightOut.lightType = BabeDeadLight::LightType::Custom; - break; - case InterType::Spot: - lightOut.lightType = BabeDeadLight::LightType::Spot; - break; - } - - if (lightIn.type == InterType::Ambient) { - lightOut.falloff = BabeDeadLight::Falloff::Constant; - lightOut.q = lightIn.energy * 8.f; - } else if (lightIn.linear > lightIn.constant && lightIn.linear > lightIn.quadratic) { - lightOut.falloff = BabeDeadLight::Falloff::Linear; - lightOut.q = 250.f / lightIn.linear; - } else if (lightIn.quadratic > lightIn.constant && lightIn.quadratic > lightIn.linear) { - lightOut.falloff = BabeDeadLight::Falloff::Quadratic; - lightOut.q = 25000.f / lightIn.quadratic; - } else { - lightOut.falloff = BabeDeadLight::Falloff::Constant; - lightOut.q = 2.f / lightIn.constant; - } - - lightOut.color = lightIn.color; - lightOut.spotCutoff = zeus::radToDeg(lightIn.spotCutoff); - lightOut.castShadows = lightIn.shadow; - lightOut.position.simd[0] = lightIn.sceneXf[0].simd[3]; - lightOut.position.simd[1] = lightIn.sceneXf[1].simd[3]; - lightOut.position.simd[2] = lightIn.sceneXf[2].simd[3]; - - zeus::CTransform lightXf(&lightIn.sceneXf[0]); - lightOut.direction = (lightXf.basis.transposed() * zeus::CVector3f(0.f, 0.f, -1.f)).normalized(); -} - -template void WriteBabeDeadLightFromBlender(DNAMP1::MREA::BabeDeadLight& lightOut, - const hecl::blender::Light& lightIn); -template void WriteBabeDeadLightFromBlender(DNAMP3::MREA::BabeDeadLight& lightOut, - const hecl::blender::Light& lightIn); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/BabeDead.hpp b/DataSpec/DNACommon/BabeDead.hpp deleted file mode 100644 index 3c6781c72..000000000 --- a/DataSpec/DNACommon/BabeDead.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -namespace hecl::blender { -struct Light; -class PyOutStream; -} // namespace hecl::blender - -namespace DataSpec { - -template -void ReadBabeDeadLightToBlender(hecl::blender::PyOutStream& os, const BabeDeadLight& light, unsigned s, unsigned l); - -template -void WriteBabeDeadLightFromBlender(BabeDeadLight& lightOut, const hecl::blender::Light& lightIn); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/CMDL.cpp b/DataSpec/DNACommon/CMDL.cpp deleted file mode 100644 index a09122128..000000000 --- a/DataSpec/DNACommon/CMDL.cpp +++ /dev/null @@ -1,2271 +0,0 @@ -#include "DataSpec/DNACommon/CMDL.hpp" - -#include - -#include "DataSpec/DNAMP1/CMDLMaterials.hpp" -#include "DataSpec/DNAMP1/CSKR.hpp" -#include "DataSpec/DNAMP1/MREA.hpp" -#include "DataSpec/DNAMP2/CMDLMaterials.hpp" -#include "DataSpec/DNAMP2/CSKR.hpp" -#include "DataSpec/DNAMP3/CMDLMaterials.hpp" -#include "DataSpec/DNAMP3/CSKR.hpp" - -#include -#include -#include - -namespace DataSpec::DNACMDL { - -template -void GetVertexAttributes(const MaterialSet& matSet, std::vector& attributesOut) { - attributesOut.clear(); - attributesOut.reserve(matSet.materials.size()); - - for (const typename MaterialSet::Material& mat : matSet.materials) { - const typename MaterialSet::Material::VAFlags& vaFlags = mat.getVAFlags(); - attributesOut.emplace_back(); - VertexAttributes& va = attributesOut.back(); - - va.pos = vaFlags.position(); - va.norm = vaFlags.normal(); - va.color0 = vaFlags.color0(); - va.color1 = vaFlags.color1(); - - if ((va.uvs[0] = vaFlags.tex0())) - ++va.uvCount; - if ((va.uvs[1] = vaFlags.tex1())) - ++va.uvCount; - if ((va.uvs[2] = vaFlags.tex2())) - ++va.uvCount; - if ((va.uvs[3] = vaFlags.tex3())) - ++va.uvCount; - if ((va.uvs[4] = vaFlags.tex4())) - ++va.uvCount; - if ((va.uvs[5] = vaFlags.tex5())) - ++va.uvCount; - if ((va.uvs[6] = vaFlags.tex6())) - ++va.uvCount; - - va.pnMtxIdx = vaFlags.pnMatIdx(); - - if ((va.texMtxIdx[0] = vaFlags.tex0MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[1] = vaFlags.tex1MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[2] = vaFlags.tex2MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[3] = vaFlags.tex3MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[4] = vaFlags.tex4MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[5] = vaFlags.tex5MatIdx())) - ++va.texMtxIdxCount; - if ((va.texMtxIdx[6] = vaFlags.tex6MatIdx())) - ++va.texMtxIdxCount; - - va.shortUVs = mat.getFlags().lightmapUVArray(); - } -} - -template -void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx) { - /* Texmaps */ - os << "texmap_list = []\n"; - for (const UniqueID32& tex : matSet.head.textureIDs) { - std::string texName = pakRouter.getBestEntryName(tex); - const nod::Node* node; - const typename PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(tex, &node); - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (!txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - std::string resPath = pakRouter.getResourceRelativePath(entry, tex); - os.format(FMT_STRING("if '{}' in bpy.data.images:\n" - " image = bpy.data.images['{}']\n" - "else:\n" - " image = bpy.data.images.load('''//{}''')\n" - " image.name = '{}'\n" - "texmap_list.append(image)\n" - "\n"), - texName, texName, resPath, texName); - } - - unsigned m = 0; - for (const typename MaterialSet::Material& mat : matSet.materials) { - MaterialSet::ConstructMaterial(os, mat, setIdx, m++); - os << "materials.append(new_material)\n"; - } -} - -template -void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx) { - unsigned m = 0; - for (const typename MaterialSet::Material& mat : matSet.materials) { - MaterialSet::ConstructMaterial(os, pakRouter, entry, mat, setIdx, m++); - os << "materials.append(new_material)\n"; - } -} - -template void ReadMaterialSetToBlender_3, DNAMP3::MaterialSet>( - hecl::blender::PyOutStream& os, const DNAMP3::MaterialSet& matSet, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx); - -class DLReader { -public: - /* Class used for splitting verts with shared positions but different skinning matrices */ - class ExtraVertTracker { - std::map>> m_extraVerts; - atUint16 m_maxBasePos = 0; - atUint16 m_nextOverPos = 1; - - public: - atInt16 addPosSkinPair(atUint16 pos, atInt16 skin) { - m_maxBasePos = std::max(m_maxBasePos, pos); - auto search = m_extraVerts.find(pos); - if (search == m_extraVerts.end()) { - m_extraVerts[pos] = {std::make_pair(skin, 0)}; - return skin; - } - std::vector>& vertTrack = search->second; - for (const std::pair& s : vertTrack) - if (s.first == skin) - return vertTrack.front().first; - vertTrack.push_back(std::make_pair(skin, m_nextOverPos++)); - return vertTrack.front().first; - } - - template - atUint32 sendAdditionalVertsToBlender(hecl::blender::PyOutStream& os, const RigPair& rp, atUint32 baseVert) const { - atUint32 addedVerts = 0; - atUint32 nextVert = 1; - while (nextVert < m_nextOverPos) { - for (const auto& [ev, evVec] : m_extraVerts) { - for (const std::pair& se : evVec) { - if (se.second == nextVert) { - os.format(FMT_STRING("bm.verts.ensure_lookup_table()\n" - "orig_vert = bm.verts[{}]\n" - "vert = bm.verts.new(orig_vert.co)\n"), - ev + baseVert); - rp.first.second->weightVertex(os, *rp.second.second, se.first); - ++nextVert; - ++addedVerts; - } - } - } - } - return addedVerts; - } - - atUint16 lookupVertIdx(atUint16 pos, atInt16 skin) const { - auto search = m_extraVerts.find(pos); - if (search == m_extraVerts.end()) - return -1; - const std::vector>& vertTrack = search->second; - if (vertTrack.front().first == skin) - return pos; - for (auto it = vertTrack.begin() + 1; it != vertTrack.end(); ++it) - if (it->first == skin) - return m_maxBasePos + it->second; - return -1; - } - }; - -private: - const VertexAttributes& m_va; - std::unique_ptr m_dl; - size_t m_dlSize; - ExtraVertTracker& m_evt; - const atInt16* m_bankIn; - atUint8* m_cur; - atUint16 readVal(GX::AttrType type) { - atUint16 retval = 0; - switch (type) { - case GX::DIRECT: - case GX::INDEX8: - if ((m_cur - m_dl.get()) >= intptr_t(m_dlSize)) - return 0; - retval = *m_cur; - ++m_cur; - break; - case GX::INDEX16: - if ((m_cur - m_dl.get() + 1) >= intptr_t(m_dlSize)) - return 0; - retval = hecl::SBig(*(atUint16*)m_cur); - m_cur += 2; - break; - default: - break; - } - return retval; - } - -public: - DLReader(const VertexAttributes& va, std::unique_ptr&& dl, size_t dlSize, ExtraVertTracker& evt, - const atInt16* bankIn = nullptr) - : m_va(va), m_dl(std::move(dl)), m_dlSize(dlSize), m_evt(evt), m_bankIn(bankIn) { - m_cur = m_dl.get(); - } - - explicit operator bool() const { return ((m_cur - m_dl.get()) < intptr_t(m_dlSize)) && *m_cur; } - - GX::Primitive readPrimitive() { return GX::Primitive(*m_cur++ & 0xf8); } - - GX::Primitive readPrimitiveAndVat(unsigned& vatOut) { - atUint8 val = *m_cur++; - vatOut = val & 0x7; - return GX::Primitive(val & 0xf8); - } - - atUint16 readVertCount() { - atUint16 retval = hecl::SBig(*(atUint16*)m_cur); - m_cur += 2; - return retval; - } - - struct DLPrimVert { - atUint16 pos = 0; - atUint16 norm = 0; - atUint16 color[2] = {0}; - atUint16 uvs[7] = {0}; - atUint8 pnMtxIdx = 0; - atUint8 texMtxIdx[7] = {0}; - }; - - DLPrimVert readVert(bool peek = false) { - atUint8* bakCur = m_cur; - DLPrimVert retval; - retval.pnMtxIdx = readVal(m_va.pnMtxIdx); - retval.texMtxIdx[0] = readVal(m_va.texMtxIdx[0]); - retval.texMtxIdx[1] = readVal(m_va.texMtxIdx[1]); - retval.texMtxIdx[2] = readVal(m_va.texMtxIdx[2]); - retval.texMtxIdx[3] = readVal(m_va.texMtxIdx[3]); - retval.texMtxIdx[4] = readVal(m_va.texMtxIdx[4]); - retval.texMtxIdx[5] = readVal(m_va.texMtxIdx[5]); - retval.texMtxIdx[6] = readVal(m_va.texMtxIdx[6]); - if (m_bankIn) { - atUint16 posIdx = readVal(m_va.pos); - atUint8 mtxIdx = retval.pnMtxIdx / 3; - atInt16 skinIdx = -1; - if (mtxIdx < 10) - skinIdx = m_bankIn[mtxIdx]; - retval.pos = m_evt.lookupVertIdx(posIdx, skinIdx); - } else - retval.pos = readVal(m_va.pos); - retval.norm = readVal(m_va.norm); - retval.color[0] = readVal(m_va.color0); - retval.color[1] = readVal(m_va.color1); - retval.uvs[0] = readVal(m_va.uvs[0]); - retval.uvs[1] = readVal(m_va.uvs[1]); - retval.uvs[2] = readVal(m_va.uvs[2]); - retval.uvs[3] = readVal(m_va.uvs[3]); - retval.uvs[4] = readVal(m_va.uvs[4]); - retval.uvs[5] = readVal(m_va.uvs[5]); - retval.uvs[6] = readVal(m_va.uvs[6]); - if (peek) - m_cur = bakCur; - return retval; - } - - void preReadMaxIdxs(DLPrimVert& out) { - atUint8* bakCur = m_cur; - while (*this) { - readPrimitive(); - atUint16 vc = readVertCount(); - for (atUint16 v = 0; v < vc; ++v) { - atUint16 val; - val = readVal(m_va.pnMtxIdx); - out.pnMtxIdx = std::max(out.pnMtxIdx, atUint8(val)); - val = readVal(m_va.texMtxIdx[0]); - out.texMtxIdx[0] = std::max(out.texMtxIdx[0], atUint8(val)); - val = readVal(m_va.texMtxIdx[1]); - out.texMtxIdx[1] = std::max(out.texMtxIdx[1], atUint8(val)); - val = readVal(m_va.texMtxIdx[2]); - out.texMtxIdx[2] = std::max(out.texMtxIdx[2], atUint8(val)); - val = readVal(m_va.texMtxIdx[3]); - out.texMtxIdx[3] = std::max(out.texMtxIdx[3], atUint8(val)); - val = readVal(m_va.texMtxIdx[4]); - out.texMtxIdx[4] = std::max(out.texMtxIdx[4], atUint8(val)); - val = readVal(m_va.texMtxIdx[5]); - out.texMtxIdx[5] = std::max(out.texMtxIdx[5], atUint8(val)); - val = readVal(m_va.texMtxIdx[6]); - out.texMtxIdx[6] = std::max(out.texMtxIdx[6], atUint8(val)); - val = readVal(m_va.pos); - out.pos = std::max(out.pos, val); - val = readVal(m_va.norm); - out.norm = std::max(out.norm, val); - val = readVal(m_va.color0); - out.color[0] = std::max(out.color[0], val); - val = readVal(m_va.color1); - out.color[1] = std::max(out.color[1], val); - val = readVal(m_va.uvs[0]); - out.uvs[0] = std::max(out.uvs[0], val); - val = readVal(m_va.uvs[1]); - out.uvs[1] = std::max(out.uvs[1], val); - val = readVal(m_va.uvs[2]); - out.uvs[2] = std::max(out.uvs[2], val); - val = readVal(m_va.uvs[3]); - out.uvs[3] = std::max(out.uvs[3], val); - val = readVal(m_va.uvs[4]); - out.uvs[4] = std::max(out.uvs[4], val); - val = readVal(m_va.uvs[5]); - out.uvs[5] = std::max(out.uvs[5], val); - val = readVal(m_va.uvs[6]); - out.uvs[6] = std::max(out.uvs[6], val); - } - } - m_cur = bakCur; - } - - void preReadMaxIdxs(DLPrimVert& out, std::vector& skinOut) { - atUint8* bakCur = m_cur; - while (*this) { - readPrimitive(); - atUint16 vc = readVertCount(); - for (atUint16 v = 0; v < vc; ++v) { - atUint16 val; - atUint8 pnMtxVal = readVal(m_va.pnMtxIdx); - out.pnMtxIdx = std::max(out.pnMtxIdx, pnMtxVal); - val = readVal(m_va.texMtxIdx[0]); - out.texMtxIdx[0] = std::max(out.texMtxIdx[0], atUint8(val)); - val = readVal(m_va.texMtxIdx[1]); - out.texMtxIdx[1] = std::max(out.texMtxIdx[1], atUint8(val)); - val = readVal(m_va.texMtxIdx[2]); - out.texMtxIdx[2] = std::max(out.texMtxIdx[2], atUint8(val)); - val = readVal(m_va.texMtxIdx[3]); - out.texMtxIdx[3] = std::max(out.texMtxIdx[3], atUint8(val)); - val = readVal(m_va.texMtxIdx[4]); - out.texMtxIdx[4] = std::max(out.texMtxIdx[4], atUint8(val)); - val = readVal(m_va.texMtxIdx[5]); - out.texMtxIdx[5] = std::max(out.texMtxIdx[5], atUint8(val)); - val = readVal(m_va.texMtxIdx[6]); - out.texMtxIdx[6] = std::max(out.texMtxIdx[6], atUint8(val)); - atUint16 posVal = readVal(m_va.pos); - out.pos = std::max(out.pos, posVal); - val = readVal(m_va.norm); - out.norm = std::max(out.norm, val); - val = readVal(m_va.color0); - out.color[0] = std::max(out.color[0], val); - val = readVal(m_va.color1); - out.color[1] = std::max(out.color[1], val); - val = readVal(m_va.uvs[0]); - out.uvs[0] = std::max(out.uvs[0], val); - val = readVal(m_va.uvs[1]); - out.uvs[1] = std::max(out.uvs[1], val); - val = readVal(m_va.uvs[2]); - out.uvs[2] = std::max(out.uvs[2], val); - val = readVal(m_va.uvs[3]); - out.uvs[3] = std::max(out.uvs[3], val); - val = readVal(m_va.uvs[4]); - out.uvs[4] = std::max(out.uvs[4], val); - val = readVal(m_va.uvs[5]); - out.uvs[5] = std::max(out.uvs[5], val); - val = readVal(m_va.uvs[6]); - out.uvs[6] = std::max(out.uvs[6], val); - - atInt16 skinIdx = m_bankIn[pnMtxVal / 3]; - skinOut[posVal] = m_evt.addPosSkinPair(posVal, skinIdx); - } - } - m_cur = bakCur; - } -}; - -void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath) { - os << "import math\n" - "from mathutils import Vector\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "def loop_from_facevert(bm, face, vert_idx):\n" - " for loop in face.loops:\n" - " if loop.vert[bm.verts.layers.int['CMDLOriginalPosIdxs']] == vert_idx:\n" - " return loop\n" - "\n" - "def loops_from_edgevert(bm, edge, vert):\n" - " ret = []\n" - " for face in edge.link_faces:\n" - " for loop in face.loops:\n" - " if loop.vert == vert:\n" - " ret.append(loop)\n" - " return ret\n" - "\n" - "def add_triangle(bm, vert_seq, vert_indices, norm_seq, norm_indices, mat_nr, od_list, two_face_vert):\n" - " if len(set(vert_indices)) != 3:\n" - " return None, None\n" - "\n" - " ret_mesh = bm\n" - " vert_seq.ensure_lookup_table()\n" - " verts = [vert_seq[i] for i in vert_indices]\n" - "\n" - " # Try getting existing face\n" - " face = bm.faces.get(verts)\n" - "\n" - " if face is not None and face.material_index != mat_nr: # Same poly, new material\n" - " # Overdraw detected; track copy\n" - " od_entry = None\n" - " for entry in od_list:\n" - " if entry['material'] == mat_nr:\n" - " od_entry = entry\n" - " if od_entry is None:\n" - " bm_cpy = bm.copy()\n" - " od_entry = {'material':mat_nr, 'bm':bm_cpy}\n" - " bmesh.ops.delete(od_entry['bm'], geom=od_entry['bm'].faces, context='FACES_ONLY')\n" - " od_list.append(od_entry)\n" - " od_entry['bm'].verts.ensure_lookup_table()\n" - " verts = [od_entry['bm'].verts[i] for i in vert_indices]\n" - " face = od_entry['bm'].faces.get(verts)\n" - " if face is None:\n" - " face = od_entry['bm'].faces.new(verts)\n" - " else: # Probably a double-sided surface\n" - " verts = [od_entry['bm'].verts[i + two_face_vert] for i in vert_indices]\n" - " face = od_entry['bm'].faces.get(verts)\n" - " if face is None:\n" - " face = od_entry['bm'].faces.new(verts)\n" - " ret_mesh = od_entry['bm']\n" - "\n" - " elif face is not None: # Same material, probably double-sided\n" - " verts = [vert_seq[i + two_face_vert] for i in vert_indices]\n" - " face = bm.faces.get(verts)\n" - " if face is None:\n" - " face = bm.faces.new(verts)\n" - "\n" - " else: # Make totally new face\n" - " face = bm.faces.new(verts)\n" - "\n" - " for i in range(3):\n" - " face.verts[i][ret_mesh.verts.layers.int['CMDLOriginalPosIdxs']] = vert_indices[i]\n" - " face.loops[i][ret_mesh.loops.layers.int['CMDLOriginalNormIdxs']] = norm_indices[i]\n" - " face.material_index = mat_nr\n" - " face.smooth = True\n" - "\n" - " return face, ret_mesh\n" - "\n" - "def expand_lightmap_triangle(lightmap_tri_tracker, uva, uvb, uvc):\n" - " result = ([uva[0],uva[1]], [uvb[0],uvb[1]], [uvc[0],uvc[1]])\n" - " inst = 0\n" - " if uva in lightmap_tri_tracker:\n" - " inst = lightmap_tri_tracker[uva]\n" - " lightmap_tri_tracker[uva] = inst + 1\n" - " if uva == uvb:\n" - " result[1][0] += 0.005\n" - " if uva == uvc:\n" - " result[2][1] -= 0.005\n" - " if inst & 0x1 and uva == uvb and uva == uvc:\n" - " result[0][0] += 0.005\n" - " result[0][1] -= 0.005\n" - " return result\n" - "\n"; - - /* Link master shader library */ - os.format(FMT_STRING("# Master shader library\n" - "with bpy.data.libraries.load('{}', link=True, relative=True) as (data_from, data_to):\n" - " data_to.node_groups = data_from.node_groups\n" - "\n"), - masterShaderPath.getAbsolutePath()); -} - -void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx) { - os << "if 'Render' not in bpy.data.collections:\n" - " coll = bpy.data.collections.new('Render')\n" - " bpy.context.scene.collection.children.link(coll)\n" - "else:\n" - " coll = bpy.data.collections['Render']\n"; - if (meshIdx < 0) { - os << "mesh = bpy.data.meshes.new(bpy.context.scene.name)\n" - "obj = bpy.data.objects.new(mesh.name, mesh)\n" - "obj.show_transparent = True\n" - "coll.objects.link(obj)\n"; - os.format(FMT_STRING("mesh.hecl_material_count = {}\n"), matSetCount); - } else { - os.format(FMT_STRING("mesh = bpy.data.meshes.new(bpy.context.scene.name + '_{:03d}')\n"), meshIdx); - os << "obj = bpy.data.objects.new(mesh.name, mesh)\n" - "obj.show_transparent = True\n" - "coll.objects.link(obj)\n"; - os.format(FMT_STRING("mesh.hecl_material_count = {}\n"), matSetCount); - } - - os << "mesh.use_auto_smooth = True\n" - "mesh.auto_smooth_angle = math.pi\n" - "\n" - "for material in materials:\n" - " mesh.materials.append(material)\n" - "\n" - "# Merge OD meshes\n" - "for od_entry in od_list:\n" - " vert_dict = [{},{}]\n" - "\n" - " for vert in od_entry['bm'].verts:\n" - " if len(vert.link_faces):\n" - " if vert.index >= two_face_vert:\n" - " use_vert_dict = vert_dict[1]\n" - " else:\n" - " use_vert_dict = vert_dict[0]\n" - " copy_vert = bm.verts.new(vert.co, vert)\n" - " use_vert_dict[vert[od_entry['bm'].verts.layers.int['CMDLOriginalPosIdxs']]] = copy_vert\n" - " copy_vert[orig_pidx_lay] = vert[od_entry['bm'].verts.layers.int['CMDLOriginalPosIdxs']]\n" - "\n" - " for face in od_entry['bm'].faces:\n" - " if face.verts[0].index >= two_face_vert:\n" - " use_vert_dict = vert_dict[1]\n" - " else:\n" - " use_vert_dict = vert_dict[0]\n" - " merge_verts = [use_vert_dict[fv[od_entry['bm'].verts.layers.int['CMDLOriginalPosIdxs']]] for fv in " - "face.verts]\n" - " try:\n" - " if bm.faces.get(merge_verts) is not None:\n" - " continue\n" - " except:\n" - " continue\n" - " merge_face = bm.faces.new(merge_verts)\n" - " for i in range(len(face.loops)):\n" - " old = face.loops[i]\n" - " new = merge_face.loops[i]\n" - " for j in range(len(od_entry['bm'].loops.layers.uv)):\n" - " new[bm.loops.layers.uv[j]] = old[od_entry['bm'].loops.layers.uv[j]]\n" - " new[orig_nidx_lay] = old[od_entry['bm'].loops.layers.int['CMDLOriginalNormIdxs']]\n" - " merge_face.smooth = True\n" - " merge_face.material_index = face.material_index\n" - "\n" - " od_entry['bm'].free()\n" - "\n" - "verts_to_del = []\n" - "for v in bm.verts:\n" - " if len(v.link_faces) == 0:\n" - " verts_to_del.append(v)\n" - "bmesh.ops.delete(bm, geom=verts_to_del, context='VERTS')\n" - "\n" - "for edge in bm.edges:\n" - " if edge.is_manifold:\n" - " pass_count = 0\n" - " for vert in edge.verts:\n" - " loops = loops_from_edgevert(bm, edge, vert)\n" - " norm0 = Vector(norm_list[loops[0][orig_nidx_lay]])\n" - " norm1 = Vector(norm_list[loops[1][orig_nidx_lay]])\n" - " if norm0.dot(norm1) < 0.9:\n" - " pass_count += 1\n" - " if pass_count > 0:\n" - " edge.smooth = False\n" - "\n" - "bm.to_mesh(mesh)\n" - "bm.free()\n" - "\n" - "# Remove redundant materials\n" - "present_mats = set()\n" - "for poly in mesh.polygons:\n" - " present_mats.add(poly.material_index)\n" - "for mat_idx in reversed(range(len(mesh.materials))):\n" - " if mat_idx not in present_mats:\n" - " mesh.materials.pop(index=mat_idx)\n" - "\n" - "mesh.update()\n" - "\n"; -} - -template -atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const RigPair& rp, - bool shortNormals, bool shortUVs, std::vector& vertAttribs, - int meshIdx, atUint32 secCount, atUint32 matSetCount, const atUint32* secSizes, - atUint32 surfaceCount) { - os << "# Begin bmesh\n" - "bm = bmesh.new()\n" - "\n" - "# Overdraw-tracking\n" - "od_list = []\n" - "\n" - "orig_pidx_lay = bm.verts.layers.int.new('CMDLOriginalPosIdxs')\n" - "orig_nidx_lay = bm.loops.layers.int.new('CMDLOriginalNormIdxs')\n" - "\n" - "lightmap_tri_tracker = {}\n"; - - if (rp.first.second) - os << "dvert_lay = bm.verts.layers.deform.verify()\n"; - - /* Pre-read pass to determine maximum used vert indices */ - atUint32 matSecCount = 0; - if (matSetCount) - matSecCount = MaterialSet::OneSection() ? 1 : matSetCount; - bool visitedDLOffsets = false; - atUint32 lastDlSec = secCount; - atUint64 afterHeaderPos = reader.position(); - DLReader::DLPrimVert maxIdxs; - std::vector skinIndices; - DLReader::ExtraVertTracker extraTracker; - for (atUint32 s = 0; s < lastDlSec; ++s) { - atUint64 secStart = reader.position(); - if (s < matSecCount) { - if (!s) { - MaterialSet matSet; - matSet.read(reader); - matSet.ensureTexturesExtracted(pakRouter); - GetVertexAttributes(matSet, vertAttribs); - } - } else { - switch (s - matSecCount) { - case 0: { - /* Positions */ - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - skinIndices.assign(secSizes[s] / 12, -1); - break; - } - case 1: { - /* Normals */ - break; - } - case 2: { - /* Colors */ - break; - } - case 3: { - /* Float UVs */ - break; - } - case 4: { - if (surfaceCount) { - /* MP3 MREA case */ - visitedDLOffsets = true; - lastDlSec = 4 + surfaceCount; - } else { - /* Short UVs */ - if (shortUVs) - break; - - /* DL Offsets (here or next section) */ - visitedDLOffsets = true; - lastDlSec = s + reader.readUint32Big() + 1; - break; - } - [[fallthrough]]; - } - default: { - if (!visitedDLOffsets) { - visitedDLOffsets = true; - lastDlSec = s + reader.readUint32Big() + 1; - break; - } - - /* GX Display List (surface) */ - SurfaceHeader sHead; - sHead.read(reader); - const atInt16* bankIn = nullptr; - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - bankIn = rp.first.second->getMatrixBank(sHead.skinMatrixBankIdx()); - - /* Do max index pre-read */ - atUint32 realDlSize = secSizes[s] - (reader.position() - secStart); - DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize, extraTracker, bankIn); - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - dl.preReadMaxIdxs(maxIdxs, skinIndices); - else - dl.preReadMaxIdxs(maxIdxs); - } - } - } - - if (s < secCount - 1) { - reader.seek(secStart + secSizes[s], athena::SeekOrigin::Begin); - } - } - - reader.seek(afterHeaderPos, athena::SeekOrigin::Begin); - - visitedDLOffsets = false; - unsigned createdUVLayers = 0; - unsigned surfIdx = 0; - - for (atUint32 s = 0; s < lastDlSec; ++s) { - atUint64 secStart = reader.position(); - if (s < matSecCount) { - MaterialSet matSet; - matSet.read(reader); - matSet.readToBlender(os, pakRouter, entry, s); - if (!s) - GetVertexAttributes(matSet, vertAttribs); - } else { - switch (s - matSecCount) { - case 0: { - /* Positions */ - atUint32 vertCount = maxIdxs.pos + 1; - std::vector positions; - positions.reserve(vertCount); - for (atUint16 i = 0; i <= maxIdxs.pos; ++i) { - positions.push_back(reader.readVec3fBig()); - const atVec3f& pos = positions.back(); - os.format(FMT_STRING("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]); - if (rp.first.second) { - if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - rp.first.second->weightVertex(os, *rp.second.second, skinIndices[i]); - else if (!SurfaceHeader::UseMatrixSkinning()) - rp.first.second->weightVertex(os, *rp.second.second, i); - } - } - if (rp.first.second && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - vertCount += extraTracker.sendAdditionalVertsToBlender(os, rp, 0); - os.format(FMT_STRING("two_face_vert = {}\n"), vertCount); - for (atUint16 i = 0; i <= maxIdxs.pos; ++i) { - const atVec3f& pos = positions[i]; - os.format(FMT_STRING("vert = bm.verts.new(({},{},{}))\n"), pos.simd[0], pos.simd[1], pos.simd[2]); - if (rp.first.second) { - if (SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - rp.first.second->weightVertex(os, *rp.second.second, skinIndices[i]); - else if (!SurfaceHeader::UseMatrixSkinning()) - rp.first.second->weightVertex(os, *rp.second.second, i); - } - } - if (rp.first.second && SurfaceHeader::UseMatrixSkinning() && !skinIndices.empty()) - extraTracker.sendAdditionalVertsToBlender(os, rp, vertCount); - break; - } - case 1: { - /* Normals */ - os << "norm_list = []\n"; - if (shortNormals) { - atUint32 normCount = secSizes[s] / 6; - for (atUint32 i = 0; i < normCount; ++i) { - float x = reader.readInt16Big() / 16384.0f; - float y = reader.readInt16Big() / 16384.0f; - float z = reader.readInt16Big() / 16384.0f; - os.format(FMT_STRING("norm_list.append(({},{},{}))\n"), x, y, z); - } - } else { - atUint32 normCount = secSizes[s] / 12; - for (atUint32 i = 0; i < normCount; ++i) { - const atVec3f norm = reader.readVec3fBig(); - os.format(FMT_STRING("norm_list.append(({},{},{}))\n"), norm.simd[0], norm.simd[1], norm.simd[2]); - } - } - break; - } - case 2: { - /* Colors */ - break; - } - case 3: { - /* Float UVs */ - os << "uv_list = []\n"; - atUint32 uvCount = secSizes[s] / 8; - for (atUint32 i = 0; i < uvCount; ++i) { - const atVec2f uv = reader.readVec2fBig(); - os.format(FMT_STRING("uv_list.append(({},{}))\n"), uv.simd[0], uv.simd[1]); - } - break; - } - case 4: { - if (surfaceCount) { - /* MP3 MREA case */ - visitedDLOffsets = true; - } else { - /* Short UVs */ - os << "suv_list = []\n"; - if (shortUVs) { - atUint32 uvCount = secSizes[s] / 4; - for (atUint32 i = 0; i < uvCount; ++i) { - float x = reader.readInt16Big() / 32768.0f; - float y = reader.readInt16Big() / 32768.0f; - os.format(FMT_STRING("suv_list.append(({},{}))\n"), x, y); - } - break; - } - - /* DL Offsets (here or next section) */ - visitedDLOffsets = true; - break; - } - [[fallthrough]]; - } - default: { - if (!visitedDLOffsets) { - visitedDLOffsets = true; - break; - } - - /* GX Display List (surface) */ - SurfaceHeader sHead; - sHead.read(reader); - VertexAttributes& curVA = vertAttribs[sHead.matIdx]; - unsigned matUVCount = curVA.uvCount; - bool matShortUVs = curVA.shortUVs; - const atInt16* bankIn = nullptr; - if (SurfaceHeader::UseMatrixSkinning() && rp.first.second) - bankIn = rp.first.second->getMatrixBank(sHead.skinMatrixBankIdx()); - - os.format(FMT_STRING("materials[{}].pass_index = {}\n"), sHead.matIdx, surfIdx++); - if (matUVCount > createdUVLayers) { - for (unsigned l = createdUVLayers; l < matUVCount; ++l) - os.format(FMT_STRING("bm.loops.layers.uv.new('UV_{}')\n"), l); - createdUVLayers = matUVCount; - } - - atUint32 realDlSize = secSizes[s] - (reader.position() - secStart); - DLReader dl(vertAttribs[sHead.matIdx], reader.readUBytes(realDlSize), realDlSize, extraTracker, bankIn); - - while (dl) { - GX::Primitive ptype = dl.readPrimitive(); - atUint16 vertCount = dl.readVertCount(); - - /* First vert */ - DLReader::DLPrimVert firstPrimVert = dl.readVert(true); - - /* 3 Prim Verts to start */ - int c = 0; - DLReader::DLPrimVert primVerts[3] = {dl.readVert(), dl.readVert(), dl.readVert()}; - - if (ptype == GX::TRIANGLESTRIP) { - atUint8 flip = 0; - for (int v = 0; v < vertCount - 2; ++v) { - if (flip) { - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - primVerts[c % 3].pos, primVerts[(c + 2) % 3].pos, primVerts[(c + 1) % 3].pos, - primVerts[c % 3].norm, primVerts[(c + 2) % 3].norm, primVerts[(c + 1) % 3].norm, - sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - primVerts[c % 3].uvs[j], primVerts[(c + 2) % 3].uvs[j], primVerts[(c + 1) % 3].uvs[j], - primVerts[c % 3].pos, j, primVerts[(c + 2) % 3].pos, j, primVerts[(c + 1) % 3].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - primVerts[c % 3].pos, j, primVerts[c % 3].uvs[j], primVerts[(c + 2) % 3].pos, j, - primVerts[(c + 2) % 3].uvs[j], primVerts[(c + 1) % 3].pos, j, primVerts[(c + 1) % 3].uvs[j]); - } - } - } else { - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - primVerts[c % 3].pos, primVerts[(c + 1) % 3].pos, primVerts[(c + 2) % 3].pos, - primVerts[c % 3].norm, primVerts[(c + 1) % 3].norm, primVerts[(c + 2) % 3].norm, - sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - primVerts[c % 3].uvs[j], primVerts[(c + 1) % 3].uvs[j], primVerts[(c + 2) % 3].uvs[j], - primVerts[c % 3].pos, j, primVerts[(c + 1) % 3].pos, j, primVerts[(c + 2) % 3].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - primVerts[c % 3].pos, j, primVerts[c % 3].uvs[j], primVerts[(c + 1) % 3].pos, j, - primVerts[(c + 1) % 3].uvs[j], primVerts[(c + 2) % 3].pos, j, primVerts[(c + 2) % 3].uvs[j]); - } - } - } - flip ^= 1; - - bool peek = (v >= vertCount - 3); - - /* Advance one prim vert */ - primVerts[c % 3] = dl.readVert(peek); - ++c; - } - } else if (ptype == GX::TRIANGLES) { - for (int v = 0; v < vertCount; v += 3) { - - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - primVerts[0].pos, primVerts[1].pos, primVerts[2].pos, primVerts[0].norm, primVerts[1].norm, - primVerts[2].norm, sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - primVerts[0].uvs[j], primVerts[1].uvs[j], primVerts[2].uvs[j], primVerts[0].pos, j, - primVerts[1].pos, j, primVerts[2].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - primVerts[0].pos, j, primVerts[0].uvs[j], primVerts[1].pos, j, primVerts[1].uvs[j], - primVerts[2].pos, j, primVerts[2].uvs[j]); - } - } - - /* Break if done */ - if (v + 3 >= vertCount) - break; - - /* Advance 3 Prim Verts */ - for (int pv = 0; pv < 3; ++pv) - primVerts[pv] = dl.readVert(); - } - } else if (ptype == GX::TRIANGLEFAN) { - ++c; - for (int v = 0; v < vertCount - 2; ++v) { - os.format(FMT_STRING("last_face, last_mesh = add_triangle(bm, bm.verts, ({},{},{}), norm_list, " - "({},{},{}), {}, od_list, " - "two_face_vert)\n"), - firstPrimVert.pos, primVerts[c % 3].pos, primVerts[(c + 1) % 3].pos, firstPrimVert.norm, - primVerts[c % 3].norm, primVerts[(c + 1) % 3].norm, sHead.matIdx); - if (matUVCount) { - os << "if last_face is not None:\n"; - for (unsigned j = 0; j < matUVCount; ++j) { - if (j == 0 && matShortUVs) - os.format( - FMT_STRING( - " uv_tri = expand_lightmap_triangle(lightmap_tri_tracker, suv_list[{}], suv_list[{}], " - "suv_list[{}])\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[0]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[1]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_tri[2]\n"), - firstPrimVert.uvs[j], primVerts[c % 3].uvs[j], primVerts[(c + 1) % 3].uvs[j], firstPrimVert.pos, - j, primVerts[c % 3].pos, j, primVerts[(c + 1) % 3].pos, j); - else - os.format( - FMT_STRING( - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n" - " loop_from_facevert(last_mesh, last_face, {})[last_mesh.loops.layers.uv[{}]].uv = " - "uv_list[{}]\n"), - firstPrimVert.pos, j, firstPrimVert.uvs[j], primVerts[c % 3].pos, j, primVerts[c % 3].uvs[j], - primVerts[(c + 1) % 3].pos, j, primVerts[(c + 1) % 3].uvs[j]); - } - } - - /* Break if done */ - if (v + 3 >= vertCount) - break; - - /* Advance one prim vert */ - primVerts[(c + 2) % 3] = dl.readVert(); - ++c; - } - } - os << "\n"; - } - } - } - } - - if (s < secCount - 1) { - reader.seek(secStart + secSizes[s], athena::SeekOrigin::Begin); - } - } - - /* Finish Mesh */ - FinishBlenderMesh(os, matSetCount, meshIdx); - - if (rp.first.second) { - if (entry.id != 0xB333E1D7) { - // This is the beta phazon suit, we want the (incorrect) weight information, but we don't want to keep the CSKR id - os.format(FMT_STRING("mesh.cskr_id = '{}'\n"), rp.first.first); - } - rp.second.second->sendVertexGroupsToBlender(os); - } - - return lastDlSec; -} - -template atUint32 -ReadGeomSectionsToBlender, DNAMP1::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_1>( - hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - const std::pair, std::pair>& rp, bool shortNormals, - bool shortUVs, std::vector& vertAttribs, int meshIdx, atUint32 secCount, atUint32 matSetCount, - const atUint32* secSizes, atUint32 surfaceCount); - -template atUint32 -ReadGeomSectionsToBlender, DNAMP2::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_2>( - hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - const std::pair, std::pair>& rp, bool shortNormals, - bool shortUVs, std::vector& vertAttribs, int meshIdx, atUint32 secCount, atUint32 matSetCount, - const atUint32* secSizes, atUint32 surfaceCount); - -template atUint32 -ReadGeomSectionsToBlender, DNAMP3::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_3>( - hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - const std::pair, std::pair>& rp, bool shortNormals, - bool shortUVs, std::vector& vertAttribs, int meshIdx, atUint32 secCount, atUint32 matSetCount, - const atUint32* secSizes, atUint32 surfaceCount); - -template -bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, const RigPair& rp) { - Header head; - head.read(reader); - - if (head.magic != 0xDEADBABE) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid CMDL magic")); - return false; - } - - if (head.version != Version) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid CMDL version")); - return false; - } - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "\n" - "bpy.context.scene.name = '{}'\n" - "bpy.context.scene.hecl_mesh_obj = bpy.context.scene.name\n"), - pakRouter.getBestEntryName(entry)); - InitGeomBlenderContext(os, dataspec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - - os << "# Materials\n" - "materials = []\n" - "\n"; - - std::vector vertAttribs; - ReadGeomSectionsToBlender( - os, reader, pakRouter, entry, rp, head.flags.shortNormals(), head.flags.shortUVs(), vertAttribs, -1, - head.secCount, head.matSetCount, head.secSizes.data()); - - return true; -} - -template bool ReadCMDLToBlender, DNAMP1::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_1, 2>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template bool ReadCMDLToBlender, DNAMP2::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_2, 4>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template bool ReadCMDLToBlender, DNAMP3::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_3, 4>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template bool ReadCMDLToBlender, DNAMP3::MaterialSet, - std::pair, std::pair>, - DNACMDL::SurfaceHeader_3, 5>( - hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, const SpecBase& dataspec, - const std::pair, std::pair>& rp); - -template -void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry, - const SpecBase& dataspec) { - Header head; - head.read(reader); - std::string bestName = fmt::format(FMT_STRING("CMDL_{}"), entry.id); - - /* Pre-read pass to determine maximum used vert indices */ - atUint32 matSecCount = 0; - if (head.matSetCount) - matSecCount = MaterialSet::OneSection() ? 1 : head.matSetCount; - atUint32 lastDlSec = head.secCount; - for (atUint32 s = 0; s < lastDlSec; ++s) { - atUint64 secStart = reader.position(); - if (s < matSecCount) { - MaterialSet matSet; - matSet.read(reader); - matSet.nameTextures(pakRouter, bestName.c_str(), s); - } - - if (s < head.secCount - 1) { - reader.seek(secStart + head.secSizes[s], athena::SeekOrigin::Begin); - } - } -} - -template void NameCMDL, DNAMP1::MaterialSet>( - athena::io::IStreamReader& reader, PAKRouter& pakRouter, - PAKRouter::EntryType& entry, const SpecBase& dataspec); - -template -static void WriteDLVal(W& writer, GX::AttrType type, atUint32 val) { - switch (type) { - case GX::DIRECT: - case GX::INDEX8: - writer.writeUByte(atUint8(val)); - break; - case GX::INDEX16: - writer.writeUint16Big(atUint16(val)); - break; - default: - break; - } -} - -template -bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh) { - bool skinned = !mesh.skins.empty(); - - Header head; - head.magic = 0xDEADBABE; - head.version = Version; - head.flags.setSkinned(skinned); - head.flags.setShortNormals(!skinned); - head.flags.setShortUVs(true); /* This just means there's an (empty) short UV section */ - head.aabbMin = mesh.aabbMin.val; - head.aabbMax = mesh.aabbMax.val; - head.matSetCount = mesh.materialSets.size(); - head.secCount = head.matSetCount + 6 + mesh.surfaces.size(); - head.secSizes.reserve(head.secCount); - - /* Lengths of padding to insert while writing */ - std::vector paddingSizes; - paddingSizes.reserve(head.secCount); - - /* Build material sets */ - std::vector matSets; -#if 0 - matSets.reserve(mesh.materialSets.size()); - { - for (const std::vector& mset : mesh.materialSets) { - matSets.emplace_back(); - MaterialSet& targetMSet = matSets.back(); - std::vector texPaths; - std::vector setBackends; - setBackends.reserve(mset.size()); - - size_t endOff = 0; - for (const Material& mat : mset) { - std::string diagName = fmt::format(FMT_STRING("{}:{}"), inPath.getLastComponent(), mat.name); - hecl::Frontend::IR matIR = FE.compileSource(mat.source, diagName); - setBackends.emplace_back(); - hecl::Backend::GX& matGX = setBackends.back(); - matGX.reset(matIR, FE.getDiagnostics()); - - targetMSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths, mesh.colorLayerCount, false, false); - - targetMSet.materials.back().binarySize(endOff); - targetMSet.head.addMaterialEndOff(endOff); - } - - texPaths.reserve(mset.size() * 4); - for (const Material& mat : mset) { - for (const hecl::ProjectPath& path : mat.texs) { - bool found = false; - for (const hecl::ProjectPath& ePath : texPaths) { - if (path == ePath) { - found = true; - break; - } - } - if (!found) - texPaths.push_back(path); - } - } - - for (const hecl::ProjectPath& path : texPaths) - targetMSet.head.addTexture(path); - - size_t secSz = 0; - targetMSet.binarySize(secSz); - size_t secSz32 = ROUND_UP_32(secSz); - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - } - } -#endif - - /* Vertex Positions */ - size_t secSz = mesh.pos.size() * 12; - size_t secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Vertex Normals */ - secSz = mesh.norm.size() * (skinned ? 12 : 6); - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Vertex Colors */ - secSz = mesh.color.size() * 4; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* UV coords */ - secSz = mesh.uv.size() * 8; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* LUV coords */ - secSz = 0; - secSz32 = ROUND_UP_32(secSz); - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surface index */ - std::vector surfEndOffs; - surfEndOffs.reserve(mesh.surfaces.size()); - secSz = mesh.surfaces.size() * 4 + 4; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surfaces */ - size_t endOff = 0; - size_t firstSurfSec = head.secSizes.size(); - for (const Mesh::Surface& surf : mesh.surfaces) { - size_t vertSz = matSets.at(0).materials.at(surf.materialIdx).getVAFlags().vertDLSize(); - if (surf.verts.size() > 65536) - LogDNACommon.report(logvisor::Fatal, FMT_STRING("GX DisplayList overflow")); - size_t secSz = 64; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - secSz += 3 + vertCount * vertSz; - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - endOff += secSz32; - surfEndOffs.push_back(endOff); - } - - /* Write sections */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - head.write(writer); - std::vector::const_iterator padIt = paddingSizes.cbegin(); - - /* Material Sets */ - for (const MaterialSet& mset : matSets) { - mset.write(writer); - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - /* Vertex Positions */ - for (const atVec3f& pos : mesh.pos) - writer.writeVec3fBig(pos); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Vertex Normals */ - for (const atVec3f& norm : mesh.norm) { - if (skinned) { - writer.writeVec3fBig(norm); - } else { - for (int i = 0; i < 3; ++i) { - int tmpV = int(norm.simd[i] * 16384.f); - tmpV = zeus::clamp(-32768, tmpV, 32767); - writer.writeInt16Big(atInt16(tmpV)); - } - } - } - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Vertex Colors */ - for (const atVec3f& col : mesh.color) { - GX::Color qCol(col); - qCol.write(writer); - } - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* UV coords */ - for (const atVec2f& uv : mesh.uv) - writer.writeVec2fBig(uv); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* LUV coords */ - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surface index */ - writer.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - writer.writeUint32Big(off); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surfaces */ - GX::Primitive prim = GX::TRIANGLES; - if (mesh.topology == hecl::HMDLTopology::Triangles) - prim = GX::TRIANGLES; - else if (mesh.topology == hecl::HMDLTopology::TriStrips) - prim = GX::TRIANGLESTRIP; - else - LogDNACommon.report(logvisor::Fatal, FMT_STRING("unrecognized mesh output mode")); - auto surfSizeIt = head.secSizes.begin() + firstSurfSec; - for (const Mesh::Surface& surf : mesh.surfaces) { - const typename MaterialSet::Material::VAFlags& vaFlags = matSets.at(0).materials.at(surf.materialIdx).getVAFlags(); - - SurfaceHeader header; - header.centroid = surf.centroid; - header.matIdx = surf.materialIdx; - header.dlSize = (*surfSizeIt++ - 64) | 0x80000000; - header.reflectionNormal = surf.reflectionNormal; - header.write(writer); - - GX::Primitive usePrim = prim; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - usePrim = GX::TRIANGLES; - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - - /* VAT0 = float normals, float UVs - * VAT1 = short normals, float UVs */ - writer.writeUByte(usePrim | (skinned ? 0x0 : 0x1)); - writer.writeUint16Big(vertCount); - - for (auto it2 = it; it2 != itEnd; ++it2) { - const Mesh::Surface::Vert& vert = *it2; - if (vert.iPos == 0xffffffff) - continue; - atUint32 skinIdx = vert.iBankSkin * 3; - WriteDLVal(writer, vaFlags.pnMatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex0MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex1MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex2MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex3MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex4MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex5MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.tex6MatIdx(), skinIdx); - WriteDLVal(writer, vaFlags.position(), vert.iPos); - WriteDLVal(writer, vaFlags.normal(), vert.iNorm); - WriteDLVal(writer, vaFlags.color0(), vert.iColor[0]); - WriteDLVal(writer, vaFlags.color1(), vert.iColor[1]); - WriteDLVal(writer, vaFlags.tex0(), vert.iUv[0]); - WriteDLVal(writer, vaFlags.tex1(), vert.iUv[1]); - WriteDLVal(writer, vaFlags.tex2(), vert.iUv[2]); - WriteDLVal(writer, vaFlags.tex3(), vert.iUv[3]); - WriteDLVal(writer, vaFlags.tex4(), vert.iUv[4]); - WriteDLVal(writer, vaFlags.tex5(), vert.iUv[5]); - WriteDLVal(writer, vaFlags.tex6(), vert.iUv[6]); - } - - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - writer.close(); - return true; -} - -template bool WriteCMDL(const hecl::ProjectPath& outPath, - const hecl::ProjectPath& inPath, - const Mesh& mesh); - -template -bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh, - hecl::blender::PoolSkinIndex& poolSkinIndex) { - Header head; - head.magic = 0xDEADBABE; - head.version = 0x10000 | Version; - head.aabbMin = mesh.aabbMin.val; - head.aabbMax = mesh.aabbMax.val; - head.matSetCount = mesh.materialSets.size(); - head.secCount = head.matSetCount + 4 + mesh.surfaces.size(); - head.secSizes.reserve(head.secCount); - - /* Lengths of padding to insert while writing */ - std::vector paddingSizes; - paddingSizes.reserve(head.secCount); - - /* Build material sets */ - std::vector matSets; - matSets.reserve(mesh.materialSets.size()); - - for (const std::vector& mset : mesh.materialSets) { - matSets.emplace_back(); - MaterialSet& targetMSet = matSets.back(); - - size_t endOff = 0; - for (const Material& mat : mset) { - ++targetMSet.materialCount; - targetMSet.materials.emplace_back(mat); - targetMSet.materials.back().binarySize(endOff); - targetMSet.materialEndOffs.push_back(endOff); - } - - size_t secSz = 0; - targetMSet.binarySize(secSz); - size_t secSz32 = ROUND_UP_32(secSz); - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - } - - hecl::blender::HMDLBuffers bufs = mesh.getHMDLBuffers(false, poolSkinIndex); - - /* Metadata */ - size_t secSz = 0; - bufs.m_meta.binarySize(secSz); - size_t secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* VBO */ - secSz = bufs.m_vboSz; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* IBO */ - secSz = bufs.m_iboSz; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surface index */ - std::vector surfEndOffs; - surfEndOffs.reserve(bufs.m_surfaces.size()); - secSz = bufs.m_surfaces.size() * 4 + 4; - secSz32 = ROUND_UP_32(secSz); - if (secSz32 == 0) - secSz32 = 32; - head.secSizes.push_back(secSz32); - paddingSizes.push_back(secSz32 - secSz); - - /* Surfaces */ - size_t endOff = 0; - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - (void)surf; - head.secSizes.push_back(64); - paddingSizes.push_back(0); - endOff += 64; - surfEndOffs.push_back(endOff); - } - - /* Write sections */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - head.write(writer); - std::vector::const_iterator padIt = paddingSizes.cbegin(); - - /* Material Sets */ - for (const MaterialSet& mset : matSets) { - mset.write(writer); - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - /* Metadata */ - bufs.m_meta.write(writer); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* VBO */ - writer.writeUBytes(bufs.m_vboData.get(), bufs.m_vboSz); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* IBO */ - writer.writeUBytes(bufs.m_iboData.get(), bufs.m_iboSz); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surface index */ - writer.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - writer.writeUint32Big(off); - writer.fill(atUint8(0), *padIt); - ++padIt; - - /* Surfaces */ - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - const Mesh::Surface& osurf = surf.m_origSurf; - - SurfaceHeader header; - header.centroid = osurf.centroid; - header.matIdx = osurf.materialIdx; - header.reflectionNormal = osurf.reflectionNormal; - header.idxStart = surf.m_start; - header.idxCount = surf.m_count; - header.skinMtxBankIdx = osurf.skinBankIdx; - header.write(writer); - - writer.fill(atUint8(0), *padIt); - ++padIt; - } - - /* Ensure final surface's alignment writes zeros */ - writer.seek(-1, athena::SeekOrigin::Current); - writer.writeUByte(0); - writer.close(); - return true; -} - -template bool -WriteHMDLCMDL(const hecl::ProjectPath& outPath, - const hecl::ProjectPath& inPath, const Mesh& mesh, - hecl::blender::PoolSkinIndex& poolSkinIndex); - -struct MaterialPool { - std::vector materials; - size_t addMaterial(const Material& mat, bool& newMat) { - size_t ret = 0; - newMat = false; - for (const Material* testMat : materials) { - if (mat == *testMat) - return ret; - ++ret; - } - materials.push_back(&mat); - newMat = true; - return ret; - } -}; - -template -bool WriteMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs) { - /* Build material set */ - std::vector surfToGlobalMats; - MaterialSet matSet; - { - MaterialPool matPool; - - size_t surfCount = 0; - for (const Mesh& mesh : meshes) - surfCount += mesh.surfaces.size(); - surfToGlobalMats.reserve(surfCount); - - size_t endOff = 0; - std::vector texPaths; - for (const Mesh& mesh : meshes) { - if (mesh.materialSets.size()) { - std::vector meshToGlobalMats; - meshToGlobalMats.reserve(mesh.materialSets[0].size()); - - for (const Material& mat : mesh.materialSets[0]) { - bool newMat; - size_t idx = matPool.addMaterial(mat, newMat); - meshToGlobalMats.push_back(idx); - if (!newMat) - continue; - - for (const auto& chunk : mat.chunks) { - if (auto pass = chunk.get_if()) { - bool found = false; - for (const hecl::ProjectPath& ePath : texPaths) { - if (pass->tex == ePath) { - found = true; - break; - } - } - if (!found) - texPaths.push_back(pass->tex); - } - } - - auto lightmapped = mat.iprops.find("retro_lightmapped"); - bool lm = lightmapped != mat.iprops.cend() && lightmapped->second != 0; - - matSet.materials.emplace_back(mat, texPaths, mesh.colorLayerCount, lm, false); - - matSet.materials.back().binarySize(endOff); - matSet.head.addMaterialEndOff(endOff); - } - - for (const Mesh::Surface& surf : mesh.surfaces) - surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]); - } - } - for (const hecl::ProjectPath& path : texPaths) - matSet.head.addTexture(path); - - size_t secSz = 0; - matSet.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - matSet.write(w); - } - - /* Iterate meshes */ - auto matIt = surfToGlobalMats.cbegin(); - for (const Mesh& mesh : meshes) { - zeus::CTransform meshXf(mesh.sceneXf.val.data()); - meshXf.basis.transpose(); - - /* Header */ - { - MeshHeader meshHeader = {}; - meshHeader.visorFlags.setFromBlenderProps(mesh.customProps); - memmove(meshHeader.xfMtx, mesh.sceneXf.val.data(), 48); - - zeus::CAABox aabb(zeus::CVector3f(mesh.aabbMin), zeus::CVector3f(mesh.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - meshAABBs.push_back(aabb); - fullAABB.accumulateBounds(aabb); - meshHeader.aabb[0] = aabb.min; - meshHeader.aabb[1] = aabb.max; - - size_t secSz = 0; - meshHeader.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - meshHeader.write(w); - } - - std::vector surfEndOffs; - surfEndOffs.reserve(mesh.surfaces.size()); - size_t endOff = 0; - auto smatIt = matIt; - for (const Mesh::Surface& surf : mesh.surfaces) { - const typename MaterialSet::Material::VAFlags& vaFlags = matSet.materials.at(*smatIt++).getVAFlags(); - size_t vertSz = vaFlags.vertDLSize(); - - endOff += 96; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - endOff += 3 + vertSz * vertCount; - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - endOff = ROUND_UP_32(endOff); - surfEndOffs.push_back(endOff); - } - - /* Positions */ - { - size_t secSz = ROUND_UP_32(mesh.pos.size() * 12); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector3f& v : mesh.pos) { - zeus::CVector3f preXfPos = meshXf * zeus::CVector3f(v); - w.writeVec3fBig(preXfPos); - } - } - - /* Normals */ - { - size_t secSz = ROUND_UP_32(mesh.norm.size() * 6); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector3f& v : mesh.norm) { - zeus::CVector3f preXfNorm = (meshXf.basis * zeus::CVector3f(v)).normalized(); - for (int i = 0; i < 3; ++i) { - int tmpV = int(preXfNorm[i] * 16384.f); - tmpV = zeus::clamp(-32768, tmpV, 32767); - w.writeInt16Big(atInt16(tmpV)); - } - } - } - - /* Colors */ - { - size_t secSz = ROUND_UP_32(mesh.color.size() * 4); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector3f& v : mesh.color) { - zeus::CColor col((zeus::CVector4f(zeus::CVector3f(v)))); - col.writeRGBA8(w); - } - } - - /* UVs */ - { - size_t secSz = ROUND_UP_32(mesh.uv.size() * 8); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector2f& v : mesh.uv) - w.writeVec2fBig(v.val); - } - - /* LUVs */ - { - size_t secSz = ROUND_UP_32(mesh.luv.size() * 4); - if (secSz == 0) - secSz = 32; - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - for (const hecl::blender::Vector2f& v : mesh.luv) { - for (int i = 0; i < 2; ++i) { - int tmpV = int(v.val.simd[i] * 32768.f); - tmpV = zeus::clamp(-32768, tmpV, 32767); - w.writeInt16Big(atInt16(tmpV)); - } - } - } - - /* Surface index */ - { - secsOut.emplace_back((surfEndOffs.size() + 1) * 4, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - w.writeUint32Big(off); - } - - /* Surfaces */ - GX::Primitive prim = GX::TRIANGLES; - if (mesh.topology == hecl::HMDLTopology::Triangles) - prim = GX::TRIANGLES; - else if (mesh.topology == hecl::HMDLTopology::TriStrips) - prim = GX::TRIANGLESTRIP; - else - LogDNACommon.report(logvisor::Fatal, FMT_STRING("unrecognized mesh output mode")); - auto surfEndOffIt = surfEndOffs.begin(); - size_t lastEndOff = 0; - for (const Mesh::Surface& surf : mesh.surfaces) { - size_t matIdx = *matIt++; - const typename MaterialSet::Material& mat = matSet.materials.at(matIdx); - const typename MaterialSet::Material::VAFlags& vaFlags = mat.getVAFlags(); - - SurfaceHeader header; - header.centroid = meshXf * zeus::CVector3f(surf.centroid); - header.matIdx = matIdx; - uint32_t dlSize = uint32_t(*surfEndOffIt - lastEndOff - 96); - header.dlSize = dlSize | 0x80000000; - lastEndOff = *surfEndOffIt++; - header.reflectionNormal = (meshXf.basis * zeus::CVector3f(surf.reflectionNormal)).normalized(); - header.aabbSz = 24; - zeus::CAABox aabb(zeus::CVector3f(surf.aabbMin), zeus::CVector3f(surf.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - header.aabb[0] = aabb.min; - header.aabb[1] = aabb.max; - - size_t secSz = 0; - header.binarySize(secSz); - secSz += dlSize; - secSz = ROUND_UP_32(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - header.write(w); - - GX::Primitive usePrim = prim; - for (auto it = surf.verts.cbegin(); it != surf.verts.cend();) { - atUint16 vertCount = 0; - auto itEnd = surf.verts.cend(); - for (auto it2 = it; it2 != surf.verts.cend(); ++it2, ++vertCount) - if (it2->iPos == 0xffffffff) { - if (vertCount == 3) { - /* All primitives here on out are triangles */ - usePrim = GX::TRIANGLES; - vertCount = atUint16((surf.verts.cend() - it + 1) * 3 / 4); - break; - } - itEnd = it2; - break; - } - - /* VAT1 = short normals, float UVs - * VAT2 = short normals, short UVs */ - w.writeUByte(usePrim | (mat.flags.lightmapUVArray() ? 0x2 : 0x1)); - w.writeUint16Big(vertCount); - - for (auto it2 = it; it2 != itEnd; ++it2) { - const Mesh::Surface::Vert& vert = *it2; - if (vert.iPos == 0xffffffff) - continue; - atUint32 skinIdx = vert.iBankSkin * 3; - WriteDLVal(w, vaFlags.pnMatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex0MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex1MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex2MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex3MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex4MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex5MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.tex6MatIdx(), skinIdx); - WriteDLVal(w, vaFlags.position(), vert.iPos); - WriteDLVal(w, vaFlags.normal(), vert.iNorm); - WriteDLVal(w, vaFlags.color0(), vert.iColor[0]); - WriteDLVal(w, vaFlags.color1(), vert.iColor[1]); - WriteDLVal(w, vaFlags.tex0(), vert.iUv[0]); - WriteDLVal(w, vaFlags.tex1(), vert.iUv[1]); - WriteDLVal(w, vaFlags.tex2(), vert.iUv[2]); - WriteDLVal(w, vaFlags.tex3(), vert.iUv[3]); - WriteDLVal(w, vaFlags.tex4(), vert.iUv[4]); - WriteDLVal(w, vaFlags.tex5(), vert.iUv[5]); - WriteDLVal(w, vaFlags.tex6(), vert.iUv[6]); - } - - if (itEnd == surf.verts.cend()) - break; - it = itEnd + 1; - } - } - } - - return true; -} - -template bool WriteMREASecs( - std::vector>& secsOut, const hecl::ProjectPath& inPath, const std::vector& meshes, - zeus::CAABox& fullAABB, std::vector& meshAABBs); - -template -bool WriteHMDLMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs) { - /* Build material set */ - std::vector surfToGlobalMats; - { - MaterialPool matPool; - - size_t surfCount = 0; - for (const Mesh& mesh : meshes) - surfCount += mesh.surfaces.size(); - surfToGlobalMats.reserve(surfCount); - - MaterialSet matSet = {}; - size_t endOff = 0; - for (const Mesh& mesh : meshes) { - if (mesh.materialSets.size()) { - std::vector meshToGlobalMats; - meshToGlobalMats.reserve(mesh.materialSets[0].size()); - - for (const Material& mat : mesh.materialSets[0]) { - bool newMat; - size_t idx = matPool.addMaterial(mat, newMat); - meshToGlobalMats.push_back(idx); - if (!newMat) - continue; - - ++matSet.materialCount; - matSet.materials.emplace_back(mat); - matSet.materials.back().binarySize(endOff); - matSet.materialEndOffs.push_back(endOff); - } - - for (const Mesh::Surface& surf : mesh.surfaces) - surfToGlobalMats.push_back(meshToGlobalMats[surf.materialIdx]); - } - } - - size_t secSz = 0; - matSet.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - matSet.write(w); - } - - /* Iterate meshes */ - auto matIt = surfToGlobalMats.cbegin(); - for (const Mesh& mesh : meshes) { - zeus::CTransform meshXf(mesh.sceneXf.val.data()); - meshXf.basis.transpose(); - - /* Header */ - { - MeshHeader meshHeader = {}; - meshHeader.visorFlags.setFromBlenderProps(mesh.customProps); - memmove(meshHeader.xfMtx, mesh.sceneXf.val.data(), 48); - - zeus::CAABox aabb(zeus::CVector3f(mesh.aabbMin), zeus::CVector3f(mesh.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - meshAABBs.push_back(aabb); - fullAABB.accumulateBounds(aabb); - meshHeader.aabb[0] = aabb.min; - meshHeader.aabb[1] = aabb.max; - - size_t secSz = 0; - meshHeader.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - meshHeader.write(w); - } - - hecl::blender::PoolSkinIndex poolSkinIndex; - hecl::blender::HMDLBuffers bufs = mesh.getHMDLBuffers(true, poolSkinIndex); - - std::vector surfEndOffs; - surfEndOffs.reserve(bufs.m_surfaces.size()); - size_t endOff = 0; - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - (void)surf; - endOff += 96; - surfEndOffs.push_back(endOff); - } - - /* Metadata */ - { - size_t secSz = 0; - bufs.m_meta.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - bufs.m_meta.write(w); - } - - /* VBO */ - { - secsOut.emplace_back(bufs.m_vboSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUBytes(bufs.m_vboData.get(), bufs.m_vboSz); - } - - /* IBO */ - { - secsOut.emplace_back(bufs.m_iboSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUBytes(bufs.m_iboData.get(), bufs.m_iboSz); - } - - /* Surface index */ - { - secsOut.emplace_back((surfEndOffs.size() + 1) * 4, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - w.writeUint32Big(surfEndOffs.size()); - for (size_t off : surfEndOffs) - w.writeUint32Big(off); - } - - /* Surfaces */ - for (const hecl::blender::HMDLBuffers::Surface& surf : bufs.m_surfaces) { - const Mesh::Surface& osurf = surf.m_origSurf; - - SurfaceHeader header; - header.centroid = meshXf * zeus::CVector3f(osurf.centroid); - header.matIdx = *matIt++; - header.reflectionNormal = (meshXf.basis * zeus::CVector3f(osurf.reflectionNormal)).normalized(); - header.idxStart = surf.m_start; - header.idxCount = surf.m_count; - header.skinMtxBankIdx = osurf.skinBankIdx; - - header.aabbSz = 24; - zeus::CAABox aabb(zeus::CVector3f(surf.m_origSurf.aabbMin), zeus::CVector3f(surf.m_origSurf.aabbMax)); - aabb = aabb.getTransformedAABox(meshXf); - header.aabb[0] = aabb.min; - header.aabb[1] = aabb.max; - - size_t secSz = 0; - header.binarySize(secSz); - secsOut.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size()); - header.write(w); - } - } - - return true; -} - -template bool WriteHMDLMREASecs( - std::vector>& secsOut, const hecl::ProjectPath& inPath, const std::vector& meshes, - zeus::CAABox& fullAABB, std::vector& meshAABBs); - -template <> -void SurfaceHeader_1::Enumerate(typename Read::StreamT& reader) { - /* centroid */ - centroid = reader.readVec3fBig(); - /* matIdx */ - matIdx = reader.readUint32Big(); - /* dlSize */ - dlSize = reader.readUint32Big(); - /* idxStart */ - idxStart = reader.readUint32Big(); - /* idxCount */ - idxCount = reader.readUint32Big(); - /* aabbSz */ - aabbSz = reader.readUint32Big(); - /* reflectionNormal */ - reflectionNormal = reader.readVec3fBig(); - /* aabb */ - size_t remAABB = aabbSz; - if (remAABB >= 24) { - aabb[0] = reader.readVec3fBig(); - aabb[1] = reader.readVec3fBig(); - remAABB -= 24; - } - reader.seek(remAABB, athena::SeekOrigin::Current); - /* align */ - reader.seekAlign32(); -} - -template <> -void SurfaceHeader_1::Enumerate(typename Write::StreamT& writer) { - /* centroid */ - writer.writeVec3fBig(centroid); - /* matIdx */ - writer.writeUint32Big(matIdx); - /* dlSize */ - writer.writeUint32Big(dlSize); - /* idxStart */ - writer.writeUint32Big(idxStart); - /* idxCount */ - writer.writeUint32Big(idxCount); - /* aabbSz */ - writer.writeUint32Big(aabbSz ? 24 : 0); - /* reflectionNormal */ - writer.writeVec3fBig(reflectionNormal); - /* aabb */ - if (aabbSz) { - writer.writeVec3fBig(aabb[0]); - writer.writeVec3fBig(aabb[1]); - } - /* align */ - writer.seekAlign32(); -} - -template <> -void SurfaceHeader_1::Enumerate(typename BinarySize::StreamT& s) { - s += (aabbSz ? 24 : 0); - s += 44; - s = (s + 31) & ~31; -} - -template <> -void SurfaceHeader_2::Enumerate(typename Read::StreamT& reader) { - /* centroid */ - centroid = reader.readVec3fBig(); - /* matIdx */ - matIdx = reader.readUint32Big(); - /* dlSize */ - dlSize = reader.readUint32Big(); - /* idxStart */ - idxStart = reader.readUint32Big(); - /* idxCount */ - idxCount = reader.readUint32Big(); - /* aabbSz */ - aabbSz = reader.readUint32Big(); - /* reflectionNormal */ - reflectionNormal = reader.readVec3fBig(); - /* skinMtxBankIdx */ - skinMtxBankIdx = reader.readInt16Big(); - /* surfaceGroup */ - surfaceGroup = reader.readUint16Big(); - /* aabb */ - size_t remAABB = aabbSz; - if (remAABB >= 24) { - aabb[0] = reader.readVec3fBig(); - aabb[1] = reader.readVec3fBig(); - remAABB -= 24; - } - reader.seek(remAABB, athena::SeekOrigin::Current); - /* align */ - reader.seekAlign32(); -} - -template <> -void SurfaceHeader_2::Enumerate(typename Write::StreamT& writer) { - /* centroid */ - writer.writeVec3fBig(centroid); - /* matIdx */ - writer.writeUint32Big(matIdx); - /* dlSize */ - writer.writeUint32Big(dlSize); - /* idxStart */ - writer.writeUint32Big(idxStart); - /* idxCount */ - writer.writeUint32Big(idxCount); - /* aabbSz */ - writer.writeUint32Big(aabbSz ? 24 : 0); - /* reflectionNormal */ - writer.writeVec3fBig(reflectionNormal); - /* skinMtxBankIdx */ - writer.writeInt16Big(skinMtxBankIdx); - /* surfaceGroup */ - writer.writeUint16Big(surfaceGroup); - /* aabb */ - if (aabbSz) { - writer.writeVec3fBig(aabb[0]); - writer.writeVec3fBig(aabb[1]); - } - /* align */ - writer.seekAlign32(); -} - -template <> -void SurfaceHeader_2::Enumerate(typename BinarySize::StreamT& s) { - s += (aabbSz ? 24 : 0); - s += 48; - s = (s + 31) & ~31; -} - -template <> -void SurfaceHeader_3::Enumerate(typename Read::StreamT& reader) { - /* centroid */ - centroid = reader.readVec3fBig(); - /* matIdx */ - matIdx = reader.readUint32Big(); - /* dlSize */ - dlSize = reader.readUint32Big(); - /* idxStart */ - idxStart = reader.readUint32Big(); - /* idxCount */ - idxCount = reader.readUint32Big(); - /* aabbSz */ - aabbSz = reader.readUint32Big(); - /* reflectionNormal */ - reflectionNormal = reader.readVec3fBig(); - /* skinMtxBankIdx */ - skinMtxBankIdx = reader.readInt16Big(); - /* surfaceGroup */ - surfaceGroup = reader.readUint16Big(); - /* aabb */ - size_t remAABB = aabbSz; - if (remAABB >= 24) { - aabb[0] = reader.readVec3fBig(); - aabb[1] = reader.readVec3fBig(); - remAABB -= 24; - } - reader.seek(remAABB, athena::SeekOrigin::Current); - /* unk3 */ - unk3 = reader.readUByte(); - /* align */ - reader.seekAlign32(); -} - -template <> -void SurfaceHeader_3::Enumerate(typename Write::StreamT& writer) { - /* centroid */ - writer.writeVec3fBig(centroid); - /* matIdx */ - writer.writeUint32Big(matIdx); - /* dlSize */ - writer.writeUint32Big(dlSize); - /* idxStart */ - writer.writeUint32Big(idxStart); - /* idxCount */ - writer.writeUint32Big(idxCount); - /* aabbSz */ - writer.writeUint32Big(aabbSz ? 24 : 0); - /* reflectionNormal */ - writer.writeVec3fBig(reflectionNormal); - /* skinMtxBankIdx */ - writer.writeInt16Big(skinMtxBankIdx); - /* surfaceGroup */ - writer.writeUint16Big(surfaceGroup); - /* aabb */ - if (aabbSz) { - writer.writeVec3fBig(aabb[0]); - writer.writeVec3fBig(aabb[1]); - } - /* unk3 */ - writer.writeUByte(unk3); - /* align */ - writer.seekAlign32(); -} - -template <> -void SurfaceHeader_3::Enumerate(typename BinarySize::StreamT& s) { - s += (aabbSz ? 24 : 0); - s += 49; - s = (s + 31) & ~31; -} - -} // namespace DataSpec::DNACMDL diff --git a/DataSpec/DNACommon/CMDL.hpp b/DataSpec/DNACommon/CMDL.hpp deleted file mode 100644 index 3b305e8be..000000000 --- a/DataSpec/DNACommon/CMDL.hpp +++ /dev/null @@ -1,168 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DataSpec/DNACommon/GX.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" - -#include -#include -#include - -namespace hecl { -class ProjectPath; -} - -namespace zeus { -class CAABox; -} - -namespace DataSpec::DNACMDL { - -using Mesh = hecl::blender::Mesh; -using Material = hecl::blender::Material; - -struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - struct Flags : BigDNA { - AT_DECL_DNA - Value flags = 0; - bool skinned() const { return (flags & 0x1) != 0; } - void setSkinned(bool val) { - flags &= ~0x1; - flags |= val; - } - bool shortNormals() const { return (flags & 0x2) != 0; } - void setShortNormals(bool val) { - flags &= ~0x2; - flags |= val << 1; - } - bool shortUVs() const { return (flags & 0x4) != 0; } - void setShortUVs(bool val) { - flags &= ~0x4; - flags |= val << 2; - } - } flags; - Value aabbMin; - Value aabbMax; - Value secCount; - Value matSetCount; - Vector secSizes; - Align<32> align; -}; - -struct SurfaceHeader_1 : BigDNA { - AT_DECL_EXPLICIT_DNA - Value centroid; - Value matIdx = 0; - Value dlSize = 0; - Value idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ - Value idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ - Value aabbSz = 0; - Value reflectionNormal; - Value aabb[2]; - Align<32> align; - - static constexpr bool UseMatrixSkinning() { return false; } - static constexpr atInt16 skinMatrixBankIdx() { return -1; } -}; - -struct SurfaceHeader_2 : BigDNA { - AT_DECL_EXPLICIT_DNA - Value centroid; - Value matIdx = 0; - Value dlSize = 0; - Value idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ - Value idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ - Value aabbSz = 0; - Value reflectionNormal; - Value skinMtxBankIdx; - Value surfaceGroup; - Value aabb[2]; - Align<32> align; - - static constexpr bool UseMatrixSkinning() { return false; } - atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; } -}; - -struct SurfaceHeader_3 : BigDNA { - AT_DECL_EXPLICIT_DNA - Value centroid; - Value matIdx = 0; - Value dlSize = 0; - Value idxStart = 0; /* Actually used by game to stash CCubeModel pointer */ - Value idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ - Value aabbSz = 0; - Value reflectionNormal; - Value skinMtxBankIdx; - Value surfaceGroup; - Value aabb[2]; - Value unk3; - Align<32> align; - - static constexpr bool UseMatrixSkinning() { return true; } - atInt16 skinMatrixBankIdx() const { return skinMtxBankIdx; } -}; - -struct VertexAttributes { - GX::AttrType pos = GX::NONE; - GX::AttrType norm = GX::NONE; - GX::AttrType color0 = GX::NONE; - GX::AttrType color1 = GX::NONE; - unsigned uvCount = 0; - GX::AttrType uvs[7] = {GX::NONE}; - GX::AttrType pnMtxIdx = GX::NONE; - unsigned texMtxIdxCount = 0; - GX::AttrType texMtxIdx[7] = {GX::NONE}; - bool shortUVs; -}; - -template -void GetVertexAttributes(const MaterialSet& matSet, std::vector& attributesOut); - -template -void ReadMaterialSetToBlender_1_2(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx); - -template -void ReadMaterialSetToBlender_3(hecl::blender::PyOutStream& os, const MaterialSet& matSet, const PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, unsigned setIdx); - -void InitGeomBlenderContext(hecl::blender::PyOutStream& os, const hecl::ProjectPath& masterShaderPath); -void FinishBlenderMesh(hecl::blender::PyOutStream& os, unsigned matSetCount, int meshIdx); - -template -atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os, athena::io::IStreamReader& reader, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, const RigPair& rp, - bool shortNormals, bool shortUVs, std::vector& vertAttribs, - int meshIdx, atUint32 secCount, atUint32 matSetCount, const atUint32* secSizes, - atUint32 surfaceCount = 0); - -template -bool ReadCMDLToBlender(hecl::blender::Connection& conn, athena::io::IStreamReader& reader, PAKRouter& pakRouter, - const typename PAKRouter::EntryType& entry, const SpecBase& dataspec, const RigPair& rp); - -template -void NameCMDL(athena::io::IStreamReader& reader, PAKRouter& pakRouter, typename PAKRouter::EntryType& entry, - const SpecBase& dataspec); - -template -bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh); - -template -bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh, - hecl::blender::PoolSkinIndex& poolSkinIndex); - -template -bool WriteMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs); - -template -bool WriteHMDLMREASecs(std::vector>& secsOut, const hecl::ProjectPath& inPath, - const std::vector& meshes, zeus::CAABox& fullAABB, std::vector& meshAABBs); - -} // namespace DataSpec::DNACMDL diff --git a/DataSpec/DNACommon/CMakeLists.txt b/DataSpec/DNACommon/CMakeLists.txt deleted file mode 100644 index d2211d761..000000000 --- a/DataSpec/DNACommon/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -make_dnalist(CMDL - FONT - DGRP - FSM2 - MAPA - MAPU - PATH - MayaSpline - EGMC - SAVWCommon - ParticleCommon - MetaforceVersionInfo - Tweaks/ITweakPlayerGun) - -set(DNACOMMON_SOURCES - DNACommon.hpp DNACommon.cpp - PAK.hpp PAK.cpp - GX.hpp GX.cpp - FSM2.hpp FSM2.cpp - MLVL.hpp MLVL.cpp - CMDL.cpp - MAPA.cpp - MAPU.cpp - PATH.hpp PATH.cpp - STRG.hpp STRG.cpp - TXTR.hpp TXTR.cpp - ANCS.hpp ANCS.cpp - ANIM.hpp ANIM.cpp - PART.hpp PART.cpp - SWHC.hpp SWHC.cpp - CRSC.hpp CRSC.cpp - ELSC.hpp ELSC.cpp - WPSC.hpp WPSC.cpp - DPSC.hpp DPSC.cpp - ParticleCommon.cpp - FONT.cpp - DGRP.cpp - ATBL.hpp ATBL.cpp - DeafBabe.hpp DeafBabe.cpp - BabeDead.hpp BabeDead.cpp - RigInverter.hpp RigInverter.cpp - AROTBuilder.hpp AROTBuilder.cpp - OBBTreeBuilder.hpp OBBTreeBuilder.cpp - MetaforceVersionInfo.hpp - Tweaks/ITweak.hpp - Tweaks/TweakWriter.hpp - Tweaks/ITweakGame.hpp - Tweaks/ITweakParticle.hpp - Tweaks/ITweakPlayer.hpp - Tweaks/ITweakPlayerControl.hpp - Tweaks/ITweakGunRes.hpp - Tweaks/ITweakPlayerRes.hpp - Tweaks/ITweakGui.hpp - Tweaks/ITweakSlideShow.hpp - Tweaks/ITweakTargeting.hpp - Tweaks/ITweakAutoMapper.hpp - Tweaks/ITweakBall.hpp - Tweaks/ITweakGuiColors.hpp) - -dataspec_add_list(DNACommon DNACOMMON_SOURCES) diff --git a/DataSpec/DNACommon/CRSC.cpp b/DataSpec/DNACommon/CRSC.cpp deleted file mode 100644 index a66b912f0..000000000 --- a/DataSpec/DNACommon/CRSC.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include "DataSpec/DNACommon/CRSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_CRSM>; -template struct PPImpl<_CRSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_CRSM>) - -template <> -std::string_view PPImpl<_CRSM>::DNAType() { - return "CRSM"sv; -} - -template <> -std::string_view PPImpl<_CRSM>::DNAType() { - return "CRSM"sv; -} - -template -bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - CRSM crsm; - crsm.read(rs); - athena::io::ToYAMLStream(crsm, writer); - return true; - } - return false; -} -template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - crsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath); -template bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath); -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/CRSC.def b/DataSpec/DNACommon/CRSC.def deleted file mode 100644 index 6fe2e2b7e..000000000 --- a/DataSpec/DNACommon/CRSC.def +++ /dev/null @@ -1,222 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef U32_ENTRY -#define U32_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef FLOAT_ENTRY -#define FLOAT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -RES_ENTRY('NODP', NODP) -RES_ENTRY('DEFS', DEFS) -RES_ENTRY('CRTS', CRTS) -RES_ENTRY('MTLS', MTLS) -RES_ENTRY('GRAS', GRAS) -RES_ENTRY('ICEE', ICEE) -RES_ENTRY('GOOO', GOOO) -RES_ENTRY('WODS', WODS) -RES_ENTRY('WATR', WATR) -RES_ENTRY('1MUD', _1MUD) -RES_ENTRY('1LAV', _1LAV) -RES_ENTRY('1SAN', _1SAN) -RES_ENTRY('1PRJ', _1PRJ) -RES_ENTRY('DCHR', DCHR) -RES_ENTRY('DCHS', DCHS) -RES_ENTRY('DCSH', DCSH) -RES_ENTRY('DENM', DENM) -RES_ENTRY('DESP', DESP) -RES_ENTRY('DESH', DESH) -RES_ENTRY('BTLE', BTLE) -RES_ENTRY('WASP', WASP) -RES_ENTRY('TALP', TALP) -RES_ENTRY('PTGM', PTGM) -RES_ENTRY('SPIR', SPIR) -RES_ENTRY('FPIR', FPIR) -RES_ENTRY('FFLE', FFLE) -RES_ENTRY('PARA', PARA) -RES_ENTRY('BMON', BMON) -RES_ENTRY('BFLR', BFLR) -RES_ENTRY('PBOS', PBOS) -RES_ENTRY('IBOS', IBOS) -RES_ENTRY('1SVA', _1SVA) -RES_ENTRY('1RPR', _1RPR) -RES_ENTRY('1MTR', _1MTR) -RES_ENTRY('1PDS', _1PDS) -RES_ENTRY('1FLB', _1FLB) -RES_ENTRY('1DRN', _1DRN) -RES_ENTRY('1MRE', _1MRE) -RES_ENTRY('CHOZ', CHOZ) -RES_ENTRY('JZAP', JZAP) -RES_ENTRY('1ISE', _1ISE) -RES_ENTRY('1BSE', _1BSE) -RES_ENTRY('1ATB', _1ATB) -RES_ENTRY('1ATA', _1ATA) -RES_ENTRY('BTSP', BTSP) -RES_ENTRY('WWSP', WWSP) -RES_ENTRY('TASP', TASP) -RES_ENTRY('TGSP', TGSP) -RES_ENTRY('SPSP', SPSP) -RES_ENTRY('FPSP', FPSP) -RES_ENTRY('FFSP', FFSP) -RES_ENTRY('PSSP', PSSP) -RES_ENTRY('BMSP', BMSP) -RES_ENTRY('BFSP', BFSP) -RES_ENTRY('PBSP', PBSP) -RES_ENTRY('IBSP', IBSP) -RES_ENTRY('2SVA', _2SVA) -RES_ENTRY('2RPR', _2RPR) -RES_ENTRY('2MTR', _2MTR) -RES_ENTRY('2PDS', _2PDS) -RES_ENTRY('2FLB', _2FLB) -RES_ENTRY('2DRN', _2DRN) -RES_ENTRY('2MRE', _2MRE) -RES_ENTRY('CHSP', CHSP) -RES_ENTRY('JZSP', JZSP) -RES_ENTRY('3ISE', _3ISE) -RES_ENTRY('3BSE', _3BSE) -RES_ENTRY('3ATB', _3ATB) -RES_ENTRY('3ATA', _3ATA) -RES_ENTRY('BTSH', BTSH) -RES_ENTRY('WWSH', WWSH) -RES_ENTRY('TASH', TASH) -RES_ENTRY('TGSH', TGSH) -RES_ENTRY('SPSH', SPSH) -RES_ENTRY('FPSH', FPSH) -RES_ENTRY('FFSH', FFSH) -RES_ENTRY('PSSH', PSSH) -RES_ENTRY('BMSH', BMSH) -RES_ENTRY('BFSH', BFSH) -RES_ENTRY('PBSH', PBSH) -RES_ENTRY('IBSH', IBSH) -RES_ENTRY('3SVA', _3SVA) -RES_ENTRY('3RPR', _3RPR) -RES_ENTRY('3MTR', _3MTR) -RES_ENTRY('3PDS', _3PDS) -RES_ENTRY('3FLB', _3FLB) -RES_ENTRY('3DRN', _3DRN) -RES_ENTRY('3MRE', _3MRE) -RES_ENTRY('CHSH', CHSH) -RES_ENTRY('JZSH', JZSH) -RES_ENTRY('5ISE', _5ISE) -RES_ENTRY('5BSE', _5BSE) -RES_ENTRY('5ATB', _5ATB) -RES_ENTRY('5ATA', _5ATA) -RES_ENTRY('NCDL', NCDL) -RES_ENTRY('DDCL', DDCL) -RES_ENTRY('CODL', CODL) -RES_ENTRY('MEDL', MEDL) -RES_ENTRY('GRDL', GRDL) -RES_ENTRY('ICDL', ICDL) -RES_ENTRY('GODL', GODL) -RES_ENTRY('WODL', WODL) -RES_ENTRY('WTDL', WTDL) -RES_ENTRY('3MUD', _3MUD) -RES_ENTRY('3LAV', _3LAV) -RES_ENTRY('3SAN', _3SAN) -RES_ENTRY('CHDL', CHDL) -RES_ENTRY('ENDL', ENDL) - -U32_ENTRY('NSFX', NSFX) -U32_ENTRY('DSFX', DSFX) -U32_ENTRY('CSFX', CSFX) -U32_ENTRY('MSFX', MSFX) -U32_ENTRY('GRFX', GRFX) -U32_ENTRY('ICFX', ICFX) -U32_ENTRY('GOFX', GOFX) -U32_ENTRY('WSFX', WSFX) -U32_ENTRY('WTFX', WTFX) -U32_ENTRY('2MUD', _2MUD) -U32_ENTRY('2LAV', _2LAV) -U32_ENTRY('2SAN', _2SAN) -U32_ENTRY('2PRJ', _2PRJ) -U32_ENTRY('DCFX', DCFX) -U32_ENTRY('DSHX', DSHX) -U32_ENTRY('DEFX', DEFX) -U32_ENTRY('ESFX', ESFX) -U32_ENTRY('SHFX', SHFX) -U32_ENTRY('BEFX', BEFX) -U32_ENTRY('WWFX', WWFX) -U32_ENTRY('TAFX', TAFX) -U32_ENTRY('GTFX', GTFX) -U32_ENTRY('SPFX', SPFX) -U32_ENTRY('FPFX', FPFX) -U32_ENTRY('FFFX', FFFX) -U32_ENTRY('PAFX', PAFX) -U32_ENTRY('BMFX', BMFX) -U32_ENTRY('BFFX', BFFX) -U32_ENTRY('PBFX', PBFX) -U32_ENTRY('IBFX', IBFX) -U32_ENTRY('4SVA', _4SVA) -U32_ENTRY('4RPR', _4RPR) -U32_ENTRY('4MTR', _4MTR) -U32_ENTRY('4PDS', _4PDS) -U32_ENTRY('4FLB', _4FLB) -U32_ENTRY('4DRN', _4DRN) -U32_ENTRY('4MRE', _4MRE) -U32_ENTRY('CZFX', CZFX) -U32_ENTRY('JZAS', JZAS) -U32_ENTRY('2ISE', _2ISE) -U32_ENTRY('2BSE', _2BSE) -U32_ENTRY('2ATB', _2ATB) -U32_ENTRY('2ATA', _2ATA) -U32_ENTRY('BSFX', BSFX) -U32_ENTRY('TSFX', TSFX) -U32_ENTRY('GSFX', GSFX) -U32_ENTRY('SSFX', SSFX) -U32_ENTRY('FSFX', FSFX) -U32_ENTRY('SFFX', SFFX) -U32_ENTRY('PSFX', PSFX) -U32_ENTRY('SBFX', SBFX) -U32_ENTRY('PBSX', PBSX) -U32_ENTRY('IBSX', IBSX) -U32_ENTRY('5SVA', _5SVA) -U32_ENTRY('5RPR', _5RPR) -U32_ENTRY('5MTR', _5MTR) -U32_ENTRY('5PDS', _5PDS) -U32_ENTRY('5FLB', _5FLB) -U32_ENTRY('5DRN', _5DRN) -U32_ENTRY('5MRE', _5MRE) -U32_ENTRY('JZPS', JZPS) -U32_ENTRY('4ISE', _4ISE) -U32_ENTRY('4BSE', _4BSE) -U32_ENTRY('4ATB', _4ATB) -U32_ENTRY('4ATA', _4ATA) -U32_ENTRY('BHFX', BHFX) -U32_ENTRY('WHFX', WHFX) -U32_ENTRY('THFX', THFX) -U32_ENTRY('GHFX', GHFX) -U32_ENTRY('FHFX', FHFX) -U32_ENTRY('HFFX', HFFX) -U32_ENTRY('PHFX', PHFX) -U32_ENTRY('MHFX', MHFX) -U32_ENTRY('HBFX', HBFX) -U32_ENTRY('PBHX', PBHX) -U32_ENTRY('IBHX', IBHX) -U32_ENTRY('6SVA', _6SVA) -U32_ENTRY('6RPR', _6RPR) -U32_ENTRY('6MTR', _6MTR) -U32_ENTRY('6PDS', _6PDS) -U32_ENTRY('6FLB', _6FLB) -U32_ENTRY('6DRN', _6DRN) -U32_ENTRY('6MRE', _6MRE) -U32_ENTRY('CHFX', CHFX) -U32_ENTRY('JZHS', JZHS) -U32_ENTRY('6ISE', _6ISE) -U32_ENTRY('6BSE', _6BSE) -U32_ENTRY('6ATB', _6ATB) -U32_ENTRY('6ATA', _6ATA) - -FLOAT_ENTRY('RNGE', x30_RNGE) -FLOAT_ENTRY('FOFF', x34_FOFF) - -#undef ENTRY -#undef RES_ENTRY -#undef U32_ENTRY -#undef FLOAT_ENTRY diff --git a/DataSpec/DNACommon/CRSC.hpp b/DataSpec/DNACommon/CRSC.hpp deleted file mode 100644 index 94ba917ed..000000000 --- a/DataSpec/DNACommon/CRSC.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _CRSM { - static constexpr ParticleType Type = ParticleType::CRSM; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; -#define FLOAT_ENTRY(name, identifier) float identifier = 0.f; -#include "CRSC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#include "CRSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "CRSC.def" - default: - return false; - } - } -}; -template -using CRSM = PPImpl<_CRSM>; - -template -bool ExtractCRSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteCRSM(const CRSM& crsm, const hecl::ProjectPath& outPath); -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/DGRP.cpp b/DataSpec/DNACommon/DGRP.cpp deleted file mode 100644 index d39427e1b..000000000 --- a/DataSpec/DNACommon/DGRP.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "DataSpec/DNACommon/DGRP.hpp" - -#include -#include -#include - -#include - -namespace DataSpec::DNADGRP { - -template -bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - DGRP dgrp; - dgrp.read(rs); - athena::io::ToYAMLStream(dgrp, writer); - return true; - } - return false; -} -template bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - dgrp.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath); -template bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNADGRP diff --git a/DataSpec/DNACommon/DGRP.hpp b/DataSpec/DNACommon/DGRP.hpp deleted file mode 100644 index 37850ee6f..000000000 --- a/DataSpec/DNACommon/DGRP.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNADGRP { - -template -struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) DGRP : BigDNA { - AT_DECL_DNA_YAML - Value dependCount; - struct ObjectTag : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC type; - Value id; - - bool validate() const { - if (!id.isValid()) - return false; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - return path && !path.isNone(); - } - }; - - Vector depends; - - void validateDeps() { - std::vector newDeps; - newDeps.reserve(depends.size()); - for (const ObjectTag& tag : depends) - if (tag.validate()) - newDeps.push_back(tag); - depends = std::move(newDeps); - dependCount = atUint32(depends.size()); - } -}; - -template -bool ExtractDGRP(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template -bool WriteDGRP(const DGRP& dgrp, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNADGRP diff --git a/DataSpec/DNACommon/DNACommon.cpp b/DataSpec/DNACommon/DNACommon.cpp deleted file mode 100644 index 1ef8ba3f0..000000000 --- a/DataSpec/DNACommon/DNACommon.cpp +++ /dev/null @@ -1,199 +0,0 @@ -#include "DNACommon.hpp" -#include "PAK.hpp" -#include "boo/ThreadLocalPtr.hpp" - -namespace DataSpec { - -logvisor::Module LogDNACommon("DataSpec::DNACommon"); -ThreadLocalPtr g_curSpec; -ThreadLocalPtr g_PakRouter; -ThreadLocalPtr g_ThreadBlenderToken; -ThreadLocalPtr UniqueIDBridge::s_Project; -UniqueID32 UniqueID32::kInvalidId; - -template -hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const IDType& id, bool silenceWarnings) { - /* Try PAKRouter first (only available at extract) */ - PAKRouterBase* pakRouter = g_PakRouter.get(); - if (pakRouter) { - hecl::ProjectPath path = pakRouter->getWorking(id, silenceWarnings); - if (path) - return path; - } - - /* Try project cache second (populated with paths read from YAML resources) */ - hecl::Database::Project* project = s_Project.get(); - if (!project) { - if (pakRouter) { - if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id.isValid()) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to translate {} to path"), id); - return {}; - } - LogDNACommon.report(logvisor::Fatal, FMT_STRING("g_PakRouter or s_Project must be set to non-null before " - "calling UniqueIDBridge::TranslatePakIdToPath")); - return {}; - } - - const hecl::ProjectPath* search = project->lookupBridgePath(id.toUint64()); - if (!search) { - if (hecl::VerbosityLevel >= 1 && !silenceWarnings && id.isValid()) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to translate {} to path"), id); - return {}; - } - return *search; -} -template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID32& id, bool silenceWarnings); -template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID64& id, bool silenceWarnings); -template hecl::ProjectPath UniqueIDBridge::TranslatePakIdToPath(const UniqueID128& id, bool silenceWarnings); - -template -hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str) { - if (str.empty()) - return {}; - hecl::Database::Project* project = s_Project.get(); - if (!project) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("UniqueIDBridge::setGlobalProject must be called before MakePathFromString")); - hecl::ProjectPath path = hecl::ProjectPath(*project, str); - project->addBridgePathToCache(IDType(path).toUint64(), path); - return path; -} -template hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str); -template hecl::ProjectPath UniqueIDBridge::MakePathFromString(std::string_view str); - -void UniqueIDBridge::SetThreadProject(hecl::Database::Project& project) { s_Project.reset(&project); } - -/** PAK 32-bit Unique ID */ -template <> -void UniqueID32::Enumerate(typename Read::StreamT& reader) { - assign(reader.readUint32Big()); -} -template <> -void UniqueID32::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_id); -} -template <> -void UniqueID32::Enumerate(typename ReadYaml::StreamT& reader) { - *this = UniqueIDBridge::MakePathFromString(reader.readString()); -} -template <> -void UniqueID32::Enumerate(typename WriteYaml::StreamT& writer) { - if (!isValid()) - return; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); - if (!path) - return; - writer.writeString(path.getEncodableString()); -} -template <> -void UniqueID32::Enumerate(typename BinarySize::StreamT& s) { - s += 4; -} - -std::string UniqueID32::toString() const { return fmt::format(FMT_STRING("{}"), *this); } - -template <> -void UniqueID32Zero::Enumerate(typename Read::StreamT& reader) { - UniqueID32::Enumerate(reader); -} -template <> -void UniqueID32Zero::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(isValid() ? m_id : 0); -} -template <> -void UniqueID32Zero::Enumerate(typename ReadYaml::StreamT& reader) { - UniqueID32::Enumerate(reader); -} -template <> -void UniqueID32Zero::Enumerate(typename WriteYaml::StreamT& writer) { - UniqueID32::Enumerate(writer); -} -template <> -void UniqueID32Zero::Enumerate(typename BinarySize::StreamT& s) { - UniqueID32::Enumerate(s); -} - -/** PAK 64-bit Unique ID */ -template <> -void UniqueID64::Enumerate(typename Read::StreamT& reader) { - assign(reader.readUint64Big()); -} -template <> -void UniqueID64::Enumerate(typename Write::StreamT& writer) { - writer.writeUint64Big(m_id); -} -template <> -void UniqueID64::Enumerate(typename ReadYaml::StreamT& reader) { - *this = UniqueIDBridge::MakePathFromString(reader.readString()); -} -template <> -void UniqueID64::Enumerate(typename WriteYaml::StreamT& writer) { - if (!isValid()) - return; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); - if (!path) - return; - writer.writeString(path.getEncodableString()); -} -template <> -void UniqueID64::Enumerate(typename BinarySize::StreamT& s) { - s += 8; -} - -std::string UniqueID64::toString() const { return fmt::format(FMT_STRING("{}"), *this); } - -/** PAK 128-bit Unique ID */ -template <> -void UniqueID128::Enumerate(typename Read::StreamT& reader) { - m_id.id[0] = reader.readUint64Big(); - m_id.id[1] = reader.readUint64Big(); -} -template <> -void UniqueID128::Enumerate(typename Write::StreamT& writer) { - writer.writeUint64Big(m_id.id[0]); - writer.writeUint64Big(m_id.id[1]); -} -template <> -void UniqueID128::Enumerate(typename ReadYaml::StreamT& reader) { - *this = UniqueIDBridge::MakePathFromString(reader.readString()); -} -template <> -void UniqueID128::Enumerate(typename WriteYaml::StreamT& writer) { - if (!isValid()) - return; - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(*this); - if (!path) - return; - writer.writeString(path.getEncodableString()); -} -template <> -void UniqueID128::Enumerate(typename BinarySize::StreamT& s) { - s += 16; -} - -std::string UniqueID128::toString() const { return fmt::format(FMT_STRING("{}"), *this); } - -/** Word Bitmap reader/writer */ -void WordBitmap::read(athena::io::IStreamReader& reader, size_t bitCount) { - m_bitCount = bitCount; - size_t wordCount = (bitCount + 31) / 32; - m_words.clear(); - m_words.reserve(wordCount); - for (size_t w = 0; w < wordCount; ++w) - m_words.push_back(reader.readUint32Big()); -} -void WordBitmap::write(athena::io::IStreamWriter& writer) const { - for (atUint32 word : m_words) - writer.writeUint32Big(word); -} -void WordBitmap::binarySize(size_t& __isz) const { __isz += m_words.size() * 4; } - -hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath, - std::string_view test) { - for (const auto& ent : dEnum) - if (hecl::StringUtils::BeginsWith(ent.m_name, test)) - return hecl::ProjectPath(parentPath, ent.m_name); - return {}; -} - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/DNACommon.hpp b/DataSpec/DNACommon/DNACommon.hpp deleted file mode 100644 index ed9e856bb..000000000 --- a/DataSpec/DNACommon/DNACommon.hpp +++ /dev/null @@ -1,394 +0,0 @@ -#pragma once - -#include -#include "logvisor/logvisor.hpp" -#include "athena/DNAYaml.hpp" -#include "hecl/Database.hpp" -#include "../SpecBase.hpp" -#include "boo/ThreadLocalPtr.hpp" -#include "zeus/CColor.hpp" - -namespace DataSpec { -struct SpecBase; - -extern logvisor::Module LogDNACommon; -extern ThreadLocalPtr g_curSpec; -extern ThreadLocalPtr g_PakRouter; -extern ThreadLocalPtr g_ThreadBlenderToken; - -/* This comes up a great deal */ -using BigDNA = athena::io::DNA; -using BigDNAV = athena::io::DNAV; -using BigDNAVYaml = athena::io::DNAVYaml; - -/** FourCC with DNA read/write */ -using DNAFourCC = hecl::DNAFourCC; - -class DNAColor final : public BigDNA, public zeus::CColor { -public: - DNAColor() = default; - DNAColor(const zeus::CColor& color) : zeus::CColor(color) {} - AT_DECL_EXPLICIT_DNA_YAML -}; -template <> -inline void DNAColor::Enumerate(typename Read::StreamT& _r) { - zeus::CColor::readRGBABig(_r); -} -template <> -inline void DNAColor::Enumerate(typename Write::StreamT& _w) { - zeus::CColor::writeRGBABig(_w); -} -template <> -inline void DNAColor::Enumerate(typename ReadYaml::StreamT& _r) { - size_t count; - if (auto v = _r.enterSubVector(count)) { - zeus::simd_floats f; - f[0] = (count >= 1) ? _r.readFloat() : 0.f; - f[1] = (count >= 2) ? _r.readFloat() : 0.f; - f[2] = (count >= 3) ? _r.readFloat() : 0.f; - f[3] = (count >= 4) ? _r.readFloat() : 0.f; - mSimd.copy_from(f); - } -} -template <> -inline void DNAColor::Enumerate(typename WriteYaml::StreamT& _w) { - if (auto v = _w.enterSubVector()) { - zeus::simd_floats f(mSimd); - _w.writeFloat(f[0]); - _w.writeFloat(f[1]); - _w.writeFloat(f[2]); - _w.writeFloat(f[3]); - } -} -template <> -inline void DNAColor::Enumerate(typename BinarySize::StreamT& _s) { - _s += 16; -} - -using FourCC = hecl::FourCC; -class UniqueID32; -class UniqueID64; -class UniqueID128; - -/** Common virtual interface for runtime ambiguity resolution */ -class PAKRouterBase { -protected: - const SpecBase& m_dataSpec; - -public: - PAKRouterBase(const SpecBase& dataSpec) : m_dataSpec(dataSpec) {} - hecl::Database::Project& getProject() const { return m_dataSpec.getProject(); } - virtual hecl::ProjectPath getWorking(const UniqueID32&, bool silenceWarnings = false) const { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAKRouter IDType mismatch; expected UniqueID32 specialization")); - return hecl::ProjectPath(); - } - virtual hecl::ProjectPath getWorking(const UniqueID64&, bool silenceWarnings = false) const { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAKRouter IDType mismatch; expected UniqueID64 specialization")); - return hecl::ProjectPath(); - } - virtual hecl::ProjectPath getWorking(const UniqueID128&, bool silenceWarnings = false) const { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAKRouter IDType mismatch; expected UniqueID128 specialization")); - return hecl::ProjectPath(); - } -}; - -/** Globally-accessed manager allowing UniqueID* classes to directly - * lookup destination paths of resources */ -class UniqueIDBridge { - friend class UniqueID32; - friend class UniqueID64; - - static ThreadLocalPtr s_Project; - -public: - template - static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings = false); - template - static hecl::ProjectPath MakePathFromString(std::string_view str); - - static void SetThreadProject(hecl::Database::Project& project); -}; - -/** PAK 32-bit Unique ID */ -class UniqueID32 : public BigDNA { -protected: - uint32_t m_id = 0xffffffff; - -public: - using value_type = uint32_t; - static UniqueID32 kInvalidId; - AT_DECL_EXPLICIT_DNA_YAML - bool isValid() const noexcept { return m_id != 0xffffffff && m_id != 0; } - void assign(uint32_t id) noexcept { m_id = id ? id : 0xffffffff; } - - UniqueID32& operator=(const hecl::ProjectPath& path) noexcept { - assign(path.parsedHash32()); - return *this; - } - - bool operator!=(const UniqueID32& other) const noexcept { return m_id != other.m_id; } - bool operator==(const UniqueID32& other) const noexcept { return m_id == other.m_id; } - bool operator<(const UniqueID32& other) const noexcept { return m_id < other.m_id; } - uint32_t toUint32() const noexcept { return m_id; } - uint64_t toUint64() const noexcept { return m_id; } - std::string toString() const; - void clear() noexcept { m_id = 0xffffffff; } - - UniqueID32() noexcept = default; - UniqueID32(uint32_t idin) noexcept { assign(idin); } - UniqueID32(athena::io::IStreamReader& reader) { read(reader); } - UniqueID32(const hecl::ProjectPath& path) noexcept { *this = path; } - UniqueID32(const char* hexStr) noexcept { - char copy[9]; - strncpy(copy, hexStr, 8); - copy[8] = '\0'; - assign(strtoul(copy, nullptr, 16)); - } - - static constexpr size_t BinarySize() noexcept { return 4; } -}; - -/** PAK 32-bit Unique ID - writes zero when invalid */ -class UniqueID32Zero : public UniqueID32 { -public: - AT_DECL_DNA_YAML - Delete __d2; - using UniqueID32::UniqueID32; -}; - -/** PAK 64-bit Unique ID */ -class UniqueID64 : public BigDNA { - uint64_t m_id = 0xffffffffffffffff; - -public: - using value_type = uint64_t; - AT_DECL_EXPLICIT_DNA_YAML - bool isValid() const noexcept { return m_id != 0xffffffffffffffff && m_id != 0; } - void assign(uint64_t id) noexcept { m_id = id ? id : 0xffffffffffffffff; } - - UniqueID64& operator=(const hecl::ProjectPath& path) noexcept { - assign(path.hash().val64()); - return *this; - } - - bool operator!=(const UniqueID64& other) const noexcept { return m_id != other.m_id; } - bool operator==(const UniqueID64& other) const noexcept { return m_id == other.m_id; } - bool operator<(const UniqueID64& other) const noexcept { return m_id < other.m_id; } - uint64_t toUint64() const noexcept { return m_id; } - std::string toString() const; - void clear() noexcept { m_id = 0xffffffffffffffff; } - - UniqueID64() noexcept = default; - UniqueID64(uint64_t idin) noexcept { assign(idin); } - UniqueID64(athena::io::IStreamReader& reader) { read(reader); } - UniqueID64(const hecl::ProjectPath& path) noexcept { *this = path; } - UniqueID64(const char* hexStr) noexcept { - char copy[17]; - std::strncpy(copy, hexStr, 16); - copy[16] = '\0'; - assign(std::strtoull(copy, nullptr, 16)); - } - - static constexpr size_t BinarySize() noexcept { return 8; } -}; - -/** PAK 128-bit Unique ID */ -class UniqueID128 : public BigDNA { -public: - union Value { - uint64_t id[2]; -#if __SSE__ - __m128i id128; -#endif - }; - -private: - Value m_id; - -public: - using value_type = uint64_t; - AT_DECL_EXPLICIT_DNA_YAML - UniqueID128() noexcept { - m_id.id[0] = 0xffffffffffffffff; - m_id.id[1] = 0xffffffffffffffff; - } - UniqueID128(uint64_t idin) noexcept { - m_id.id[0] = idin; - m_id.id[1] = 0; - } - bool isValid() const noexcept { - return m_id.id[0] != 0xffffffffffffffff && m_id.id[0] != 0 && m_id.id[1] != 0xffffffffffffffff && m_id.id[1] != 0; - } - - UniqueID128& operator=(const hecl::ProjectPath& path) noexcept { - m_id.id[0] = path.hash().val64(); - m_id.id[1] = 0; - return *this; - } - UniqueID128(const hecl::ProjectPath& path) noexcept { *this = path; } - - bool operator!=(const UniqueID128& other) const noexcept { -#if __SSE__ - __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); - int vmask = _mm_movemask_epi8(vcmp); - return vmask != 0xffff; -#else - return (m_id.id[0] != other.m_id.id[0]) || (m_id.id[1] != other.m_id.id[1]); -#endif - } - bool operator==(const UniqueID128& other) const noexcept { -#if __SSE__ - __m128i vcmp = _mm_cmpeq_epi32(m_id.id128, other.m_id.id128); - int vmask = _mm_movemask_epi8(vcmp); - return vmask == 0xffff; -#else - return (m_id.id[0] == other.m_id.id[0]) && (m_id.id[1] == other.m_id.id[1]); -#endif - } - bool operator<(const UniqueID128& other) const noexcept { - return m_id.id[0] < other.m_id.id[0] || (m_id.id[0] == other.m_id.id[0] && m_id.id[1] < other.m_id.id[1]); - } - void clear() noexcept { - m_id.id[0] = 0xffffffffffffffff; - m_id.id[1] = 0xffffffffffffffff; - } - uint64_t toUint64() const noexcept { return m_id.id[0]; } - uint64_t toHighUint64() const noexcept { return m_id.id[0]; } - uint64_t toLowUint64() const noexcept { return m_id.id[1]; } - std::string toString() const; - - static constexpr size_t BinarySize() noexcept { return 16; } -}; - -/** Casts ID type to its null-zero equivalent */ -template -using CastIDToZero = typename std::conditional_t, UniqueID32Zero, T>; - -/** Word Bitmap reader/writer */ -class WordBitmap { - std::vector m_words; - size_t m_bitCount = 0; - -public: - void read(athena::io::IStreamReader& reader, size_t bitCount); - void write(athena::io::IStreamWriter& writer) const; - void reserve(size_t bitCount) { m_words.reserve((bitCount + 31) / 32); } - void binarySize(size_t& __isz) const; - size_t getBitCount() const { return m_bitCount; } - bool getBit(size_t idx) const { - size_t wordIdx = idx / 32; - if (wordIdx >= m_words.size()) - return false; - size_t wordCur = idx % 32; - return (m_words[wordIdx] >> wordCur) & 0x1; - } - void setBit(size_t idx) { - size_t wordIdx = idx / 32; - while (wordIdx >= m_words.size()) - m_words.push_back(0); - size_t wordCur = idx % 32; - m_words[wordIdx] |= (1 << wordCur); - m_bitCount = std::max(m_bitCount, idx + 1); - } - void unsetBit(size_t idx) { - size_t wordIdx = idx / 32; - while (wordIdx >= m_words.size()) - m_words.push_back(0); - size_t wordCur = idx % 32; - m_words[wordIdx] &= ~(1 << wordCur); - m_bitCount = std::max(m_bitCount, idx + 1); - } - void clear() { - m_words.clear(); - m_bitCount = 0; - } - - class Iterator { - friend class WordBitmap; - const WordBitmap& m_bmp; - size_t m_idx = 0; - Iterator(const WordBitmap& bmp, size_t idx) : m_bmp(bmp), m_idx(idx) {} - - public: - using iterator_category = std::forward_iterator_tag; - using value_type = bool; - using difference_type = std::ptrdiff_t; - using pointer = bool*; - using reference = bool&; - - Iterator& operator++() { - ++m_idx; - return *this; - } - bool operator*() const { return m_bmp.getBit(m_idx); } - bool operator!=(const Iterator& other) const { return m_idx != other.m_idx; } - }; - Iterator begin() const { return Iterator(*this, 0); } - Iterator end() const { return Iterator(*this, m_bitCount); } -}; - -/** Resource cooker function */ -using ResCooker = std::function; - -/** Mappings of resources involved in extracting characters */ -template -struct CharacterAssociations { - struct RigPair { - IDType cskr, cinf; - }; - struct ModelRigPair { - IDType cinf, cmdl; - }; - /* CMDL -> (CSKR, CINF) */ - std::unordered_map m_cmdlRigs; - /* CSKR -> ANCS */ - std::unordered_map> m_cskrToCharacter; - /* ANCS -> (CINF, CMDL) */ - std::unordered_multimap> m_characterToAttachmentRigs; - using MultimapIteratorPair = - std::pair>::const_iterator, - typename std::unordered_multimap>::const_iterator>; - void addAttachmentRig(IDType character, IDType cinf, IDType cmdl, const char* name) { - auto range = m_characterToAttachmentRigs.equal_range(character); - for (auto it = range.first; it != range.second; ++it) - if (it->second.second == name) - return; - m_characterToAttachmentRigs.insert(std::make_pair(character, std::make_pair(ModelRigPair{cinf, cmdl}, name))); - } -}; - -hecl::ProjectPath GetPathBeginsWith(const hecl::DirectoryEnumerator& dEnum, const hecl::ProjectPath& parentPath, - std::string_view test); -inline hecl::ProjectPath GetPathBeginsWith(const hecl::ProjectPath& parentPath, std::string_view test) { - return GetPathBeginsWith(hecl::DirectoryEnumerator(parentPath.getAbsolutePath()), parentPath, test); -} - -} // namespace DataSpec - -/* Hash template-specializations for UniqueID types */ -namespace std { -template <> -struct hash { - size_t operator()(const DataSpec::DNAFourCC& fcc) const noexcept { return fcc.toUint32(); } -}; - -template <> -struct hash { - size_t operator()(const DataSpec::UniqueID32& id) const noexcept { return id.toUint32(); } -}; - -template <> -struct hash { - size_t operator()(const DataSpec::UniqueID64& id) const noexcept { return id.toUint64(); } -}; - -template <> -struct hash { - size_t operator()(const DataSpec::UniqueID128& id) const noexcept { return id.toHighUint64() ^ id.toLowUint64(); } -}; -} // namespace std - -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID32, "{:08X}", obj.toUint32()) -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID32Zero, "{:08X}", obj.toUint32()) -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID64, "{:016X}", obj.toUint64()) -FMT_CUSTOM_FORMATTER(DataSpec::UniqueID128, "{:016X}{:016X}", obj.toHighUint64(), obj.toLowUint64()) diff --git a/DataSpec/DNACommon/DPSC.cpp b/DataSpec/DNACommon/DPSC.cpp deleted file mode 100644 index 4b88eda08..000000000 --- a/DataSpec/DNACommon/DPSC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/DPSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_DPSM>; -template struct PPImpl<_DPSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_DPSM>) - -template <> -std::string_view PPImpl<_DPSM>::DNAType() { - return "DPSM"sv; -} - -template <> -std::string_view PPImpl<_DPSM>::DNAType() { - return "DPSM"sv; -} - -template -bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - DPSM dpsm; - dpsm.read(rs); - athena::io::ToYAMLStream(dpsm, writer); - return true; - } - return false; -} -template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - dpsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); -template bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/DPSC.def b/DataSpec/DNACommon/DPSC.def deleted file mode 100644 index ac61eb49f..000000000 --- a/DataSpec/DNACommon/DPSC.def +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -ENTRY('1LFT', x0_quad.x0_LFT) -ENTRY('1SZE', x0_quad.x4_SZE) -ENTRY('1ROT', x0_quad.x8_ROT) -ENTRY('1OFF', x0_quad.xc_OFF) -ENTRY('1CLR', x0_quad.x10_CLR) -ENTRY('1TEX', x0_quad.x14_TEX) -ENTRY('1ADD', x0_quad.x18_ADD) -ENTRY('2LFT', x1c_quad.x0_LFT) -ENTRY('2SZE', x1c_quad.x4_SZE) -ENTRY('2ROT', x1c_quad.x8_ROT) -ENTRY('2OFF', x1c_quad.xc_OFF) -ENTRY('2CLR', x1c_quad.x10_CLR) -ENTRY('2TEX', x1c_quad.x14_TEX) -ENTRY('2ADD', x1c_quad.x18_ADD) -ENTRY('DMDL', x38_DMDL) -ENTRY('DLFT', x48_DLFT) -ENTRY('DMOP', x4c_DMOP) -ENTRY('DMRT', x50_DMRT) -ENTRY('DMSC', x54_DMSC) -ENTRY('DMCL', x58_DMCL) -ENTRY('DMAB', x5c_24_DMAB) -ENTRY('DMOO', x5c_25_DMOO) - -#undef ENTRY diff --git a/DataSpec/DNACommon/DPSC.hpp b/DataSpec/DNACommon/DPSC.hpp deleted file mode 100644 index 56de7d9e6..000000000 --- a/DataSpec/DNACommon/DPSC.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _DPSM { - static constexpr ParticleType Type = ParticleType::DPSM; - - struct SQuadDescr { - IntElementFactory x0_LFT; - RealElementFactory x4_SZE; - RealElementFactory x8_ROT; - VectorElementFactory xc_OFF; - ColorElementFactory x10_CLR; - UVElementFactory x14_TEX; - bool x18_ADD = false; - }; - - SQuadDescr x0_quad; - SQuadDescr x1c_quad; - ChildResourceFactory x38_DMDL; - IntElementFactory x48_DLFT; - VectorElementFactory x4c_DMOP; - VectorElementFactory x50_DMRT; - VectorElementFactory x54_DMSC; - ColorElementFactory x58_DMCL; - - bool x5c_24_DMAB = false; - bool x5c_25_DMOO = false; - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#include "DPSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "DPSC.def" - default: - return false; - } - } -}; -template -using DPSM = PPImpl<_DPSM>; - -template -bool ExtractDPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteDPSM(const DPSM& dpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/DeafBabe.cpp b/DataSpec/DNACommon/DeafBabe.cpp deleted file mode 100644 index 51aa1bd4e..000000000 --- a/DataSpec/DNACommon/DeafBabe.cpp +++ /dev/null @@ -1,258 +0,0 @@ -#include "DataSpec/DNACommon/DeafBabe.hpp" - -#include -#include -#include -#include - -#include "DataSpec/DNACommon/AROTBuilder.hpp" -#include "DataSpec/DNAMP1/DeafBabe.hpp" -#include "DataSpec/DNAMP1/DCLN.hpp" -#include "DataSpec/DNAMP2/DeafBabe.hpp" - -#include -#include -#include - -namespace DataSpec { - -template -void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln, atInt32 idx) { - os << "material_index = []\n" - "col_bm = bmesh.new()\n"; - for (const atVec3f& vert : db.verts) { - zeus::simd_floats f(vert.simd); - os.format(FMT_STRING("col_bm.verts.new(({},{},{}))\n"), f[0], f[1], f[2]); - } - - os << "col_bm.verts.ensure_lookup_table()\n"; - - int triIdx = 0; - for (const typename DEAFBABE::Triangle& tri : db.triangleEdgeConnections) { - const typename DEAFBABE::Material& triMat = db.materials[db.triMats[triIdx++]]; - const typename DEAFBABE::Edge& edge0 = db.edgeVertConnections[tri.edges[0]]; - const typename DEAFBABE::Edge& edge1 = db.edgeVertConnections[tri.edges[1]]; - const typename DEAFBABE::Edge& edge2 = db.edgeVertConnections[tri.edges[2]]; - if (!edge0.verts[0] && !edge1.verts[0] && !edge2.verts[0]) - break; - - int vindices[3]; - vindices[2] = - (edge1.verts[0] != edge0.verts[0] && edge1.verts[0] != edge0.verts[1]) ? edge1.verts[0] : edge1.verts[1]; - - if (triMat.flipFace()) { - vindices[0] = edge0.verts[1]; - vindices[1] = edge0.verts[0]; - } else { - vindices[0] = edge0.verts[0]; - vindices[1] = edge0.verts[1]; - } - - os << "tri_verts = []\n"; - os.format(FMT_STRING("tri_verts.append(col_bm.verts[{}])\n"), vindices[0]); - os.format(FMT_STRING("tri_verts.append(col_bm.verts[{}])\n"), vindices[1]); - os.format(FMT_STRING("tri_verts.append(col_bm.verts[{}])\n"), vindices[2]); - - os.format(FMT_STRING("face = col_bm.faces.get(tri_verts)\n" - "if face is None:\n" - " face = col_bm.faces.new(tri_verts)\n" - "else:\n" - " face = face.copy()\n" - " for i in range(3):\n" - " face.verts[i].co = tri_verts[i].co\n" - " col_bm.verts.ensure_lookup_table()\n" - "face.material_index = select_material(0x{:016X}" - ")\n" - "face.smooth = False\n" - "\n"), - atUint64(triMat.material)); - } - - db.insertNoClimb(os); - - if (isDcln) - os.format(FMT_STRING("col_mesh = bpy.data.meshes.new('CMESH_{}')\n"), idx); - else - os << "col_mesh = bpy.data.meshes.new('CMESH')\n"; - - os << "col_bm.to_mesh(col_mesh)\n" - "col_mesh_obj = bpy.data.objects.new(col_mesh.name, col_mesh)\n" - "\n" - "for mat_name in material_index:\n" - " mat = material_dict[mat_name]\n" - " col_mesh.materials.append(mat)\n" - "\n" - "if 'Collision' not in bpy.data.collections:\n" - " coll = bpy.data.collections.new('Collision')\n" - " bpy.context.scene.collection.children.link(coll)\n" - "else:\n" - " coll = bpy.data.collections['Collision']\n" - "coll.objects.link(col_mesh_obj)\n" - "bpy.context.view_layer.objects.active = col_mesh_obj\n" - "bpy.ops.object.mode_set(mode='EDIT')\n" - "bpy.ops.mesh.tris_convert_to_quads()\n" - "bpy.ops.object.mode_set(mode='OBJECT')\n" - "bpy.context.view_layer.objects.active = None\n" - "col_mesh_obj.display_type = 'SOLID'\n" - "\n"; -} - -template void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DNAMP1::DeafBabe& db, - bool isDcln, atInt32 idx); -template void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DNAMP2::DeafBabe& db, - bool isDcln, atInt32 idx); -template void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, - const DNAMP1::DCLN::Collision& db, bool isDcln, - atInt32 idx); - -template -static void PopulateAreaFields( - DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB, - std::enable_if_t::value || std::is_same::value, - int>* = 0) { - AROTBuilder builder; - auto octree = builder.buildCol(colMesh, db.rootNodeType); - static_cast&>(db.bspTree) = std::move(octree.first); - db.bspSize = octree.second; - - db.unk1 = 0x1000000; - size_t dbSize = 0; - db.binarySize(dbSize); - db.length = dbSize - 8; - db.magic = 0xDEAFBABE; - db.version = 3; - db.aabb[0] = fullAABB.min; - db.aabb[1] = fullAABB.max; -} - -template -static void PopulateAreaFields(DEAFBABE& db, const hecl::blender::ColMesh& colMesh, const zeus::CAABox& fullAABB, - std::enable_if_t::value, int>* = 0) { - db.magic = 0xDEAFBABE; - db.version = 2; - db.memSize = 0; -} - -class MaterialPool { - std::unordered_map m_materials; - -public: - template - int AddOrLookup(const M& mat, V& vec) { - auto search = m_materials.find(mat.material); - if (search != m_materials.end()) - return search->second; - auto idx = int(vec.size()); - vec.push_back(mat); - m_materials[mat.material] = idx; - return idx; - } -}; - -template -void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh) { - using BlendMat = hecl::blender::ColMesh::Material; - - auto MakeMat = [](const BlendMat& mat, bool flipFace) -> typename DEAFBABE::Material { - typename DEAFBABE::Material dbMat = {}; - dbMat.setUnknown(mat.unknown); - dbMat.setSurfaceStone(mat.surfaceStone); - dbMat.setSurfaceMetal(mat.surfaceMetal); - dbMat.setSurfaceGrass(mat.surfaceGrass); - dbMat.setSurfaceIce(mat.surfaceIce); - dbMat.setPillar(mat.pillar); - dbMat.setSurfaceMetalGrating(mat.surfaceMetalGrating); - dbMat.setSurfacePhazon(mat.surfacePhazon); - dbMat.setSurfaceDirt(mat.surfaceDirt); - dbMat.setSurfaceLava(mat.surfaceLava); - dbMat.setSurfaceSPMetal(mat.surfaceSPMetal); - dbMat.setSurfaceLavaStone(mat.surfaceLavaStone); - dbMat.setSurfaceSnow(mat.surfaceSnow); - dbMat.setSurfaceMudSlow(mat.surfaceMudSlow); - dbMat.setSurfaceFabric(mat.surfaceFabric); - dbMat.setHalfPipe(mat.halfPipe); - dbMat.setSurfaceMud(mat.surfaceMud); - dbMat.setSurfaceGlass(mat.surfaceGlass); - dbMat.setUnused3(mat.unused3); - dbMat.setUnused4(mat.unused4); - dbMat.setSurfaceShield(mat.surfaceShield); - dbMat.setSurfaceSand(mat.surfaceSand); - dbMat.setSurfaceMothOrSeedOrganics(mat.surfaceMothOrSeedOrganics); - dbMat.setSurfaceWeb(mat.surfaceWeb); - dbMat.setProjectilePassthrough(mat.projPassthrough); - dbMat.setSolid(mat.solid); - dbMat.setNoPlatformCollision(mat.noPlatformCollision); - dbMat.setCameraPassthrough(mat.camPassthrough); - dbMat.setSurfaceWood(mat.surfaceWood); - dbMat.setSurfaceOrganic(mat.surfaceOrganic); - dbMat.setNoEdgeCollision(mat.noEdgeCollision); - dbMat.setSurfaceRubber(mat.surfaceRubber); - dbMat.setSeeThrough(mat.seeThrough); - dbMat.setScanPassthrough(mat.scanPassthrough); - dbMat.setAiPassthrough(mat.aiPassthrough); - dbMat.setCeiling(mat.ceiling); - dbMat.setWall(mat.wall); - dbMat.setFloor(mat.floor); - dbMat.setAiBlock(mat.aiBlock); - dbMat.setJumpNotAllowed(mat.jumpNotAllowed); - dbMat.setSpiderBall(mat.spiderBall); - dbMat.setScrewAttackWallJump(mat.screwAttackWallJump); - dbMat.setFlipFace(flipFace); - return dbMat; - }; - - MaterialPool matPool; - db.materials.reserve(colMesh.materials.size() * 2); - - zeus::CAABox fullAABB; - - db.verts.reserve(colMesh.verts.size()); - db.vertMats.resize(colMesh.verts.size()); - for (const auto& vert : colMesh.verts) { - fullAABB.accumulateBounds(zeus::CVector3f(vert)); - db.verts.push_back(vert); - } - db.vertMatsCount = colMesh.verts.size(); - db.vertCount = colMesh.verts.size(); - - db.edgeVertConnections.reserve(colMesh.edges.size()); - db.edgeMats.resize(colMesh.edges.size()); - for (const auto& edge : colMesh.edges) { - db.edgeVertConnections.emplace_back(); - db.edgeVertConnections.back().verts[0] = edge.verts[0]; - db.edgeVertConnections.back().verts[1] = edge.verts[1]; - } - db.edgeMatsCount = colMesh.edges.size(); - db.edgeVertsCount = colMesh.edges.size(); - - db.triMats.reserve(colMesh.trianges.size()); - db.triangleEdgeConnections.reserve(colMesh.trianges.size()); - for (const auto& tri : colMesh.trianges) { - int triMatIdx = matPool.AddOrLookup(MakeMat(colMesh.materials[tri.matIdx], tri.flip), db.materials); - db.triMats.push_back(triMatIdx); - - db.triangleEdgeConnections.emplace_back(); - db.triangleEdgeConnections.back().edges[0] = tri.edges[0]; - db.triangleEdgeConnections.back().edges[1] = tri.edges[1]; - db.triangleEdgeConnections.back().edges[2] = tri.edges[2]; - - for (int e = 0; e < 3; ++e) { - db.edgeMats[tri.edges[e]] = triMatIdx; - for (int v = 0; v < 2; ++v) - db.vertMats[colMesh.edges[e].verts[v]] = triMatIdx; - } - } - db.triMatsCount = colMesh.trianges.size(); - db.triangleEdgesCount = colMesh.trianges.size() * 3; - - db.materialCount = db.materials.size(); - - PopulateAreaFields(db, colMesh, fullAABB); -} - -template void DeafBabeBuildFromBlender(DNAMP1::DeafBabe& db, const hecl::blender::ColMesh& colMesh); -template void DeafBabeBuildFromBlender(DNAMP2::DeafBabe& db, const hecl::blender::ColMesh& colMesh); -template void DeafBabeBuildFromBlender(DNAMP1::DCLN::Collision& db, - const hecl::blender::ColMesh& colMesh); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/DeafBabe.hpp b/DataSpec/DNACommon/DeafBabe.hpp deleted file mode 100644 index 230df7a77..000000000 --- a/DataSpec/DNACommon/DeafBabe.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include - -namespace hecl::blender { -class PyOutStream; -struct ColMesh; -} // namespace hecl::blender - -namespace DataSpec { - -enum class BspNodeType : atUint32 { Invalid, Branch, Leaf }; - -template -void DeafBabeSendToBlender(hecl::blender::PyOutStream& os, const DEAFBABE& db, bool isDcln = false, atInt32 idx = -1); - -template -void DeafBabeBuildFromBlender(DEAFBABE& db, const hecl::blender::ColMesh& colMesh); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/EGMC.hpp b/DataSpec/DNACommon/EGMC.hpp deleted file mode 100644 index 54f7b717b..000000000 --- a/DataSpec/DNACommon/EGMC.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec::DNACommon { -struct EGMC : public BigDNA { - AT_DECL_DNA - Value count; - - struct Object : BigDNA { - AT_DECL_DNA - Value mesh; - Value instanceId; - }; - - Vector objects; -}; -} // namespace DataSpec::DNACommon diff --git a/DataSpec/DNACommon/ELSC.cpp b/DataSpec/DNACommon/ELSC.cpp deleted file mode 100644 index 32d3d3cac..000000000 --- a/DataSpec/DNACommon/ELSC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/ELSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_ELSM>; -template struct PPImpl<_ELSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_ELSM>) - -template <> -std::string_view ELSM::DNAType() { - return "ELSM"sv; -} - -template <> -std::string_view ELSM::DNAType() { - return "ELSM"sv; -} - -template -bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - ELSM elsm; - elsm.read(rs); - athena::io::ToYAMLStream(elsm, writer); - return true; - } - return false; -} -template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteELSM(const ELSM& elsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - elsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteELSM(const ELSM& gpsm, const hecl::ProjectPath& outPath); -template bool WriteELSM(const ELSM& gpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/ELSC.def b/DataSpec/DNACommon/ELSC.def deleted file mode 100644 index b8498ab1a..000000000 --- a/DataSpec/DNACommon/ELSC.def +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef EMITTER_ENTRY -#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -INT_ENTRY('LIFE', x0_LIFE) -INT_ENTRY('SLIF', x4_SLIF) -REAL_ENTRY('GRAT', x8_GRAT) -INT_ENTRY('SCNT', xc_SCNT) -INT_ENTRY('SSEG', x10_SSEG) -COLOR_ENTRY('COLR', x14_COLR) -EMITTER_ENTRY('IEMT', x18_IEMT) -EMITTER_ENTRY('FEMT', x1c_FEMT) -REAL_ENTRY('AMPL', x20_AMPL) -REAL_ENTRY('AMPD', x24_AMPD) -REAL_ENTRY('LWD1', x28_LWD1) -REAL_ENTRY('LWD2', x2c_LWD2) -REAL_ENTRY('LWD3', x30_LWD3) -COLOR_ENTRY('LCL1', x34_LCL1) -COLOR_ENTRY('LCL2', x38_LCL2) -COLOR_ENTRY('LCL3', x3c_LCL3) -RES_ENTRY('SSWH', x40_SSWH) -RES_ENTRY('GPSM', x50_GPSM) -RES_ENTRY('EPSM', x60_EPSM) -BOOL_ENTRY('ZERY', x70_ZERY) - -#undef ENTRY -#undef INT_ENTRY -#undef REAL_ENTRY -#undef COLOR_ENTRY -#undef EMITTER_ENTRY -#undef RES_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/ELSC.hpp b/DataSpec/DNACommon/ELSC.hpp deleted file mode 100644 index e6881d9c0..000000000 --- a/DataSpec/DNACommon/ELSC.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/ParticleCommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -#include - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _ELSM { - static constexpr ParticleType Type = ParticleType::ELSM; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define BOOL_ENTRY(name, identifier) bool identifier = false; -#include "ELSC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#include "ELSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "ELSC.def" - default: - return false; - } - } -}; -template -using ELSM = PPImpl<_ELSM>; - -template -bool ExtractELSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteELSM(const ELSM& elsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/FONT.cpp b/DataSpec/DNACommon/FONT.cpp deleted file mode 100644 index 2c5a7c2a6..000000000 --- a/DataSpec/DNACommon/FONT.cpp +++ /dev/null @@ -1,235 +0,0 @@ -#include "DataSpec/DNACommon/FONT.hpp" - -#include "DataSpec/DNACommon/PAK.hpp" - -#include - -namespace DataSpec::DNAFont { -logvisor::Module LogModule("DataSpec::DNAFont"); - -template -void FONT::_read(athena::io::IStreamReader& __dna_reader) { - /* magic */ - DNAFourCC magic; - magic.read(__dna_reader); - if (magic != SBIG('FONT')) { - LogModule.report(logvisor::Fatal, FMT_STRING("Invalid FONT magic '{}'"), magic); - return; - } - /* version */ - version = __dna_reader.readUint32Big(); - /* unknown1 */ - unknown1 = __dna_reader.readUint32Big(); - /* lineHeight */ - lineHeight = __dna_reader.readInt32Big(); - /* verticalOffset */ - verticalOffset = __dna_reader.readInt32Big(); - /* lineMargin */ - lineMargin = __dna_reader.readInt32Big(); - /* unknown2 */ - unknown2 = __dna_reader.readBool(); - /* unknown3 */ - unknown3 = __dna_reader.readBool(); - /* unknown4 */ - unknown4 = __dna_reader.readUint32Big(); - /* fontSize */ - fontSize = __dna_reader.readUint32Big(); - /* name */ - name = __dna_reader.readString(-1); - /* textureId */ - textureId.read(__dna_reader); - /* textureFormat */ - textureFormat = __dna_reader.readUint32Big(); - /* glyphCount */ - glyphCount = __dna_reader.readUint32Big(); - /* glyphs */ - for (atUint32 i = 0; i < glyphCount; i++) { - if (version < 4) - glyphs.emplace_back(new GlyphMP1); - else - glyphs.emplace_back(new GlyphMP2); - glyphs.back()->read(__dna_reader); - } - /* kerningInfoCount */ - kerningInfoCount = __dna_reader.readUint32Big(); - /* kerningInfo */ - __dna_reader.enumerate(kerningInfo, kerningInfoCount); -} - -template -void FONT::_write(athena::io::IStreamWriter& __dna_writer) const { - /* magic */ - __dna_writer.writeBytes((atInt8*)"FONT", 4); - /* version */ - __dna_writer.writeUint32Big(version); - /* unknown1 */ - __dna_writer.writeUint32Big(unknown1); - /* lineHeight */ - __dna_writer.writeInt32Big(lineHeight); - /* verticalOffset */ - __dna_writer.writeInt32Big(verticalOffset); - /* lineMargin */ - __dna_writer.writeInt32Big(lineMargin); - /* unknown2 */ - __dna_writer.writeBool(unknown2); - /* unknown3 */ - __dna_writer.writeBool(unknown3); - /* unknown4 */ - __dna_writer.writeUint32Big(unknown4); - /* fontSize */ - __dna_writer.writeUint32Big(fontSize); - /* name */ - __dna_writer.writeString(name, -1); - /* textureId */ - textureId.write(__dna_writer); - /* textureFormat */ - __dna_writer.writeUint32Big(textureFormat); - /* glyphCount */ - __dna_writer.writeUint32Big(glyphCount); - /* glyphs */ - for (const std::unique_ptr& glyph : glyphs) - glyph->write(__dna_writer); - /* kerningInfoCount */ - __dna_writer.writeUint32Big(kerningInfoCount); - /* kerningInfo */ - __dna_writer.enumerate(kerningInfo); -} - -template -void FONT::_read(athena::io::YAMLDocReader& __dna_docin) { - /* version */ - version = __dna_docin.readUint32("version"); - /* unknown1 */ - unknown1 = __dna_docin.readUint32("unknown1"); - /* lineHeight */ - lineHeight = __dna_docin.readInt32("lineHeight"); - /* verticalOffset */ - verticalOffset = __dna_docin.readInt32("verticalOffset"); - /* lineMargin */ - lineMargin = __dna_docin.readInt32("lineMargin"); - /* unknown2 */ - unknown2 = __dna_docin.readBool("unknown2"); - /* unknown3 */ - unknown3 = __dna_docin.readBool("unknown3"); - /* unknown4 */ - unknown4 = __dna_docin.readUint32("unknown4"); - /* fontSize */ - fontSize = __dna_docin.readUint32("fontSize"); - /* name */ - name = __dna_docin.readString("name"); - /* textureId */ - __dna_docin.enumerate("textureId", textureId); - /* textureFormat */ - textureFormat = __dna_docin.readUint32("textureFormat"); - /* glyphCount */ - /* glyphs */ - size_t count; - if (auto v = __dna_docin.enterSubVector("glyphs", count)) { - glyphCount = count; - for (atUint32 i = 0; i < glyphCount; i++) { - if (version < 4) - glyphs.emplace_back(new GlyphMP1); - else - glyphs.emplace_back(new GlyphMP2); - - if (auto rec = __dna_docin.enterSubRecord()) - glyphs.back()->read(__dna_docin); - } - } - /* kerningInfoCount squelched */ - /* kerningInfo */ - kerningInfoCount = __dna_docin.enumerate("kerningInfo", kerningInfo); -} - -template -void FONT::_write(athena::io::YAMLDocWriter& __dna_docout) const { - /* version */ - __dna_docout.writeUint32("version", version); - /* unknown1 */ - __dna_docout.writeUint32("unknown1", unknown1); - /* lineHeight */ - __dna_docout.writeInt32("lineHeight", lineHeight); - /* verticalOffset */ - __dna_docout.writeInt32("verticalOffset", verticalOffset); - /* lineMargin */ - __dna_docout.writeInt32("lineMargin", lineMargin); - /* unknown2 */ - __dna_docout.writeBool("unknown2", unknown2); - /* unknown3 */ - __dna_docout.writeBool("unknown3", unknown3); - /* unknown4 */ - __dna_docout.writeUint32("unknown4", unknown4); - /* fontSize */ - __dna_docout.writeUint32("fontSize", fontSize); - /* name */ - __dna_docout.writeString("name", name); - /* textureId */ - __dna_docout.enumerate("textureId", textureId); - /* textureFormat */ - __dna_docout.writeUint32("textureFormat", textureFormat); - /* glyphCount squelched */ - /* glyphs */ - if (auto v = __dna_docout.enterSubVector("glyphs")) - for (const std::unique_ptr& glyph : glyphs) - if (auto rec = __dna_docout.enterSubRecord()) - glyph->write(__dna_docout); - /* kerningInfoCount squelched */ - /* kerningInfo */ - __dna_docout.enumerate("kerningInfo", kerningInfo); -} - -template <> -std::string_view FONT::DNAType() { - return "FONT"sv; -} - -template <> -std::string_view FONT::DNAType() { - return "FONT"sv; -} - -template -void FONT::_binarySize(size_t& __isz) const { - __isz += name.size() + 1; - textureId.binarySize(__isz); - for (const std::unique_ptr& glyph : glyphs) - glyph->binarySize(__isz); - for (const KerningInfo& k : kerningInfo) - k.binarySize(__isz); - __isz += 46; -} - -AT_SUBSPECIALIZE_DNA_YAML(FONT) -AT_SUBSPECIALIZE_DNA_YAML(FONT) - -template -bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - FONT font; - font.read(rs); - athena::io::ToYAMLStream(font, writer); - return true; - } - return false; -} - -template bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - font.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath); -template bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFont diff --git a/DataSpec/DNACommon/FONT.hpp b/DataSpec/DNACommon/FONT.hpp deleted file mode 100644 index 0ebdef68d..000000000 --- a/DataSpec/DNACommon/FONT.hpp +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAFont { -struct GlyphRect : BigDNA { - AT_DECL_DNA_YAML - Value left; - Value top; - Value right; - Value bottom; -}; -struct IGlyph : BigDNAVYaml { - AT_DECL_DNA_YAMLV - Value m_character; - GlyphRect m_glyphRect; - - atUint16 character() const { return m_character; } - float left() const { return m_glyphRect.left; } - float top() const { return m_glyphRect.top; } - float right() const { return m_glyphRect.right; } - float bottom() const { return m_glyphRect.bottom; } - GlyphRect rect() const { return m_glyphRect; } - - virtual atInt32 layer() const { return 0; } - virtual atInt32 leftPadding() const = 0; - virtual atInt32 advance() const = 0; - virtual atInt32 rightPadding() const = 0; - virtual atInt32 width() const = 0; - virtual atInt32 height() const = 0; - virtual atInt32 baseline() const = 0; - virtual atInt32 kerningIndex() const = 0; -}; - -struct GlyphMP1 : IGlyph { - AT_DECL_DNA_YAMLV - Value m_leftPadding; - Value m_advance; - Value m_rightPadding; - Value m_width; - Value m_height; - Value m_baseline; - Value m_kerningIndex; - - atInt32 leftPadding() const override { return m_leftPadding; } - atInt32 advance() const override { return m_advance; } - atInt32 rightPadding() const override { return m_rightPadding; } - atInt32 width() const override { return m_width; } - atInt32 height() const override { return m_height; } - atInt32 baseline() const override { return m_baseline; } - atInt32 kerningIndex() const override { return m_kerningIndex; } -}; - -struct GlyphMP2 : IGlyph { - AT_DECL_DNA_YAMLV - Value m_layer; - Value m_leftPadding; - Value m_advance; - Value m_rightPadding; - Value m_width; - Value m_height; - Value m_baseline; - Value m_kerningIndex; - - atInt32 layer() const override { return m_layer; } - atInt32 leftPadding() const override { return m_leftPadding; } - atInt32 advance() const override { return m_advance; } - atInt32 rightPadding() const override { return m_rightPadding; } - atInt32 width() const override { return m_width; } - atInt32 height() const override { return m_height; } - atInt32 baseline() const override { return m_baseline; } - atInt32 kerningIndex() const override { return m_kerningIndex; } -}; - -struct KerningInfo : BigDNA { - AT_DECL_DNA_YAML - Value thisChar; - Value nextChar; - Value adjust; -}; - -template -struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FONT : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - Value version; - Value unknown1; - Value lineHeight; - Value verticalOffset; - Value lineMargin; - Value unknown2; - Value unknown3; - Value unknown4; - Value fontSize; // in points - String<-1> name; - Value textureId; - Value textureFormat; - Value glyphCount; - std::vector> glyphs; - Value kerningInfoCount; - Vector kerningInfo; - - void gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(textureId, pathsOut); - } -}; - -template -bool ExtractFONT(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteFONT(const FONT& font, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFont diff --git a/DataSpec/DNACommon/FSM2.cpp b/DataSpec/DNACommon/FSM2.cpp deleted file mode 100644 index 535c2dc1b..000000000 --- a/DataSpec/DNACommon/FSM2.cpp +++ /dev/null @@ -1,82 +0,0 @@ -#include "DataSpec/DNACommon/FSM2.hpp" - -#include "DataSpec/DNACommon/PAK.hpp" - -#include -#include -#include - -#include - -namespace DataSpec::DNAFSM2 { -logvisor::Module LogDNAFSM2("DataSpec::DNAFSM2"); - -template -template -void FSM2::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"header"}, header, s); - if (header.magic != SBIG('FSM2')) { - LogDNAFSM2.report(logvisor::Fatal, FMT_STRING("Invalid FSM2 magic '{}' expected 'FSM2'"), header.magic); - return; - } - - if (header.version == 1) { - if (!detail) - detail.reset(new FSMV1); - Do(athena::io::PropId{"detail"}, static_cast(*detail), s); - } else if (header.version == 2) { - if (!detail) - detail.reset(new FSMV2); - Do(athena::io::PropId{"detail"}, static_cast(*detail), s); - } else { - LogDNAFSM2.report(logvisor::Fatal, FMT_STRING("Invalid FSM2 version '{}'"), header.version); - return; - } -} - -AT_SPECIALIZE_DNA(FSM2) -AT_SPECIALIZE_DNA(FSM2) - -template <> -std::string_view FSM2::DNAType() { - return "FSM2"sv; -} - -template <> -std::string_view FSM2::DNAType() { - return "FSM2"sv; -} - -template struct FSM2; -template struct FSM2; - -template -bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - FSM2 fsm2; - fsm2.read(rs); - athena::io::ToYAMLStream(fsm2, writer); - return true; - } - return false; -} -template bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - fsm2.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath); -template bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFSM2 diff --git a/DataSpec/DNACommon/FSM2.hpp b/DataSpec/DNACommon/FSM2.hpp deleted file mode 100644 index 163e22243..000000000 --- a/DataSpec/DNACommon/FSM2.hpp +++ /dev/null @@ -1,147 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAFSM2 { -struct IFSM : BigDNAVYaml { - Delete _d; -}; - -template -struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) FSM2 : BigDNA { - struct Header : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC magic = FOURCC('FSM2'); - Value version; - } header; - - struct CommonStruct : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown; - }; - - struct FSMV1 : IFSM { - AT_DECL_DNA_YAMLV - Value stateCount; - Value unknown1Count; - Value unknown2Count; - Value unknown3Count; - struct State : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknownCount; - Vector unknown; - }; - - struct Unknown1 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2Count; - Vector unknown2; - Value unknown3; - }; - - struct Unknown2 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknownCount; - Vector unknown; - }; - - struct Unknown3 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknownCount; - Vector unknown; - Value fsmId; - }; - - Vector states; - Vector unknown1; - Vector unknown2; - Vector unknown3; - }; - - struct FSMV2 : IFSM { - AT_DECL_DNA_YAMLV - Value stateCount; - Value unknown1Count; - Value unknown2Count; - Value unknown3Count; - struct State : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5Count; - Vector unknown5; - }; - - struct Unknown1 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6Count; - Vector unknown6; - Value unknown7; - }; - - struct Unknown2 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5Count; - Vector unknown5; - }; - - struct Unknown3 : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5Count; - Vector unknown5; - Value fsmId; - }; - - Vector states; - Vector unknown1; - Vector unknown2; - Vector unknown3; - }; - - std::unique_ptr detail; - AT_DECL_EXPLICIT_DNA_YAML -}; - -template -bool ExtractFSM2(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template -bool WriteFSM2(const FSM2& fsm2, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAFSM2 diff --git a/DataSpec/DNACommon/GX.cpp b/DataSpec/DNACommon/GX.cpp deleted file mode 100644 index 88a3809ab..000000000 --- a/DataSpec/DNACommon/GX.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "GX.hpp" - -namespace GX { - -template <> -void Color::Enumerate::Read>(Read::StreamT& reader) { - reader.readUBytesToBuf(&num, 4); -} -template <> -void Color::Enumerate::Write>(Write::StreamT& writer) { - writer.writeUBytes(reinterpret_cast(&num), 4); -} -template <> -void Color::Enumerate::BinarySize>(BinarySize::StreamT& s) { - s += 4; -} - -} // namespace GX \ No newline at end of file diff --git a/DataSpec/DNACommon/GX.hpp b/DataSpec/DNACommon/GX.hpp deleted file mode 100644 index dc56be6ed..000000000 --- a/DataSpec/DNACommon/GX.hpp +++ /dev/null @@ -1,298 +0,0 @@ -#pragma once - -#include - -#include - -namespace GX { -enum AttrType { NONE, DIRECT, INDEX8, INDEX16 }; - -enum TevColorArg { - CC_CPREV = 0, - CC_APREV = 1, - CC_C0 = 2, - CC_A0 = 3, - CC_C1 = 4, - CC_A1 = 5, - CC_C2 = 6, - CC_A2 = 7, - CC_TEXC = 8, - CC_TEXA = 9, - CC_RASC = 10, - CC_RASA = 11, - CC_ONE = 12, - CC_HALF = 13, - CC_KONST = 14, - CC_ZERO = 15, -}; - -enum TevAlphaArg { - CA_APREV = 0, - CA_A0 = 1, - CA_A1 = 2, - CA_A2 = 3, - CA_TEXA = 4, - CA_RASA = 5, - CA_KONST = 6, - CA_ZERO = 7, -}; - -enum TevKColorSel { - TEV_KCSEL_8_8 = 0x00, - TEV_KCSEL_7_8 = 0x01, - TEV_KCSEL_6_8 = 0x02, - TEV_KCSEL_5_8 = 0x03, - TEV_KCSEL_4_8 = 0x04, - TEV_KCSEL_3_8 = 0x05, - TEV_KCSEL_2_8 = 0x06, - TEV_KCSEL_1_8 = 0x07, - - TEV_KCSEL_1 = TEV_KCSEL_8_8, - TEV_KCSEL_3_4 = TEV_KCSEL_6_8, - TEV_KCSEL_1_2 = TEV_KCSEL_4_8, - TEV_KCSEL_1_4 = TEV_KCSEL_2_8, - - TEV_KCSEL_K0 = 0x0C, - TEV_KCSEL_K1 = 0x0D, - TEV_KCSEL_K2 = 0x0E, - TEV_KCSEL_K3 = 0x0F, - TEV_KCSEL_K0_R = 0x10, - TEV_KCSEL_K1_R = 0x11, - TEV_KCSEL_K2_R = 0x12, - TEV_KCSEL_K3_R = 0x13, - TEV_KCSEL_K0_G = 0x14, - TEV_KCSEL_K1_G = 0x15, - TEV_KCSEL_K2_G = 0x16, - TEV_KCSEL_K3_G = 0x17, - TEV_KCSEL_K0_B = 0x18, - TEV_KCSEL_K1_B = 0x19, - TEV_KCSEL_K2_B = 0x1A, - TEV_KCSEL_K3_B = 0x1B, - TEV_KCSEL_K0_A = 0x1C, - TEV_KCSEL_K1_A = 0x1D, - TEV_KCSEL_K2_A = 0x1E, - TEV_KCSEL_K3_A = 0x1F -}; - -enum TevKAlphaSel { - TEV_KASEL_8_8 = 0x00, - TEV_KASEL_7_8 = 0x01, - TEV_KASEL_6_8 = 0x02, - TEV_KASEL_5_8 = 0x03, - TEV_KASEL_4_8 = 0x04, - TEV_KASEL_3_8 = 0x05, - TEV_KASEL_2_8 = 0x06, - TEV_KASEL_1_8 = 0x07, - - TEV_KASEL_1 = TEV_KASEL_8_8, - TEV_KASEL_3_4 = TEV_KASEL_6_8, - TEV_KASEL_1_2 = TEV_KASEL_4_8, - TEV_KASEL_1_4 = TEV_KASEL_2_8, - - TEV_KASEL_K0_R = 0x10, - TEV_KASEL_K1_R = 0x11, - TEV_KASEL_K2_R = 0x12, - TEV_KASEL_K3_R = 0x13, - TEV_KASEL_K0_G = 0x14, - TEV_KASEL_K1_G = 0x15, - TEV_KASEL_K2_G = 0x16, - TEV_KASEL_K3_G = 0x17, - TEV_KASEL_K0_B = 0x18, - TEV_KASEL_K1_B = 0x19, - TEV_KASEL_K2_B = 0x1A, - TEV_KASEL_K3_B = 0x1B, - TEV_KASEL_K0_A = 0x1C, - TEV_KASEL_K1_A = 0x1D, - TEV_KASEL_K2_A = 0x1E, - TEV_KASEL_K3_A = 0x1F -}; - -enum TevOp { - TEV_ADD = 0, - TEV_SUB = 1, - TEV_COMP_R8_GT = 8, - TEV_COMP_R8_EQ = 9, - TEV_COMP_GR16_GT = 10, - TEV_COMP_GR16_EQ = 11, - TEV_COMP_BGR24_GT = 12, - TEV_COMP_BGR24_EQ = 13, - TEV_COMP_RGB8_GT = 14, - TEV_COMP_RGB8_EQ = 15, - TEV_COMP_A8_GT = TEV_COMP_RGB8_GT, - TEV_COMP_A8_EQ = TEV_COMP_RGB8_EQ -}; - -enum TevBias { - TB_ZERO = 0, - TB_ADDHALF = 1, - TB_SUBHALF = 2, -}; - -enum TevScale { CS_SCALE_1 = 0, CS_SCALE_2 = 1, CS_SCALE_4 = 2, CS_DIVIDE_2 = 3 }; - -enum TexGenType { - TG_MTX3x4 = 0, - TG_MTX2x4, - TG_BUMP0, - TG_BUMP1, - TG_BUMP2, - TG_BUMP3, - TG_BUMP4, - TG_BUMP5, - TG_BUMP6, - TG_BUMP7, - TG_SRTG -}; - -enum TexGenSrc { - TG_POS = 0, - TG_NRM, - TG_BINRM, - TG_TANGENT, - TG_TEX0, - TG_TEX1, - TG_TEX2, - TG_TEX3, - TG_TEX4, - TG_TEX5, - TG_TEX6, - TG_TEX7, - TG_TEXCOORD0, - TG_TEXCOORD1, - TG_TEXCOORD2, - TG_TEXCOORD3, - TG_TEXCOORD4, - TG_TEXCOORD5, - TG_TEXCOORD6, - TG_COLOR0, - TG_COLOR1 -}; - -enum TexMtx { - TEXMTX0 = 30, - TEXMTX1 = 33, - TEXMTX2 = 36, - TEXMTX3 = 39, - TEXMTX4 = 42, - TEXMTX5 = 45, - TEXMTX6 = 48, - TEXMTX7 = 51, - TEXMTX8 = 54, - TEXMTX9 = 57, - IDENTITY = 60 -}; - -enum PTTexMtx { - PTTEXMTX0 = 64, - PTTEXMTX1 = 67, - PTTEXMTX2 = 70, - PTTEXMTX3 = 73, - PTTEXMTX4 = 76, - PTTEXMTX5 = 79, - PTTEXMTX6 = 82, - PTTEXMTX7 = 85, - PTTEXMTX8 = 88, - PTTEXMTX9 = 91, - PTTEXMTX10 = 94, - PTTEXMTX11 = 97, - PTTEXMTX12 = 100, - PTTEXMTX13 = 103, - PTTEXMTX14 = 106, - PTTEXMTX15 = 109, - PTTEXMTX16 = 112, - PTTEXMTX17 = 115, - PTTEXMTX18 = 118, - PTTEXMTX19 = 121, - PTIDENTITY = 125 -}; - -enum TevRegID { TEVPREV = 0, TEVREG0 = 1, TEVREG1 = 2, TEVREG2 = 3, TEVLAZY = 5 }; - -enum DiffuseFn { DF_NONE = 0, DF_SIGN, DF_CLAMP }; - -enum AttnFn { AF_SPEC = 0, AF_SPOT = 1, AF_NONE }; - -enum Primitive { - POINTS = 0xb8, - LINES = 0xa8, - LINESTRIP = 0xb0, - TRIANGLES = 0x90, - TRIANGLESTRIP = 0x98, - TRIANGLEFAN = 0xa0, - QUADS = 0x80 -}; - -enum ChannelID { - GX_COLOR0, - GX_COLOR1, - GX_ALPHA0, - GX_ALPHA1, - GX_COLOR0A0, - GX_COLOR1A1, - GX_COLOR_ZERO, - GX_ALPHA_BUMP, - GX_ALPHA_BUMPN, - GX_COLOR_NULL = 0xff -}; - -enum BlendFactor : uint16_t { - BL_ZERO, - BL_ONE, - BL_SRCCLR, - BL_INVSRCCLR, - BL_SRCALPHA, - BL_INVSRCALPHA, - BL_DSTALPHA, - BL_INVDSTALPHA -}; - -struct Color : athena::io::DNA { - union { - uint8_t color[4]; - uint32_t num = 0; - }; - Color() = default; - Color& operator=(const atVec4f& vec) { - athena::simd_floats f(vec.simd); - color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f)); - color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f)); - color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f)); - color[3] = uint8_t(std::min(std::max(f[3] * 255.f, 0.f), 255.f)); - return *this; - } - Color& operator=(const atVec3f& vec) { - athena::simd_floats f(vec.simd); - color[0] = uint8_t(std::min(std::max(f[0] * 255.f, 0.f), 255.f)); - color[1] = uint8_t(std::min(std::max(f[1] * 255.f, 0.f), 255.f)); - color[2] = uint8_t(std::min(std::max(f[2] * 255.f, 0.f), 255.f)); - color[3] = 0xff; - return *this; - } - Color& operator=(uint8_t val) { - color[0] = val; - color[1] = val; - color[2] = val; - color[3] = val; - return *this; - } - atVec4f toVec4f() const { - atVec4f out; - athena::simd_floats f; - f[0] = color[0] / 255.f; - f[1] = color[1] / 255.f; - f[2] = color[2] / 255.f; - f[3] = color[3] / 255.f; - out.simd.copy_from(f); - return out; - } - Color(const atVec4f& vec) { *this = vec; } - Color(const atVec3f& vec) { *this = vec; } - Color(uint8_t val) { *this = val; } - bool operator==(const Color& other) const { return num == other.num; } - bool operator!=(const Color& other) const { return num != other.num; } - uint8_t operator[](size_t idx) const { return color[idx]; } - uint8_t& operator[](size_t idx) { return color[idx]; } - AT_DECL_EXPLICIT_DNA -}; - -} // namespace GX diff --git a/DataSpec/DNACommon/MAPA.cpp b/DataSpec/DNACommon/MAPA.cpp deleted file mode 100644 index 8a14db344..000000000 --- a/DataSpec/DNACommon/MAPA.cpp +++ /dev/null @@ -1,426 +0,0 @@ -#include "DataSpec/DNACommon/MAPA.hpp" - -#include "DataSpec/DNACommon/GX.hpp" -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" -#include "DataSpec/DNAMP1/MAPA.hpp" -#include "DataSpec/DNAMP2/MAPA.hpp" -#include "DataSpec/DNAMP3/MAPA.hpp" - -#include -#include -#include - -namespace DataSpec::DNAMAPA { - -static logvisor::Module Log("DNAMAPA"); - -template <> -void MAPA::Enumerate(typename Read::StreamT& __dna_reader) { - /* magic */ - magic = __dna_reader.readUint32Big(); - if (magic != 0xDEADD00D) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid MAPA magic")); - return; - } - /* version */ - version = __dna_reader.readUint32Big(); - if (version == 2) - header = std::make_unique(); - else if (version == 3) - header = std::make_unique(); - else if (version == 5) - header = std::make_unique(); - else { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid MAPA version")); - return; - } - - header->read(__dna_reader); - - for (atUint32 i = 0; i < header->mappableObjectCount(); i++) { - std::unique_ptr mo = nullptr; - if (version != 5) { - mo = std::make_unique(); - } else { - mo = std::make_unique(); - } - mo->read(__dna_reader); - mappableObjects.push_back(std::move(mo)); - } - - /* vertices */ - __dna_reader.enumerateBig(vertices, header->vertexCount()); - /* surfaceHeaders */ - __dna_reader.enumerate(surfaceHeaders, header->surfaceCount()); - /* surfaces */ - __dna_reader.enumerate(surfaces, header->surfaceCount()); -} - -template <> -void MAPA::Enumerate(typename Write::StreamT& __dna_writer) { - /* magic */ - __dna_writer.writeUint32Big(magic); - /* version */ - __dna_writer.writeUint32Big(version); - header->write(__dna_writer); - - /* mappableObjects */ - for (const std::unique_ptr& mo : mappableObjects) - mo->write(__dna_writer); - /* vertices */ - __dna_writer.enumerateBig(vertices); - /* surfaceHeaders */ - __dna_writer.enumerate(surfaceHeaders); - /* surfaces */ - __dna_writer.enumerate(surfaces); -} - -template <> -void MAPA::Enumerate(typename BinarySize::StreamT& s) { - header->binarySize(s); - - for (const std::unique_ptr& mo : mappableObjects) - mo->binarySize(s); - - s += vertices.size() * 12; - for (const SurfaceHeader& sh : surfaceHeaders) - sh.binarySize(s); - for (const Surface& su : surfaces) - su.binarySize(s); - s += 8; -} - -static const char* RetroMapVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER"}; - -static const char* RetroMapObjVisModes[] = {"ALWAYS", "MAPSTATIONORVISIT", "VISIT", "NEVER", "MAPSTATIONORVISIT2"}; - -template -bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force) { - if (!force && outPath.isFile()) - return true; - - if (!conn.createBlend(outPath, hecl::blender::BlendType::MapArea)) - return false; - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os << "import bpy, bmesh\n" - "from mathutils import Matrix\n" - "\n" - "bpy.types.Object.retro_mappable_type = bpy.props.IntProperty(name='Retro: MAPA object type', default=-1)\n" - "bpy.types.Object.retro_mappable_sclyid = bpy.props.StringProperty(name='Retro: MAPA object SCLY ID')\n" - "bpy.types.Scene.retro_map_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', 0)," - "('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1)," - "('VISIT', 'Visit', 'Visible after Visit', 2)," - "('NEVER', 'Never', 'Never Visible', 3)]," - "name='Retro: Map Visibility Mode')\n" - "bpy.types.Object.retro_mapobj_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', " - "0)," - "('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1)," - "('VISIT', 'Visit', 'Visible after Door Visit', 2)," - "('NEVER', 'Never', 'Never Visible', 3)," - "('MAPSTATIONORVISIT2', 'Map Station or Visit 2', 'Visible after Map Station or Visit', 4)]," - "name='Retro: Map Object Visibility Mode')\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "def add_triangle(bm, verts):\n" - " verts = [bm.verts[vi] for vi in verts]\n" - " face = bm.faces.get(verts)\n" - " if face:\n" - " face = face.copy()\n" - " bm.verts.ensure_lookup_table()\n" - " face.normal_flip()\n" - " else:\n" - " bm.faces.new(verts)\n" - "\n" - "def add_border(bm, verts):\n" - " verts = [bm.verts[vi] for vi in verts]\n" - " edge = bm.edges.get(verts)\n" - " if not edge:\n" - " edge = bm.edges.new(verts)\n" - " edge.seam = True\n" - "\n"; - - os.format(FMT_STRING("bpy.context.scene.name = 'MAPA_{}'\n" - "bpy.context.scene.retro_map_vis_mode = '{}'\n"), - entry.id, RetroMapVisModes[mapa.header->visMode()]); - - /* Add empties representing MappableObjects */ - int moIdx = 0; - for (const std::unique_ptr& mo : mapa.mappableObjects) { - if (mapa.version < 5) { - const MAPA::MappableObjectMP1_2* moMP12 = static_cast(mo.get()); - zeus::simd_floats mtxF[3]; - for (int i = 0; i < 3; ++i) - moMP12->transformMtx[i].simd.copy_to(mtxF[i]); - os.format(FMT_STRING("obj = bpy.data.objects.new('MAPOBJ_{:02d}', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.retro_mappable_type = {}\n" - "obj.retro_mapobj_vis_mode = '{}'\n" - "obj.retro_mappable_sclyid = '0x{:08X}'\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n"), - moIdx, int(moMP12->type), RetroMapObjVisModes[moMP12->visMode], moMP12->sclyId, mtxF[0][0], mtxF[0][1], - mtxF[0][2], mtxF[0][3], mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3], mtxF[2][0], mtxF[2][1], - mtxF[2][2], mtxF[2][3]); - ++moIdx; - continue; - } else { - const MAPA::MappableObjectMP3* moMP3 = static_cast(mo.get()); - zeus::simd_floats mtxF[3]; - for (int i = 0; i < 3; ++i) - moMP3->transformMtx[i].simd.copy_to(mtxF[i]); - os.format(FMT_STRING("obj = bpy.data.objects.new('MAPOBJ_{:02d}', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.retro_mappable_type = {}\n" - "obj.retro_mapobj_vis_mode = '{}'\n" - "obj.retro_mappable_sclyid = '0x{:08X}'\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n"), - moIdx, int(moMP3->type), RetroMapObjVisModes[moMP3->visMode], moMP3->sclyId, mtxF[0][0], mtxF[0][1], - mtxF[0][2], mtxF[0][3], mtxF[1][0], mtxF[1][1], mtxF[1][2], mtxF[1][3], mtxF[2][0], mtxF[2][1], - mtxF[2][2], mtxF[2][3]); - ++moIdx; - continue; - } - } - - os << "# Begin bmesh\n" - "bm = bmesh.new()\n" - "\n"; - - /* Read in verts */ - for (const atVec3f& vert : mapa.vertices) { - zeus::simd_floats f(vert.simd); - os.format(FMT_STRING("bm.verts.new(({},{},{}))\n"), f[0], f[1], f[2]); - } - os << "bm.verts.ensure_lookup_table()\n"; - - /* Read in surfaces */ - for (const typename MAPA::Surface& surf : mapa.surfaces) { - for (const typename MAPA::Surface::Primitive& prim : surf.primitives) { - auto iit = prim.indices.cbegin(); - - /* 3 Prim Verts to start */ - int c = 0; - unsigned int primVerts[3] = {*iit++, *iit++, *iit++}; - - if (GX::Primitive(prim.type) == GX::TRIANGLESTRIP) { - atUint8 flip = 0; - for (size_t v = 0; v < prim.indexCount - 2; ++v) { - if (flip) { - os.format(FMT_STRING("add_triangle(bm, ({},{},{}))\n"), primVerts[c % 3], primVerts[(c + 2) % 3], - primVerts[(c + 1) % 3]); - } else { - os.format(FMT_STRING("add_triangle(bm, ({},{},{}))\n"), primVerts[c % 3], primVerts[(c + 1) % 3], - primVerts[(c + 2) % 3]); - } - flip ^= 1; - - /* Break if done */ - if (iit == prim.indices.cend()) - break; - - bool peek = (v >= prim.indexCount - 3); - - /* Advance one prim vert */ - if (peek) - primVerts[c % 3] = *iit; - else - primVerts[c % 3] = *iit++; - ++c; - } - } else if (GX::Primitive(prim.type) == GX::TRIANGLES) { - for (size_t v = 0; v < prim.indexCount; v += 3) { - os.format(FMT_STRING("add_triangle(bm, ({},{},{}))\n"), primVerts[0], primVerts[1], primVerts[2]); - - /* Break if done */ - if (v + 3 >= prim.indexCount) - break; - - /* Advance 3 Prim Verts */ - for (int pv = 0; pv < 3; ++pv) - primVerts[pv] = *iit++; - } - } - } - - for (const typename MAPA::Surface::Border& border : surf.borders) { - auto iit = border.indices.cbegin(); - for (size_t i = 0; i < border.indexCount - 1; ++i) { - os.format(FMT_STRING("add_border(bm, ({},{}))\n"), *iit, *(iit + 1)); - ++iit; - } - } - } - - os << "mesh = bpy.data.meshes.new('MAP')\n" - "obj = bpy.data.objects.new(mesh.name, mesh)\n" - "bm.to_mesh(mesh)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "bm.free()\n"; - - const zeus::CMatrix4f* tmpMtx = pakRouter.lookupMAPATransform(entry.id); - const zeus::CMatrix4f& mtx = tmpMtx ? *tmpMtx : zeus::skIdentityMatrix4f; - os.format(FMT_STRING("mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n"), - mtx[0][0], mtx[1][0], mtx[2][0], mtx[3][0], mtx[0][1], mtx[1][1], mtx[2][1], mtx[3][1], mtx[0][2], - mtx[1][2], mtx[2][2], mtx[3][2]); - - /* World background */ - hecl::ProjectPath worldDir = outPath.getParentPath().getParentPath(); - for (const auto& ent : hecl::DirectoryEnumerator(worldDir.getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!world") && - hecl::StringUtils::EndsWith(ent.m_name, ".blend")) { - os.linkBackground(fmt::format(FMT_STRING("//../{}"), ent.m_name), "World"sv); - break; - } - } - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -template bool ReadMAPAToBlender>(hecl::blender::Connection& conn, const MAPA& mapa, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template bool ReadMAPAToBlender>(hecl::blender::Connection& conn, const MAPA& mapa, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template bool ReadMAPAToBlender>(hecl::blender::Connection& conn, const MAPA& mapa, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template -bool Cook(const hecl::blender::MapArea& mapaIn, const hecl::ProjectPath& out) { - if (mapaIn.verts.size() >= 256) { - Log.report(logvisor::Error, FMT_STRING("MAPA {} vertex range exceeded [{}/{}]"), out.getRelativePath(), - mapaIn.verts.size(), 255); - return false; - } - - MAPAType mapa; - mapa.magic = 0xDEADD00D; - mapa.version = MAPAType::Version(); - - zeus::CAABox aabb; - for (const hecl::blender::Vector3f& vert : mapaIn.verts) - aabb.accumulateBounds(vert.val); - - mapa.header = std::make_unique(); - typename MAPAType::Header& header = static_cast(*mapa.header); - header.unknown1 = 0; - header.mapVisMode = mapaIn.visType; - header.boundingBox[0] = aabb.min; - header.boundingBox[1] = aabb.max; - header.moCount = mapaIn.pois.size(); - header.vtxCount = mapaIn.verts.size(); - header.surfCount = mapaIn.surfaces.size(); - - mapa.mappableObjects.reserve(mapaIn.pois.size()); - for (const hecl::blender::MapArea::POI& poi : mapaIn.pois) { - mapa.mappableObjects.push_back(std::make_unique()); - typename MAPAType::MappableObject& mobj = - static_cast(*mapa.mappableObjects.back()); - mobj.type = MAPA::IMappableObject::Type(poi.type); - mobj.visMode = poi.visMode; - mobj.sclyId = poi.objid; - mobj.transformMtx[0] = poi.xf.val[0]; - mobj.transformMtx[1] = poi.xf.val[1]; - mobj.transformMtx[2] = poi.xf.val[2]; - } - - mapa.vertices.reserve(mapaIn.verts.size()); - for (const hecl::blender::Vector3f& vert : mapaIn.verts) - mapa.vertices.push_back(vert.val); - - size_t offsetCur = 0; - for (const auto& mo : mapa.mappableObjects) - mo->binarySize(offsetCur); - offsetCur += mapa.vertices.size() * 12; - offsetCur += mapaIn.surfaces.size() * 32; - - mapa.surfaceHeaders.reserve(mapaIn.surfaces.size()); - mapa.surfaces.reserve(mapaIn.surfaces.size()); - for (const hecl::blender::MapArea::Surface& surfIn : mapaIn.surfaces) { - mapa.surfaceHeaders.emplace_back(); - DNAMAPA::MAPA::SurfaceHeader& surfHead = mapa.surfaceHeaders.back(); - mapa.surfaces.emplace_back(); - DNAMAPA::MAPA::Surface& surf = mapa.surfaces.back(); - - surf.primitiveCount = 1; - surf.primitives.emplace_back(); - DNAMAPA::MAPA::Surface::Primitive& prim = surf.primitives.back(); - prim.type = GX::TRIANGLESTRIP; - prim.indexCount = surfIn.count; - prim.indices.reserve(surfIn.count); - auto itBegin = mapaIn.indices.begin() + surfIn.start; - auto itEnd = itBegin + surfIn.count; - for (auto it = itBegin; it != itEnd; ++it) - prim.indices.push_back(*it); - - surf.borderCount = surfIn.borders.size(); - surf.borders.reserve(surfIn.borders.size()); - for (const auto& borderIn : surfIn.borders) { - surf.borders.emplace_back(); - DNAMAPA::MAPA::Surface::Border& border = surf.borders.back(); - border.indexCount = borderIn.second; - border.indices.reserve(borderIn.second); - auto it2Begin = mapaIn.indices.begin() + borderIn.first; - auto it2End = it2Begin + borderIn.second; - for (auto it = it2Begin; it != it2End; ++it) - border.indices.push_back(*it); - } - - surfHead.normal = surfIn.normal.val; - surfHead.centroid = surfIn.centerOfMass; - surfHead.polyOff = offsetCur; - offsetCur += 4; - prim.binarySize(offsetCur); - surfHead.edgeOff = offsetCur; - offsetCur += 4; - for (const auto& border : surf.borders) - border.binarySize(offsetCur); - } - - athena::io::FileWriter f(out.getAbsolutePath()); - mapa.write(f); - int64_t rem = f.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - f.writeBytes((atInt8*)"\xff", 1); - return true; -} - -template bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); -template bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); -template bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); - -} // namespace DataSpec::DNAMAPA diff --git a/DataSpec/DNACommon/MAPA.hpp b/DataSpec/DNACommon/MAPA.hpp deleted file mode 100644 index 4d3a470f4..000000000 --- a/DataSpec/DNACommon/MAPA.hpp +++ /dev/null @@ -1,177 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace hecl::blender { -class Connection; -struct MapArea; -} // namespace hecl::blender - -namespace DataSpec::DNAMAPA { -struct MAPA : BigDNA { - AT_DECL_EXPLICIT_DNA - Value magic; - Value version; - struct IMAPAHeader : BigDNAV { - Delete _d; - virtual atUint32 visMode() const = 0; - virtual atUint32 mappableObjectCount() const = 0; - virtual atUint32 vertexCount() const = 0; - virtual atUint32 surfaceCount() const = 0; - }; - - struct HeaderMP1 : IMAPAHeader { - AT_DECL_DNAV - Value unknown1 = 0; - Value mapVisMode = 0; - Value boundingBox[2] = {}; - Value moCount = 0; - Value vtxCount = 0; - Value surfCount = 0; - atUint32 visMode() const override { return mapVisMode; } - atUint32 mappableObjectCount() const override { return moCount; } - atUint32 vertexCount() const override { return vtxCount; } - atUint32 surfaceCount() const override { return surfCount; } - }; - - struct HeaderMP2 : IMAPAHeader { - AT_DECL_DNAV - Value unknown1 = 0; - Value mapVisMode = 0; - Value boundingBox[2] = {}; - Value unknown3 = 0; - Value unknown4 = 0; - Value unknown5 = 0; - Value moCount = 0; - Value vtxCount = 0; - Value surfCount = 0; - atUint32 visMode() const override { return mapVisMode; } - atUint32 mappableObjectCount() const override { return moCount; } - atUint32 vertexCount() const override { return vtxCount; } - atUint32 surfaceCount() const override { return surfCount; } - }; - - struct HeaderMP3 : IMAPAHeader { - AT_DECL_DNAV - Value unknown1 = 0; - Value mapVisMode = 0; - Value boundingBox[2] = {}; - Value unknown3 = 0; - Value unknown4 = 0; - Value unknown5 = 0; - Value unknown6 = 0; - Value moCount = 0; - Value vtxCount = 0; - Value surfCount = 0; - Value internalNameLength = 0; - Value unknown7 = 0; - String internalName; - atUint32 visMode() const override { return mapVisMode; } - atUint32 mappableObjectCount() const override { return moCount; } - atUint32 vertexCount() const override { return vtxCount; } - atUint32 surfaceCount() const override { return surfCount; } - }; - - std::unique_ptr header; - - struct IMappableObject : BigDNAV { - Delete _d; - enum class Type : atUint32 { - BlueDoor = 0, - ShieldDoor = 1, - IceDoor = 2, - WaveDoor = 3, - PlasmaDoor = 4, - BigDoor1 = 5, - BigDoor2 = 6, - IceDoorCeiling = 7, - IceDoorFloor = 8, - WaveDoorCeiling = 9, - WaveDoorFloor = 10, - IceDoorFloor2 = 13, - WaveDoorFloor2 = 14, - DownArrowYellow = 27, /* Maintenance Tunnel */ - UpArrowYellow = 28, /* Phazon Processing Center */ - DownArrowGreen = 29, /* Elevator A */ - UpArrowGreen = 30, /* Elite Control Access */ - DownArrowRed = 31, /* Elevator B */ - UpArrowRed = 32, /* Fungal Hall Access */ - TransportLift = 33, - SaveStation = 34, - MissileStation = 37 - }; - }; - - struct MappableObjectMP1_2 : IMappableObject { - AT_DECL_DNAV - Value type; - Value visMode; - Value sclyId; - Value seek1 = -1; - Value transformMtx[3]; - Value seek2[4] = {-1, -1, -1, -1}; - }; - - struct MappableObjectMP3 : IMappableObject { - AT_DECL_DNAV - Value type; - Value visMode; - Value sclyId; - Buffer unknownHash; - Value seek1 = -1; - Value transformMtx[3]; - Value seek2[4] = {-1, -1, -1, -1}; - }; - - std::vector> mappableObjects; - VectorvertexCount())> vertices; - - struct SurfaceHeader : BigDNA { - AT_DECL_DNA - Value normal; - Value centroid; - Value polyOff; - Value edgeOff; - }; - - VectorsurfaceCount())> surfaceHeaders; - - struct Surface : BigDNA { - AT_DECL_DNA - Value primitiveCount; - struct Primitive : BigDNA { - AT_DECL_DNA - Value type; - Value indexCount; - Vector indices; - Align<4> align; - }; - Vector primitives; - Value borderCount; - struct Border : BigDNA { - AT_DECL_DNA - Value indexCount; - Vector indices; - Align<4> align; - }; - Vector borders; - }; - - VectorsurfaceCount())> surfaces; -}; - -template -bool ReadMAPAToBlender(hecl::blender::Connection& conn, const MAPA& mapa, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force); - -template -bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out); - -} // namespace DataSpec::DNAMAPA diff --git a/DataSpec/DNACommon/MAPU.cpp b/DataSpec/DNACommon/MAPU.cpp deleted file mode 100644 index 04e4c029a..000000000 --- a/DataSpec/DNACommon/MAPU.cpp +++ /dev/null @@ -1,146 +0,0 @@ -#include "DataSpec/DNACommon/MAPU.hpp" - -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -#include -#include - -namespace DataSpec::DNAMAPU { - -template -bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force) { - if (!force && outPath.isFile()) - return true; - - if (!conn.createBlend(outPath, hecl::blender::BlendType::MapUniverse)) - return false; - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os << "import bpy\n" - "from mathutils import Matrix\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Object.retro_mapworld_color = bpy.props.FloatVectorProperty(name='Retro: MapWorld Color'," - " description='Sets map world color', subtype='COLOR', size=4, min=0.0, max=1.0)\n" - "bpy.types.Object.retro_mapworld_path = bpy.props.StringProperty(name='Retro: MapWorld Path'," - " description='Sets path to World root')\n" - "\n"; - - hecl::ProjectPath hexPath = pakRouter.getWorking(mapu.hexMapa); - os.linkMesh(hexPath.getAbsolutePath(), "MAP"); - os << "hexMesh = bpy.data.objects['MAP'].data\n"; - - for (const MAPU::World& wld : mapu.worlds) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(wld.mlvl); - const MAPU::Transform& wldXf = wld.transform; - zeus::simd_floats wldXfF[3]; - for (int i = 0; i < 3; ++i) - wldXf.xf[i].simd.copy_to(wldXfF[i]); - zeus::simd_floats hexColorF(wld.hexColor.mSimd); - os.format(FMT_STRING("wldObj = bpy.data.objects.new('{}', None)\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "wldObj.rotation_mode = 'QUATERNION'\n" - "wldObj.location = mtxd[0]\n" - "wldObj.rotation_quaternion = mtxd[1]\n" - "wldObj.scale = mtxd[2]\n" - "wldObj.retro_mapworld_color = ({}, {}, {}, {})\n" - "wldObj.retro_mapworld_path = '''{}'''\n" - "bpy.context.scene.collection.objects.link(wldObj)\n"), - wld.name, wldXfF[0][0], wldXfF[0][1], wldXfF[0][2], wldXfF[0][3], wldXfF[1][0], wldXfF[1][1], - wldXfF[1][2], wldXfF[1][3], wldXfF[2][0], wldXfF[2][1], wldXfF[2][2], wldXfF[2][3], hexColorF[0], - hexColorF[1], hexColorF[2], hexColorF[3], path.getParentPath().getRelativePath()); - int idx = 0; - for (const MAPU::Transform& hexXf : wld.hexTransforms) { - zeus::simd_floats hexXfF[3]; - for (int i = 0; i < 3; ++i) - hexXf.xf[i].simd.copy_to(hexXfF[i]); - os.format(FMT_STRING("obj = bpy.data.objects.new('{}_{}', hexMesh)\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = mtxd[2]\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.parent = wldObj\n"), - wld.name, idx++, hexXfF[0][0], hexXfF[0][1], hexXfF[0][2], hexXfF[0][3], hexXfF[1][0], hexXfF[1][1], - hexXfF[1][2], hexXfF[1][3], hexXfF[2][0], hexXfF[2][1], hexXfF[2][2], hexXfF[2][3]); - } - } - - os << "for screen in bpy.data.screens:\n" - " for area in screen.areas:\n" - " for space in area.spaces:\n" - " if space.type == 'VIEW_3D':\n" - " space.clip_end = 8000.0\n"; - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -template bool ReadMAPUToBlender>(hecl::blender::Connection& conn, const MAPU& mapu, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -template bool ReadMAPUToBlender>(hecl::blender::Connection& conn, const MAPU& mapu, - const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, - bool force); - -bool MAPU::Cook(const hecl::blender::MapUniverse& mapuIn, const hecl::ProjectPath& out) { - MAPU mapu; - - mapu.magic = 0xABCDEF01; - mapu.version = 1; - mapu.hexMapa = mapuIn.hexagonPath; - - mapu.worldCount = mapuIn.worlds.size(); - mapu.worlds.reserve(mapuIn.worlds.size()); - for (const hecl::blender::MapUniverse::World& wld : mapuIn.worlds) { - mapu.worlds.emplace_back(); - MAPU::World& wldOut = mapu.worlds.back(); - wldOut.name = wld.name; - for (const auto& ent : wld.worldPath.enumerateDir()) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!world") && - hecl::StringUtils::EndsWith(ent.m_name, ".blend")) { - wldOut.mlvl = hecl::ProjectPath(wld.worldPath, ent.m_name); - break; - } - } - wldOut.transform.xf[0] = wld.xf.val[0]; - wldOut.transform.xf[1] = wld.xf.val[1]; - wldOut.transform.xf[2] = wld.xf.val[2]; - wldOut.hexCount = wld.hexagons.size(); - wldOut.hexTransforms.reserve(wld.hexagons.size()); - for (const hecl::blender::Matrix4f& mtx : wld.hexagons) { - wldOut.hexTransforms.emplace_back(); - MAPU::Transform& xf = wldOut.hexTransforms.back(); - xf.xf[0] = mtx.val[0]; - xf.xf[1] = mtx.val[1]; - xf.xf[2] = mtx.val[2]; - } - wldOut.hexColor = zeus::CColor(wld.color.val); - } - - athena::io::FileWriter f(out.getAbsolutePath()); - mapu.write(f); - int64_t rem = f.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - f.writeBytes((atInt8*)"\xff", 1); - return true; -} - -} // namespace DataSpec::DNAMAPU diff --git a/DataSpec/DNACommon/MAPU.hpp b/DataSpec/DNACommon/MAPU.hpp deleted file mode 100644 index 55fe10610..000000000 --- a/DataSpec/DNACommon/MAPU.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace hecl::blender { -class Connection; -struct MapUniverse; -} // namespace hecl::blender - -namespace DataSpec::DNAMAPU { -struct MAPU : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - UniqueID32 hexMapa; - Value worldCount; - struct Transform : BigDNA { - AT_DECL_DNA - Value xf[3]; - }; - struct World : BigDNA { - AT_DECL_DNA - String<-1> name; - UniqueID32 mlvl; - Transform transform; - Value hexCount; - Vector hexTransforms; - DNAColor hexColor; - }; - Vector worlds; - - static bool Cook(const hecl::blender::MapUniverse& mapu, const hecl::ProjectPath& out); -}; - -template -bool ReadMAPUToBlender(hecl::blender::Connection& conn, const MAPU& mapu, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force); - -} // namespace DataSpec::DNAMAPU diff --git a/DataSpec/DNACommon/MLVL.cpp b/DataSpec/DNACommon/MLVL.cpp deleted file mode 100644 index 24c081147..000000000 --- a/DataSpec/DNACommon/MLVL.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "DataSpec/DNACommon/MLVL.hpp" - -#include "DataSpec/DNAMP1/MLVL.hpp" -#include "DataSpec/DNAMP2/MLVL.hpp" -#include "DataSpec/DNAMP3/MLVL.hpp" - -#include -#include - -namespace DataSpec::DNAMLVL { - -template -bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force, - std::function fileChanged) { - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - if (!force && blendPath.isFile()) - return true; - - /* Create World Blend */ - if (!conn.createBlend(blendPath, hecl::blender::BlendType::World)) - return false; - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "import bmesh\n" - "from mathutils import Matrix\n" - "\n" - "bpy.context.scene.name = 'World'\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n"; - - /* Insert area empties */ - int areaIdx = 0; - for (const auto& area : mlvl.areas) { - const typename PAKRouter::EntryType* mreaEntry = pakRouter.lookupEntry(area.areaMREAId); - - os.AABBToBMesh(area.aabb[0], area.aabb[1]); - zeus::simd_floats xfMtxF[3]; - for (int i = 0; i < 3; ++i) - area.transformMtx[i].simd.copy_to(xfMtxF[i]); - os.format(FMT_STRING("box_mesh = bpy.data.meshes.new('''{}''')\n" - "bm.to_mesh(box_mesh)\n" - "bm.free()\n" - "box = bpy.data.objects.new(box_mesh.name, box_mesh)\n" - "bpy.context.scene.collection.objects.link(box)\n" - "mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "box.rotation_mode = 'QUATERNION'\n" - "box.location = mtxd[0]\n" - "box.rotation_quaternion = mtxd[1]\n" - "box.scale = mtxd[2]\n"), - *mreaEntry->unique.m_areaName, xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], xfMtxF[0][3], xfMtxF[1][0], xfMtxF[1][1], - xfMtxF[1][2], xfMtxF[1][3], xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], xfMtxF[2][3]); - - /* Insert dock planes */ - int dockIdx = 0; - for (const auto& dock : area.docks) { - os << "bm = bmesh.new()\n"; - zeus::CVector3f pvAvg; - for (const atVec3f& pv : dock.planeVerts) - pvAvg += pv; - pvAvg /= zeus::CVector3f(dock.planeVerts.size()); - int idx = 0; - for (const atVec3f& pv : dock.planeVerts) { - const zeus::CVector3f pvRel = zeus::CVector3f(pv) - pvAvg; - os.format(FMT_STRING("bm.verts.new(({},{},{}))\n" - "bm.verts.ensure_lookup_table()\n"), - pvRel[0], pvRel[1], pvRel[2]); - if (idx) - os << "bm.edges.new((bm.verts[-2], bm.verts[-1]))\n"; - ++idx; - } - os << "bm.edges.new((bm.verts[-1], bm.verts[0]))\n"; - os.format(FMT_STRING("dockMesh = bpy.data.meshes.new('DOCK_{:02d}_{:02d}')\n"), areaIdx, dockIdx); - os << "dockObj = bpy.data.objects.new(dockMesh.name, dockMesh)\n" - "bpy.context.scene.collection.objects.link(dockObj)\n" - "bm.to_mesh(dockMesh)\n" - "bm.free()\n" - "dockObj.parent = box\n"; - os.format(FMT_STRING("dockObj.location = ({},{},{})\n"), float(pvAvg[0]), float(pvAvg[1]), float(pvAvg[2])); - ++dockIdx; - } - ++areaIdx; - } - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -template bool ReadMLVLToBlender, DNAMP1::MLVL>( - hecl::blender::Connection& conn, const DNAMP1::MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -template bool ReadMLVLToBlender, DNAMP2::MLVL>( - hecl::blender::Connection& conn, const DNAMP2::MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -template bool ReadMLVLToBlender, DNAMP3::MLVL>( - hecl::blender::Connection& conn, const DNAMP3::MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -} // namespace DataSpec::DNAMLVL diff --git a/DataSpec/DNACommon/MLVL.hpp b/DataSpec/DNACommon/MLVL.hpp deleted file mode 100644 index 452d421d1..000000000 --- a/DataSpec/DNACommon/MLVL.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace hecl::blender { -class Connection; -} - -namespace DataSpec::DNAMLVL { - -template -bool ReadMLVLToBlender(hecl::blender::Connection& conn, const MLVL& mlvl, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKRouter::EntryType& entry, bool force, - std::function fileChanged); - -} diff --git a/DataSpec/DNACommon/MayaSpline.hpp b/DataSpec/DNACommon/MayaSpline.hpp deleted file mode 100644 index 11de1f0bf..000000000 --- a/DataSpec/DNACommon/MayaSpline.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec { -struct MayaSpline : public BigDNA { - AT_DECL_DNA_YAML - Value preInf; - Value postInf; - Value knotCount; - struct Knot : BigDNA { - AT_DECL_DNA_YAML - Value time; - Value amplitude; - Value unk1; - Value unk2; - Vector unk1Floats; - Vector unk2Floats; - }; - - Vector knots; - Value clampMode; - Value minAmp; - Value maxAmp; -}; -} // namespace DataSpec \ No newline at end of file diff --git a/DataSpec/DNACommon/MetaforceVersionInfo.hpp b/DataSpec/DNACommon/MetaforceVersionInfo.hpp deleted file mode 100644 index 20505ef13..000000000 --- a/DataSpec/DNACommon/MetaforceVersionInfo.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec { -enum class ERegion { Invalid = -1, NTSC_U = 'E', PAL = 'P', NTSC_J = 'J' }; -enum class EGame { - Invalid = 0, - MetroidPrime1, - MetroidPrime2, - MetroidPrime3, -}; - -struct MetaforceVersionInfo : BigDNA { - AT_DECL_DNA_YAML - - String<-1> version; - Value region; - Value game; - Value isTrilogy; -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/OBBTreeBuilder.cpp b/DataSpec/DNACommon/OBBTreeBuilder.cpp deleted file mode 100644 index e778d4b5f..000000000 --- a/DataSpec/DNACommon/OBBTreeBuilder.cpp +++ /dev/null @@ -1,258 +0,0 @@ -#include "DataSpec/DNACommon/OBBTreeBuilder.hpp" - -#include -#include -#include - -#include "DataSpec/DNAMP1/DCLN.hpp" - -#include -#include -#include -#include - -namespace DataSpec { - -using ColMesh = hecl::blender::ColMesh; - -struct FittedOBB { - zeus::CTransform xf; - zeus::CVector3f he; -}; - -static std::vector MakeRootTriangleIndex(const ColMesh& mesh) { - std::vector ret; - ret.reserve(mesh.trianges.size()); - for (size_t i = 0; i < mesh.trianges.size(); ++i) - ret.push_back(i); - return ret; -} - -static std::unordered_set GetTriangleVerts(const ColMesh& mesh, int triIdx) { - const ColMesh::Triangle& T = mesh.trianges[triIdx]; - std::unordered_set verts; - verts.insert(mesh.edges[T.edges[0]].verts[0]); - verts.insert(mesh.edges[T.edges[0]].verts[1]); - verts.insert(mesh.edges[T.edges[1]].verts[0]); - verts.insert(mesh.edges[T.edges[1]].verts[1]); - verts.insert(mesh.edges[T.edges[2]].verts[0]); - verts.insert(mesh.edges[T.edges[2]].verts[1]); - return verts; -} - -// method to set the OBB parameters which produce a box oriented according to -// the covariance matrix C, which just containts the points pnts -static FittedOBB BuildFromCovarianceMatrix(gmm::dense_matrix& C, const ColMesh& mesh, - const std::vector& index) { - FittedOBB ret; - - // extract the eigenvalues and eigenvectors from C - gmm::dense_matrix eigvec(3, 3); - std::vector eigval(3); - using namespace gmm; - using MAT1 = gmm::dense_matrix; - gmm::symmetric_qr_algorithm(C, eigval, eigvec, default_tol_for_qr); - - // find the right, up and forward vectors from the eigenvectors - zeus::CVector3f r(eigvec(0, 0), eigvec(1, 0), eigvec(2, 0)); - zeus::CVector3f f(eigvec(0, 1), eigvec(1, 1), eigvec(2, 1)); - zeus::CVector3f u(eigvec(0, 2), eigvec(1, 2), eigvec(2, 2)); - r.normalize(); - f.normalize(); - u.normalize(); - - // set the rotation matrix using the eigvenvectors - ret.xf.basis[0] = r; - ret.xf.basis[1] = f; - ret.xf.basis[2] = u; - ret.xf.orthonormalize(); - - // now build the bounding box extents in the rotated frame - zeus::CVector3f minim(1e10f, 1e10f, 1e10f), maxim(-1e10f, -1e10f, -1e10f); - for (int triIdx : index) { - std::unordered_set verts = GetTriangleVerts(mesh, triIdx); - for (uint32_t v : verts) { - const zeus::CVector3f& p = mesh.verts[v].val; - zeus::CVector3f p_prime(ret.xf.basis[0].dot(p), ret.xf.basis[1].dot(p), ret.xf.basis[2].dot(p)); - minim = zeus::min(minim, p_prime); - maxim = zeus::max(maxim, p_prime); - } - } - - // set the center of the OBB to be the average of the - // minimum and maximum, and the extents be half of the - // difference between the minimum and maximum - zeus::CVector3f center = (maxim + minim) * 0.5f; - ret.xf.origin = ret.xf.basis * center; - ret.he = (maxim - minim) * 0.5f; - - return ret; -} - -// builds an OBB from triangles specified as an array of -// points with integer indices into the point array. Forms -// the covariance matrix for the triangles, then uses the -// method build_from_covariance_matrix() method to fit -// the box. ALL points will be fit in the box, regardless -// of whether they are indexed by a triangle or not. -static FittedOBB FitOBB(const ColMesh& mesh, const std::vector& index) { - float Ai, Am = 0.0; - zeus::CVector3f mu, mui; - gmm::dense_matrix C(3, 3); - float cxx = 0.0, cxy = 0.0, cxz = 0.0, cyy = 0.0, cyz = 0.0, czz = 0.0; - - // loop over the triangles this time to find the - // mean location - for (int i : index) { - std::unordered_set verts = GetTriangleVerts(mesh, i); - auto it = verts.begin(); - zeus::CVector3f p = mesh.verts[*it++].val; - zeus::CVector3f q = mesh.verts[*it++].val; - zeus::CVector3f r = mesh.verts[*it++].val; - mui = (p + q + r) / 3.f; - Ai = (q - p).cross(r - p).magnitude() / 2.f; - mu += mui * Ai; - Am += Ai; - - // these bits set the c terms to Am*E[xx], Am*E[xy], Am*E[xz].... - cxx += (9.0 * mui.x() * mui.x() + p.x() * p.x() + q.x() * q.x() + r.x() * r.x()) * (Ai / 12.0); - cxy += (9.0 * mui.x() * mui.y() + p.x() * p.y() + q.x() * q.y() + r.x() * r.y()) * (Ai / 12.0); - cxz += (9.0 * mui.x() * mui.z() + p.x() * p.z() + q.x() * q.z() + r.x() * r.z()) * (Ai / 12.0); - cyy += (9.0 * mui.y() * mui.y() + p.y() * p.y() + q.y() * q.y() + r.y() * r.y()) * (Ai / 12.0); - cyz += (9.0 * mui.y() * mui.z() + p.y() * p.z() + q.y() * q.z() + r.y() * r.z()) * (Ai / 12.0); - } - - if (zeus::close_enough(Am, 0.f)) - return {}; - - // divide out the Am fraction from the average position and - // covariance terms - mu = mu / Am; - cxx /= Am; - cxy /= Am; - cxz /= Am; - cyy /= Am; - cyz /= Am; - czz /= Am; - - // now subtract off the E[x]*E[x], E[x]*E[y], ... terms - cxx -= mu.x() * mu.x(); - cxy -= mu.x() * mu.y(); - cxz -= mu.x() * mu.z(); - cyy -= mu.y() * mu.y(); - cyz -= mu.y() * mu.z(); - czz -= mu.z() * mu.z(); - - // now build the covariance matrix - C(0, 0) = cxx; - C(0, 1) = cxy; - C(0, 2) = cxz; - C(1, 0) = cxy; - C(1, 1) = cyy; - C(1, 2) = cyz; - C(2, 0) = cxz; - C(2, 1) = cyz; - C(2, 2) = czz; - - // set the obb parameters from the covariance matrix - return BuildFromCovarianceMatrix(C, mesh, index); -} - -template -static void MakeLeaf(const ColMesh& mesh, const std::vector& index, Node& n) { - n.left.reset(); - n.right.reset(); - n.isLeaf = true; - n.leafData = std::make_unique(); - n.leafData->triangleIndexCount = atUint32(index.size()); - n.leafData->triangleIndices.reserve(n.leafData->triangleIndexCount); - for (int i : index) - n.leafData->triangleIndices.push_back(i); -} - -template -static std::unique_ptr RecursiveMakeNode(const ColMesh& mesh, const std::vector& index) { - // calculate root OBB - FittedOBB obb = FitOBB(mesh, index); - - // make results row-major and also invert the rotation basis - obb.xf.basis.transpose(); - - std::unique_ptr n = std::make_unique(); - for (int i = 0; i < 3; ++i) { - n->xf[i] = zeus::CVector4f{obb.xf.basis[i]}; - n->xf[i].simd[3] = float(obb.xf.origin[i]); - } - n->halfExtent = obb.he; - - // terminate branch when volume < 1.0 - if (obb.he[0] * obb.he[1] * obb.he[2] < 1.f) { - MakeLeaf(mesh, index, *n); - return n; - } - - n->isLeaf = false; - - std::vector indexNeg[3]; - std::vector indexPos[3]; - for (int c = 0; c < 3; ++c) { - // subdivide negative side - indexNeg[c].reserve(index.size()); - for (int i : index) { - std::unordered_set verts = GetTriangleVerts(mesh, i); - for (uint32_t vtx : verts) { - zeus::CVector3f v = mesh.verts[vtx].val; - v = obb.xf.basis * (v - obb.xf.origin); - if (v[c] < 0.f) { - indexNeg[c].push_back(i); - break; - } - } - } - - // subdivide positive side - indexPos[c].reserve(index.size()); - for (int i : index) { - std::unordered_set verts = GetTriangleVerts(mesh, i); - for (uint32_t vtx : verts) { - zeus::CVector3f v = mesh.verts[vtx].val; - v = obb.xf.basis * (v - obb.xf.origin); - if (v[c] >= 0.f) { - indexPos[c].push_back(i); - break; - } - } - } - } - - size_t idxMin = index.size(); - int minComp = -1; - for (int c = 0; c < 3; ++c) { - size_t test = std::max(indexNeg[c].size(), indexPos[c].size()); - if (test < idxMin && test < index.size() * 3 / 4) { - minComp = c; - idxMin = test; - } - } - - if (minComp == -1) { - MakeLeaf(mesh, index, *n); - return n; - } - - n->left = RecursiveMakeNode(mesh, indexNeg[minComp]); - n->right = RecursiveMakeNode(mesh, indexPos[minComp]); - - return n; -} - -template -std::unique_ptr OBBTreeBuilder::buildCol(const ColMesh& mesh) { - std::vector root = MakeRootTriangleIndex(mesh); - return RecursiveMakeNode(mesh, root); -} - -template std::unique_ptr -OBBTreeBuilder::buildCol(const ColMesh& mesh); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/OBBTreeBuilder.hpp b/DataSpec/DNACommon/OBBTreeBuilder.hpp deleted file mode 100644 index 45085966f..000000000 --- a/DataSpec/DNACommon/OBBTreeBuilder.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include - -#include - -namespace DataSpec { - -struct OBBTreeBuilder { - using ColMesh = hecl::blender::ColMesh; - template - static std::unique_ptr buildCol(const ColMesh& mesh); -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/PAK.cpp b/DataSpec/DNACommon/PAK.cpp deleted file mode 100644 index c8e626fed..000000000 --- a/DataSpec/DNACommon/PAK.cpp +++ /dev/null @@ -1,679 +0,0 @@ -#include "DataSpec/DNACommon/PAK.hpp" - -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -namespace DataSpec { - -template -void UniqueResult::checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry) { - UniqueResult::Type resultType = UniqueResult::Type::NotFound; - bool foundOneLayer = false; - const std::string* levelName = nullptr; - typename PAKBRIDGE::PAKType::IDType useLevelId; - typename PAKBRIDGE::PAKType::IDType useAreaId; - unsigned layerIdx = 0; - for (const auto& [levelId, level] : pakBridge.m_levelDeps) { - if (entry.id == levelId || level.resources.find(entry.id) != level.resources.end()) { - levelName = &level.name; - resultType = UniqueResult::Type::Level; - break; - } - - for (const auto& [areaId, area] : level.areas) { - unsigned l = 0; - for (const auto& layer : area.layers) { - if (layer.resources.find(entry.id) != layer.resources.end()) { - if (foundOneLayer) { - if (useAreaId == areaId) { - resultType = UniqueResult::Type::Area; - } else if (useLevelId == levelId) { - resultType = UniqueResult::Type::Level; - break; - } else { - m_type = UniqueResult::Type::Pak; - return; - } - continue; - } else - resultType = UniqueResult::Type::Layer; - levelName = &level.name; - useLevelId = levelId; - useAreaId = areaId; - layerIdx = l; - foundOneLayer = true; - } - ++l; - } - if (area.resources.find(entry.id) != area.resources.end()) { - if (foundOneLayer) { - if (useAreaId == areaId) { - resultType = UniqueResult::Type::Area; - } else if (useLevelId == levelId) { - resultType = UniqueResult::Type::Level; - break; - } else { - m_type = UniqueResult::Type::Pak; - return; - } - continue; - } else - resultType = UniqueResult::Type::Area; - levelName = &level.name; - useLevelId = levelId; - useAreaId = areaId; - foundOneLayer = true; - } - } - } - m_type = resultType; - m_levelName = levelName; - if (resultType == UniqueResult::Type::Layer || resultType == UniqueResult::Type::Area) { - const typename PAKBRIDGE::Level::Area& area = pakBridge.m_levelDeps.at(useLevelId).areas.at(useAreaId); - m_areaName = &area.name; - if (resultType == UniqueResult::Type::Layer) { - const typename PAKBRIDGE::Level::Area::Layer& layer = area.layers[layerIdx]; - m_layerName = &layer.name; - } - } -} - -template void UniqueResult::checkEntry(const DNAMP1::PAKBridge& pakBridge, - const DNAMP1::PAKBridge::PAKType::Entry& entry); -template void UniqueResult::checkEntry(const DNAMP2::PAKBridge& pakBridge, - const DNAMP2::PAKBridge::PAKType::Entry& entry); -template void UniqueResult::checkEntry(const DNAMP3::PAKBridge& pakBridge, - const DNAMP3::PAKBridge::PAKType::Entry& entry); - -hecl::ProjectPath UniqueResult::uniquePath(const hecl::ProjectPath& pakPath) const { - if (m_type == Type::Pak) - return pakPath; - - hecl::ProjectPath levelDir; - if (m_levelName) - levelDir.assign(pakPath, *m_levelName); - else - levelDir = pakPath; - - if (m_type == Type::Area) { - hecl::ProjectPath areaDir(levelDir, *m_areaName); - return areaDir; - } else if (m_type == Type::Layer) { - hecl::ProjectPath areaDir(levelDir, *m_areaName); - hecl::ProjectPath layerDir(areaDir, *m_layerName); - return layerDir; - } - - return levelDir; -} - -template -void PAKRouter::build(std::vector& bridges, std::function progress) { - m_bridges = &bridges; - m_bridgePaths.clear(); - - m_uniqueEntries.clear(); - m_sharedEntries.clear(); - m_charAssoc.m_cmdlRigs.clear(); - size_t count = 0; - float bridgesSz = bridges.size(); - - /* Route entries unique/shared per-pak */ - size_t bridgeIdx = 0; - for (BRIDGETYPE& bridge : bridges) { - const auto& name = bridge.getName(); - - std::string_view::const_iterator extit = name.end() - 4; - std::string baseName(name.begin(), extit); - - m_bridgePaths.emplace_back( - std::make_pair(hecl::ProjectPath(m_gameWorking, baseName), hecl::ProjectPath(m_gameCooked, baseName))); - - /* Index this PAK */ - bridge.build(); - - /* Add to global entry lookup */ - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - for (const auto& entry : pak.m_entries) { - if (!pak.m_noShare) { - auto sSearch = m_sharedEntries.find(entry.first); - if (sSearch != m_sharedEntries.end()) - continue; - auto uSearch = m_uniqueEntries.find(entry.first); - if (uSearch != m_uniqueEntries.end()) { - m_uniqueEntries.erase(uSearch); - m_sharedEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second); - } else - m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second); - } else - m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second); - } - - /* Add RigPairs to global map */ - bridge.addCMDLRigPairs(*this, m_charAssoc); - - progress(++count / bridgesSz); - ++bridgeIdx; - } - - /* Add named resources to catalog YAML files */ - for (BRIDGETYPE& bridge : bridges) { - athena::io::YAMLDocWriter catalogWriter; - - enterPAKBridge(bridge); - - /* Add MAPA transforms to global map */ - bridge.addMAPATransforms(*this, m_mapaTransforms, m_overrideEntries); - - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - for (const auto& namedEntry : pak.m_nameEntries) { - if (namedEntry.name == "holo_cinf") - continue; /* Problematic corner case */ - if (auto rec = catalogWriter.enterSubRecord(namedEntry.name)) { - hecl::ProjectPath working = getWorking(namedEntry.id); - if (working.getAuxInfo().size()) { - if (auto v = catalogWriter.enterSubVector()) { - catalogWriter.writeString(working.getRelativePath()); - catalogWriter.writeString(working.getAuxInfo()); - } - } else - catalogWriter.writeString(working.getRelativePath()); - } - } - - /* Write catalog */ - intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; - pakPath.makeDirChain(true); - athena::io::FileWriter writer(hecl::ProjectPath(pakPath, "!catalog.yaml").getAbsolutePath()); - catalogWriter.finish(&writer); - } -} - -template -void PAKRouter::enterPAKBridge(const BRIDGETYPE& pakBridge) { - g_PakRouter.reset(this); - auto pit = m_bridgePaths.begin(); - size_t bridgeIdx = 0; - for (const BRIDGETYPE& bridge : *m_bridges) { - if (&bridge == &pakBridge) { - m_pak.reset(&pakBridge.getPAK()); - m_node.reset(&pakBridge.getNode()); - m_curBridgeIdx.reset(reinterpret_cast(bridgeIdx)); - return; - } - ++pit; - ++bridgeIdx; - } - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKBridge provided to PAKRouter::enterPAKBridge() was not part of build()")); -} - -template -hecl::ProjectPath PAKRouter::getCharacterWorking(const EntryType* entry) const { - auto characterSearch = m_charAssoc.m_cskrToCharacter.find(entry->id); - if (characterSearch != m_charAssoc.m_cskrToCharacter.cend()) { - hecl::ProjectPath characterPath = getWorking(characterSearch->second.first); - if (entry->type == FOURCC('EVNT')) { - std::string extension(characterSearch->second.second); - return characterPath.getWithExtension((std::string(".") + extension.c_str()).c_str(), true); - } - return characterPath.ensureAuxInfo(characterSearch->second.second); - } - return {}; -} - -template -hecl::ProjectPath PAKRouter::getWorking(const EntryType* entry, - const ResExtractor& extractor) const { - if (!entry) - return hecl::ProjectPath(); - - auto overrideSearch = m_overrideEntries.find(entry->id); - if (overrideSearch != m_overrideEntries.end()) - return overrideSearch->second; - - const PAKType* pak = m_pak.get(); - intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - if (pak && pak->m_noShare) { - const EntryType* singleSearch = pak->lookupEntry(entry->id); - if (singleSearch) { - const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; - std::string entName = getBestEntryName(*entry); - std::string auxInfo; - if (extractor.fileExts[0] && !extractor.fileExts[1]) - entName += extractor.fileExts[0]; - else if (extractor.fileExts[0]) - entName += ".*"; - else if (hecl::ProjectPath chWork = getCharacterWorking(entry)) - return chWork; - return hecl::ProjectPath(pakPath, entName).ensureAuxInfo(auxInfo); - } - } - - auto uniqueSearch = m_uniqueEntries.find(entry->id); - if (uniqueSearch != m_uniqueEntries.end()) { - const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first); - const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].first; - std::string entName = getBestEntryName(*entry); - std::string auxInfo; - if (extractor.fileExts[0] && !extractor.fileExts[1]) - entName += extractor.fileExts[0]; - else if (extractor.fileExts[0]) - entName += ".*"; - else if (hecl::ProjectPath chWork = getCharacterWorking(entry)) - return chWork; - if (bridge.getPAK().m_noShare) { - return hecl::ProjectPath(pakPath, entName).ensureAuxInfo(auxInfo); - } else { - hecl::ProjectPath uniquePath = entry->unique.uniquePath(pakPath); - return hecl::ProjectPath(uniquePath, entName).ensureAuxInfo(auxInfo); - } - } - - auto sharedSearch = m_sharedEntries.find(entry->id); - if (sharedSearch != m_sharedEntries.end()) { - std::string entBase = getBestEntryName(*entry); - std::string auxInfo; - std::string entName = entBase; - if (extractor.fileExts[0] && !extractor.fileExts[1]) - entName += extractor.fileExts[0]; - else if (extractor.fileExts[0]) - entName += ".*"; - else if (hecl::ProjectPath chWork = getCharacterWorking(entry)) - return chWork; - hecl::ProjectPath sharedPath(m_sharedWorking, entName); - return sharedPath.ensureAuxInfo(auxInfo); - } - - LogDNACommon.report(logvisor::Fatal, FMT_STRING("Unable to find entry {}"), entry->id); - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getWorking(const EntryType* entry) const { - if (!entry) - return hecl::ProjectPath(); - return getWorking(entry, BRIDGETYPE::LookupExtractor(*m_node.get(), *m_pak.get(), *entry)); -} - -template -hecl::ProjectPath PAKRouter::getWorking(const IDType& id, bool silenceWarnings) const { - return getWorking(lookupEntry(id, nullptr, silenceWarnings, false)); -} - -template -hecl::ProjectPath PAKRouter::getCooked(const EntryType* entry) const { - if (!entry) - return hecl::ProjectPath(); - - auto overrideSearch = m_overrideEntries.find(entry->id); - if (overrideSearch != m_overrideEntries.end()) { - return overrideSearch->second.getCookedPath( - *m_dataSpec.overrideDataSpec(overrideSearch->second, m_dataSpec.getDataSpecEntry())); - } - - const PAKType* pak = m_pak.get(); - intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - if (pak && pak->m_noShare) { - const EntryType* singleSearch = pak->lookupEntry(entry->id); - if (singleSearch) { - const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].second; - return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); - } - } - auto uniqueSearch = m_uniqueEntries.find(entry->id); - if (uniqueSearch != m_uniqueEntries.end()) { - const BRIDGETYPE& bridge = m_bridges->at(uniqueSearch->second.first); - const hecl::ProjectPath& pakPath = m_bridgePaths[uniqueSearch->second.first].second; - if (bridge.getPAK().m_noShare) { - return hecl::ProjectPath(pakPath, getBestEntryName(*entry)); - } else { - hecl::ProjectPath uniquePath = entry->unique.uniquePath(pakPath); - return hecl::ProjectPath(uniquePath, getBestEntryName(*entry)); - } - } - auto sharedSearch = m_sharedEntries.find(entry->id); - if (sharedSearch != m_sharedEntries.end()) { - return hecl::ProjectPath(m_sharedCooked, getBestEntryName(*entry)); - } - LogDNACommon.report(logvisor::Fatal, FMT_STRING("Unable to find entry {}"), entry->id); - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getCooked(const IDType& id, bool silenceWarnings) const { - return getCooked(lookupEntry(id, nullptr, silenceWarnings, false)); -} - -template -std::string PAKRouter::getResourceRelativePath(const EntryType& a, const IDType& b) const { - const nod::Node* node = m_node.get(); - const PAKType* pak = m_pak.get(); - if (!pak) - LogDNACommon.report( - logvisor::Fatal, - FMT_STRING("PAKRouter::enterPAKBridge() must be called before PAKRouter::getResourceRelativePath()")); - const typename BRIDGETYPE::PAKType::Entry* be = lookupEntry(b); - if (!be) - return std::string(); - hecl::ProjectPath aPath = getWorking(&a, BRIDGETYPE::LookupExtractor(*node, *pak, a)); - std::string ret; - for (size_t i = 0; i < aPath.levelCount(); ++i) - ret += "../"; - hecl::ProjectPath bPath = getWorking(be, BRIDGETYPE::LookupExtractor(*node, *pak, *be)); - ret += bPath.getRelativePath(); - return ret; -} - -template -std::string PAKRouter::getBestEntryName(const EntryType& entry, bool stdOverride) const { - std::string name; - for (const BRIDGETYPE& bridge : *m_bridges) { - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - const typename BRIDGETYPE::PAKType::Entry* e = pak.lookupEntry(entry.id); - if (!e) - continue; - - if (stdOverride && !pak.m_noShare) { - if (entry.type == FOURCC('MLVL')) - return fmt::format(FMT_STRING("!world_{}"), entry.id); - else if (entry.type == FOURCC('MREA')) - return fmt::format(FMT_STRING("!area_{}"), entry.id); - else if (entry.type == FOURCC('MAPA')) - return fmt::format(FMT_STRING("!map_{}"), entry.id); - else if (entry.type == FOURCC('PATH')) - return fmt::format(FMT_STRING("!path_{}"), entry.id); - else if (entry.type == FOURCC('MAPW')) - return fmt::format(FMT_STRING("!mapw_{}"), entry.id); - else if (entry.type == FOURCC('SAVW')) - return fmt::format(FMT_STRING("!savw_{}"), entry.id); - } - - std::string catalogueName; - name = pak.bestEntryName(bridge.getNode(), entry, catalogueName); - if (!catalogueName.empty()) - return name; - } - return name; -} - -template -std::string PAKRouter::getBestEntryName(const IDType& entry, bool stdOverride) const { - std::string name; - for (const BRIDGETYPE& bridge : *m_bridges) { - const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); - const typename BRIDGETYPE::PAKType::Entry* e = pak.lookupEntry(entry); - if (!e) - continue; - - if (stdOverride && !pak.m_noShare) { - if (e->type == FOURCC('MLVL')) - return fmt::format(FMT_STRING("!world_{}"), e->id); - else if (e->type == FOURCC('MREA')) - return fmt::format(FMT_STRING("!area_{}"), e->id); - else if (e->type == FOURCC('MAPA')) - return fmt::format(FMT_STRING("!map_{}"), e->id); - else if (e->type == FOURCC('PATH')) - return fmt::format(FMT_STRING("!path_{}"), e->id); - else if (e->type == FOURCC('MAPW')) - return fmt::format(FMT_STRING("!mapw_{}"), e->id); - else if (e->type == FOURCC('SAVW')) - return fmt::format(FMT_STRING("!savw_{}"), e->id); - } - - std::string catalogueName; - name = pak.bestEntryName(bridge.getNode(), *e, catalogueName); - if (!catalogueName.empty()) - return name; - } - return name; -} - -template -bool PAKRouter::extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok, - std::function progress) { - enterPAKBridge(pakBridge); - size_t count = 0; - size_t sz = m_pak->m_entries.size(); - float fsz = sz; - for (unsigned w = 0; count < sz; ++w) { - for (const auto& item : m_pak->m_firstEntries) { - const auto* entryPtr = m_pak->lookupEntry(item); - ResExtractor extractor = BRIDGETYPE::LookupExtractor(*m_node.get(), *m_pak.get(), *entryPtr); - if (extractor.weight != w) - continue; - - std::string bestName = getBestEntryName(*entryPtr, false); - float thisFac = ++count / fsz; - progress(bestName.c_str(), thisFac); - - const nod::Node* node = m_node.get(); - - hecl::ProjectPath working = getWorking(entryPtr, extractor); - working.makeDirChain(false); - hecl::ResourceLock resLk(working); - if (!resLk) - continue; - - /* Extract to unmodified directory */ - hecl::ProjectPath cooked = working.getCookedPath(m_dataSpec.getUnmodifiedSpec()); - if (force || cooked.isNone()) { - cooked.makeDirChain(false); - PAKEntryReadStream s = entryPtr->beginReadStream(*node); - const auto fout = hecl::FopenUnique(cooked.getAbsolutePath().data(), "wb"); - std::fwrite(s.data(), 1, s.length(), fout.get()); - } - - if (extractor.func_a) /* Doesn't need PAKRouter access */ - { - if (force || !extractor.IsFullyExtracted(working)) { - PAKEntryReadStream s = entryPtr->beginReadStream(*node); - extractor.func_a(s, working); - } - } else if (extractor.func_b) /* Needs PAKRouter access */ - { - if (force || !extractor.IsFullyExtracted(working)) { - PAKEntryReadStream s = entryPtr->beginReadStream(*node); - extractor.func_b(m_dataSpec, s, working, *this, *entryPtr, force, btok, - [&progress, thisFac](const char* update) { progress(update, thisFac); }); - } - } - } - } - - return true; -} - -template -const typename BRIDGETYPE::PAKType::Entry* -PAKRouter::lookupEntry(const IDType& entry, const nod::Node** nodeOut, bool silenceWarnings, - bool currentPAK) const { - if (!entry.isValid()) - return nullptr; - - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::lookupEntry()")); - - const PAKType* pak = m_pak.get(); - const nod::Node* node = m_node.get(); - if (pak) { - const EntryType* ent = pak->lookupEntry(entry); - if (ent) { - if (nodeOut) - *nodeOut = node; - return ent; - } - } - - if (currentPAK) { -#ifndef NDEBUG - if (!silenceWarnings) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to find PAK entry {} in current PAK"), entry); -#endif - return nullptr; - } - - for (const BRIDGETYPE& bridge : *m_bridges) { - const PAKType& pak = bridge.getPAK(); - const EntryType* ent = pak.lookupEntry(entry); - if (ent) { - if (nodeOut) - *nodeOut = &bridge.getNode(); - return ent; - } - } - -#ifndef NDEBUG - if (!silenceWarnings) - LogDNACommon.report(logvisor::Warning, FMT_STRING("unable to find PAK entry {}"), entry); -#endif - if (nodeOut) - *nodeOut = nullptr; - return nullptr; -} - -template -const typename CharacterAssociations::IDType>::RigPair* -PAKRouter::lookupCMDLRigPair(const IDType& id) const { - auto search = m_charAssoc.m_cmdlRigs.find(id); - if (search == m_charAssoc.m_cmdlRigs.end()) - return nullptr; - return &search->second; -} - -template -const typename CharacterAssociations::IDType>::MultimapIteratorPair -PAKRouter::lookupCharacterAttachmentRigs(const IDType& id) const { - return m_charAssoc.m_characterToAttachmentRigs.equal_range(id); -} - -template -const zeus::CMatrix4f* PAKRouter::lookupMAPATransform(const IDType& id) const { - auto search = m_mapaTransforms.find(id); - if (search == m_mapaTransforms.end()) - return nullptr; - return &search->second; -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerWorking(const IDType& areaId, int layerIdx) const { - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->first, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - return hecl::ProjectPath(areaPath, area.second.layers.at(layerIdx).name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerWorking(const IDType& areaId, int layerIdx, - bool& activeOut) const { - activeOut = false; - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerWorking()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->first, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - const typename Level::Area::Layer& layer = area.second.layers.at(layerIdx); - activeOut = layer.active; - return hecl::ProjectPath(areaPath, layer.name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerCooked(const IDType& areaId, int layerIdx) const { - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->second, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - return hecl::ProjectPath(areaPath, area.second.layers.at(layerIdx).name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -hecl::ProjectPath PAKRouter::getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const { - activeOut = false; - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::getAreaLayerCooked()")); - auto bridgePathIt = m_bridgePaths.cbegin(); - for (const BRIDGETYPE& bridge : *m_bridges) { - for (const auto& level : bridge.m_levelDeps) - for (const auto& area : level.second.areas) - if (area.first == areaId) { - hecl::ProjectPath levelPath(bridgePathIt->second, level.second.name); - hecl::ProjectPath areaPath(levelPath, area.second.name); - if (layerIdx < 0) - return areaPath; - const typename Level::Area::Layer& layer = area.second.layers.at(layerIdx); - activeOut = layer.active; - return hecl::ProjectPath(areaPath, layer.name); - } - ++bridgePathIt; - } - return hecl::ProjectPath(); -} - -template -void PAKRouter::enumerateResources(const std::function& func) { - if (!m_bridges) - LogDNACommon.report(logvisor::Fatal, - FMT_STRING("PAKRouter::build() must be called before PAKRouter::enumerateResources()")); - for (const auto& entryPair : m_uniqueEntries) - if (!func(entryPair.second.second)) - return; - for (const auto& entryPair : m_sharedEntries) - if (!func(entryPair.second.second)) - return; -} - -template -bool PAKRouter::mreaHasDupeResources(const IDType& id) const { - const PAKType* pak = m_pak.get(); - if (!pak) - LogDNACommon.report( - logvisor::Fatal, - FMT_STRING("PAKRouter::enterPAKBridge() must be called before PAKRouter::mreaHasDupeResources()")); - return pak->mreaHasDupeResources(id); -} - -template class PAKRouter; -template class PAKRouter; -template class PAKRouter; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/PAK.hpp b/DataSpec/DNACommon/PAK.hpp deleted file mode 100644 index 56e956436..000000000 --- a/DataSpec/DNACommon/PAK.hpp +++ /dev/null @@ -1,234 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include -#include -#include - -namespace DataSpec { - -/** PAK entry stream reader */ -class PAKEntryReadStream : public athena::io::IStreamReader { - std::unique_ptr m_buf; - atUint64 m_sz = 0; - atUint64 m_pos = 0; - -public: - PAKEntryReadStream() = default; - explicit operator bool() const { return m_buf.operator bool(); } - PAKEntryReadStream(const PAKEntryReadStream& other) = delete; - PAKEntryReadStream(PAKEntryReadStream&& other) = default; - PAKEntryReadStream& operator=(const PAKEntryReadStream& other) = delete; - PAKEntryReadStream& operator=(PAKEntryReadStream&& other) = default; - PAKEntryReadStream(std::unique_ptr&& buf, atUint64 sz, atUint64 pos) - : m_buf(std::move(buf)), m_sz(sz), m_pos(pos) { - if (m_pos >= m_sz) - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAK stream cursor overrun")); - } - void seek(atInt64 pos, athena::SeekOrigin origin) override { - if (origin == athena::SeekOrigin::Begin) { - m_pos = pos; - } else if (origin == athena::SeekOrigin::Current) { - m_pos += pos; - } else if (origin == athena::SeekOrigin::End) { - m_pos = m_sz + pos; - } - if (m_pos > m_sz) { - LogDNACommon.report(logvisor::Fatal, FMT_STRING("PAK stream cursor overrun")); - } - } - atUint64 position() const override { return m_pos; } - atUint64 length() const override { return m_sz; } - const atUint8* data() const { return m_buf.get(); } - atUint64 readUBytesToBuf(void* buf, atUint64 len) override { - atUint64 bufEnd = m_pos + len; - if (bufEnd > m_sz) - len -= bufEnd - m_sz; - memmove(buf, m_buf.get() + m_pos, len); - m_pos += len; - return len; - } -}; - -struct UniqueResult { - enum class Type { NotFound, Pak, Level, Area, Layer } m_type = Type::NotFound; - const std::string* m_levelName = nullptr; - const std::string* m_areaName = nullptr; - const std::string* m_layerName = nullptr; - UniqueResult() = default; - UniqueResult(Type tp) : m_type(tp) {} - - template - void checkEntry(const PAKBRIDGE& pakBridge, const typename PAKBRIDGE::PAKType::Entry& entry); - - hecl::ProjectPath uniquePath(const hecl::ProjectPath& pakPath) const; -}; - -template -class PAKRouter; - -/** Resource extractor type */ -template -struct ResExtractor { - std::function func_a; - std::function&, - const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&, - std::function)> - func_b; - std::array fileExts = {}; - unsigned weight = 0; - std::function&, typename PAKBRIDGE::PAKType::Entry&)> - func_name; - - ResExtractor() = default; - - ResExtractor(std::function func, - std::array&& fileExtsIn, unsigned weightin = 0, - std::function&, - typename PAKBRIDGE::PAKType::Entry&)> - nfunc = {}) - : func_a(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {} - - ResExtractor(std::function&, - const typename PAKBRIDGE::PAKType::Entry&, bool, hecl::blender::Token&, - std::function)> - func, - std::array&& fileExtsIn, unsigned weightin = 0, - std::function&, - typename PAKBRIDGE::PAKType::Entry&)> - nfunc = {}) - : func_b(std::move(func)), fileExts(std::move(fileExtsIn)), weight(weightin), func_name(std::move(nfunc)) {} - - bool IsFullyExtracted(const hecl::ProjectPath& path) const { - hecl::ProjectPath::Type tp = path.getPathType(); - if (tp == hecl::ProjectPath::Type::None) - return false; - else if (tp == hecl::ProjectPath::Type::Glob) { - for (int i = 0; i < 6; ++i) { - if (!fileExts[i]) - break; - hecl::ProjectPath withExt = path.getWithExtension(fileExts[i], true); - if (withExt.isNone()) - return false; - } - } - return true; - } -}; - -/** Level hierarchy representation */ -template -struct Level { - std::string name; - struct Area { - std::string name; - struct Layer { - std::string name; - bool active; - std::unordered_set resources; - }; - std::vector layers; - std::unordered_set resources; - }; - std::unordered_map areas; - std::unordered_set resources; -}; - -/** PAKRouter (for detecting shared entry locations) */ -template -class PAKRouter : public PAKRouterBase { -public: - using PAKType = typename BRIDGETYPE::PAKType; - using IDType = typename PAKType::IDType; - using EntryType = typename PAKType::Entry; - -private: - const std::vector* m_bridges = nullptr; - std::vector> m_bridgePaths; - ThreadLocalPtr m_curBridgeIdx; - const hecl::ProjectPath& m_gameWorking; - const hecl::ProjectPath& m_gameCooked; - hecl::ProjectPath m_sharedWorking; - hecl::ProjectPath m_sharedCooked; - ThreadLocalPtr m_pak; - ThreadLocalPtr m_node; - std::unordered_map> m_uniqueEntries; - std::unordered_map> m_sharedEntries; - std::unordered_map m_overrideEntries; - CharacterAssociations m_charAssoc; - std::unordered_map m_mapaTransforms; - - hecl::ProjectPath getCharacterWorking(const EntryType* entry) const; - -public: - PAKRouter(const SpecBase& dataSpec, const hecl::ProjectPath& working, const hecl::ProjectPath& cooked) - : PAKRouterBase(dataSpec) - , m_gameWorking(working) - , m_gameCooked(cooked) - , m_sharedWorking(working, "Shared") - , m_sharedCooked(cooked, "Shared") {} - - void build(std::vector& bridges, std::function progress); - - void enterPAKBridge(const BRIDGETYPE& pakBridge); - const BRIDGETYPE& getCurrentBridge() const { return (*m_bridges)[reinterpret_cast(m_curBridgeIdx.get())]; } - - using PAKRouterBase::getWorking; - hecl::ProjectPath getWorking(const EntryType* entry, const ResExtractor& extractor) const; - hecl::ProjectPath getWorking(const EntryType* entry) const; - hecl::ProjectPath getWorking(const IDType& id, bool silenceWarnings = false) const override; - hecl::ProjectPath getCooked(const EntryType* entry) const; - hecl::ProjectPath getCooked(const IDType& id, bool silenceWarnings = false) const; - - std::string getResourceRelativePath(const EntryType& a, const IDType& b) const; - - std::string getBestEntryName(const EntryType& entry, bool stdOverride = true) const; - std::string getBestEntryName(const IDType& entry, bool stdOverride = true) const; - - bool extractResources(const BRIDGETYPE& pakBridge, bool force, hecl::blender::Token& btok, - std::function progress); - - const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const nod::Node** nodeOut = nullptr, - bool silenceWarnings = false, bool currentPAK = false) const; - - template - bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings = false) { - const nod::Node* node; - const EntryType* entry = lookupEntry(id, &node, silenceWarnings); - if (!entry) - return false; - PAKEntryReadStream rs = entry->beginReadStream(*node); - out.read(rs); - return true; - } - - PAKEntryReadStream beginReadStreamForId(const IDType& id, bool silenceWarnings = false) { - const nod::Node* node; - const EntryType* entry = lookupEntry(id, &node, silenceWarnings); - return entry->beginReadStream(*node); - } - - const typename CharacterAssociations::RigPair* lookupCMDLRigPair(const IDType& id) const; - const typename CharacterAssociations::MultimapIteratorPair - lookupCharacterAttachmentRigs(const IDType& id) const; - const zeus::CMatrix4f* lookupMAPATransform(const IDType& mapaId) const; - - hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx) const; - hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const; - hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx) const; - hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const; - - void enumerateResources(const std::function& func); - - bool mreaHasDupeResources(const IDType& id) const; -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/PART.cpp b/DataSpec/DNACommon/PART.cpp deleted file mode 100644 index 23176e42a..000000000 --- a/DataSpec/DNACommon/PART.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/PART.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_GPSM>; -template struct PPImpl<_GPSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_GPSM>) - -template <> -std::string_view GPSM::DNAType() { - return "GPSM"sv; -} - -template <> -std::string_view GPSM::DNAType() { - return "GPSM"sv; -} - -template -bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - GPSM gpsm; - gpsm.read(rs); - athena::io::ToYAMLStream(gpsm, writer); - return true; - } - return false; -} -template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - gpsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath); -template bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/PART.def b/DataSpec/DNACommon/PART.def deleted file mode 100644 index 8b932cbf3..000000000 --- a/DataSpec/DNACommon/PART.def +++ /dev/null @@ -1,141 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef VECTOR_ENTRY -#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef MOD_VECTOR_ENTRY -#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef EMITTER_ENTRY -#define EMITTER_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef UV_ENTRY -#define UV_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef KSSM_ENTRY -#define KSSM_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) -#endif - -VECTOR_ENTRY('PSIV', x0_PSIV) -MOD_VECTOR_ENTRY('PSVM', x4_PSVM) -VECTOR_ENTRY('PSOV', x8_PSOV) -INT_ENTRY('PSLT', xc_PSLT) -INT_ENTRY('PSWT', x10_PSWT) -REAL_ENTRY('PSTS', x14_PSTS) -VECTOR_ENTRY('POFS', x18_POFS) -INT_ENTRY('SEED', x1c_SEED) -REAL_ENTRY('LENG', x20_LENG) -REAL_ENTRY('WIDT', x24_WIDT) -INT_ENTRY('MAXP', x28_MAXP) -REAL_ENTRY('GRTE', x2c_GRTE) -COLOR_ENTRY('COLR', x30_COLR) -INT_ENTRY('LTME', x34_LTME) -VECTOR_ENTRY('ILOC', x38_ILOC) -VECTOR_ENTRY('IVEC', x3c_IVEC) -EMITTER_ENTRY('EMTR', x40_EMTR) -INT_ENTRY('MBSP', x48_MBSP) -REAL_ENTRY('SIZE', x4c_SIZE) -REAL_ENTRY('ROTA', x50_ROTA) -UV_ENTRY('TEXR', x54_TEXR) -UV_ENTRY('TIND', x58_TIND) -RES_ENTRY('PMDL', x5c_PMDL) -VECTOR_ENTRY('PMOP', x6c_PMOP) -VECTOR_ENTRY('PMRT', x70_PMRT) -VECTOR_ENTRY('PMSC', x74_PMSC) -COLOR_ENTRY('PMCL', x78_PMCL) -MOD_VECTOR_ENTRY('VEL1', x7c_VEL1) -MOD_VECTOR_ENTRY('VEL2', x80_VEL2) -MOD_VECTOR_ENTRY('VEL3', x84_VEL3) -MOD_VECTOR_ENTRY('VEL4', x88_VEL4) -RES_ENTRY('ICTS', x8c_ICTS) -INT_ENTRY('NCSY', x9c_NCSY) -INT_ENTRY('CSSD', xa0_CSSD) -RES_ENTRY('IDTS', xa4_IDTS) -INT_ENTRY('NDSY', xb4_NDSY) -RES_ENTRY('IITS', xb8_IITS) -INT_ENTRY('PISY', xc8_PISY) -INT_ENTRY('SISY', xcc_SISY) -KSSM_ENTRY('KSSM', xd0_KSSM) -RES_ENTRY('SSWH', xd4_SSWH) -INT_ENTRY('SSSD', xe4_SSSD) -VECTOR_ENTRY('SSPO', xe8_SSPO) -INT_ENTRY('SESD', xf8_SESD) -VECTOR_ENTRY('SEPO', xfc_SEPO) -RES_ENTRY('PMLC', xec_PMLC) -INT_ENTRY('LTYP', x100_LTYP) -COLOR_ENTRY('LCLR', x104_LCLR) -REAL_ENTRY('LINT', x108_LINT) -VECTOR_ENTRY('LOFF', x10c_LOFF) -VECTOR_ENTRY('LDIR', x110_LDIR) -INT_ENTRY('LFOT', x114_LFOT) -REAL_ENTRY('LFOR', x118_LFOR) -REAL_ENTRY('LSLA', x11c_LSLA) - -/* 0-00 additions */ -RES_ENTRY('SELC', xd8_SELC) -REAL_ENTRY('ADV1', x10c_ADV1) -REAL_ENTRY('ADV2', x110_ADV2) -REAL_ENTRY('ADV3', x114_ADV3) -REAL_ENTRY('ADV4', x118_ADV4) -REAL_ENTRY('ADV5', x11c_ADV5) -REAL_ENTRY('ADV6', x120_ADV6) -REAL_ENTRY('ADV7', x124_ADV7) -REAL_ENTRY('ADV8', x128_ADV8) - -BOOL_ENTRY('SORT', x44_28_SORT, false) -BOOL_ENTRY('MBLR', x44_30_MBLR, false) -BOOL_ENTRY('LINE', x44_24_LINE, false) -BOOL_ENTRY('LIT_', x44_29_LIT_, false) -BOOL_ENTRY('AAPH', x44_26_AAPH, false) -BOOL_ENTRY('ZBUF', x44_27_ZBUF, false) -BOOL_ENTRY('FXLL', x44_25_FXLL, false) -BOOL_ENTRY('PMAB', x44_31_PMAB, false) -BOOL_ENTRY('VMD4', x45_29_VMD4, false) -BOOL_ENTRY('VMD3', x45_28_VMD3, false) -BOOL_ENTRY('VMD2', x45_27_VMD2, false) -BOOL_ENTRY('VMD1', x45_26_VMD1, false) -BOOL_ENTRY('OPTS', x45_31_OPTS, false) -BOOL_ENTRY('PMUS', x45_24_PMUS, false) -BOOL_ENTRY('PMOO', x45_25_PMOO, true) -BOOL_ENTRY('CIND', x45_30_CIND, false) - -BOOL_ENTRY('ORNT', x30_30_ORNT, false) -BOOL_ENTRY('RSOP', x30_31_RSOP, false) - -#undef ENTRY -#undef INT_ENTRY -#undef REAL_ENTRY -#undef VECTOR_ENTRY -#undef MOD_VECTOR_ENTRY -#undef COLOR_ENTRY -#undef EMITTER_ENTRY -#undef UV_ENTRY -#undef RES_ENTRY -#undef KSSM_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/PART.hpp b/DataSpec/DNACommon/PART.hpp deleted file mode 100644 index 679f6dfe2..000000000 --- a/DataSpec/DNACommon/PART.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _GPSM { - static constexpr ParticleType Type = ParticleType::GPSM; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; -#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define EMITTER_ENTRY(name, identifier) EmitterElementFactory identifier; -#define UV_ENTRY(name, identifier) UVElementFactory identifier; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define KSSM_ENTRY(name, identifier) SpawnSystemKeyframeData identifier; -#define BOOL_ENTRY(name, identifier, def) bool identifier = def; -#include "PART.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); -#include "PART.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "PART.def" - default: - return false; - } - } -}; -template -using GPSM = PPImpl<_GPSM>; - -template -bool ExtractGPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteGPSM(const GPSM& gpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/PATH.cpp b/DataSpec/DNACommon/PATH.cpp deleted file mode 100644 index a5e330427..000000000 --- a/DataSpec/DNACommon/PATH.cpp +++ /dev/null @@ -1,248 +0,0 @@ -#include "PATH.hpp" -#include "hecl/Blender/Connection.hpp" -#include "zeus/CAABox.hpp" -#include "DataSpec/DNACommon/AROTBuilder.hpp" - -namespace DataSpec::DNAPATH { - -#define DUMP_OCTREE 0 - -#if DUMP_OCTREE -/* octree dumper */ -static void OutputOctreeNode(hecl::blender::PyOutStream& os, int idx, const zeus::CAABox& aabb) { - const zeus::CVector3f pos = aabb.center(); - const zeus::CVector3f extent = aabb.extents(); - os.format( - "obj = bpy.data.objects.new('Leaf_%d', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.location = (%f,%f,%f)\n" - "obj.scale = (%f,%f,%f)\n" - "obj.empty_display_type = 'CUBE'\n" - "obj.layers[1] = True\n" - "obj.layers[0] = False\n", - idx, pos.x(), pos.y(), pos.z(), extent.x(), extent.y(), extent.z()); -} -#endif - -template -void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, - const zeus::CMatrix4f* xf, const std::string& areaPath) { - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "import bmesh\n" - "from mathutils import Vector, Matrix\n" - "\n" - "bpy.types.Material.retro_path_idx_mask = bpy.props.IntProperty(name='Retro: Path Index Mask')\n" - "bpy.types.Material.retro_path_type_mask = bpy.props.IntProperty(name='Retro: Path Type Mask')\n" - "\n" - "material_dict = {}\n" - "material_index = []\n" - "def make_ground_material(idxMask):\n" - " mat = bpy.data.materials.new('Ground %X' % idxMask)\n" - " mat.diffuse_color = (0.8, 0.460, 0.194, 1.0)\n" - " return mat\n" - "def make_flyer_material(idxMask):\n" - " mat = bpy.data.materials.new('Flyer %X' % idxMask)\n" - " mat.diffuse_color = (0.016, 0.8, 0.8, 1.0)\n" - " return mat\n" - "def make_swimmer_material(idxMask):\n" - " mat = bpy.data.materials.new('Swimmer %X' % idxMask)\n" - " mat.diffuse_color = (0.074, 0.293, 0.8, 1.0)\n" - " return mat\n" - "def select_material(meshIdxMask, meshTypeMask):\n" - " key = (meshIdxMask, meshTypeMask)\n" - " if key in material_index:\n" - " return material_index.index(key)\n" - " elif key in material_dict:\n" - " material_index.append(key)\n" - " return len(material_index)-1\n" - " else:\n" - " if meshTypeMask == 0x2:\n" - " mat = make_flyer_material(meshIdxMask)\n" - " elif meshTypeMask == 0x4:\n" - " mat = make_swimmer_material(meshIdxMask)\n" - " else:\n" - " mat = make_ground_material(meshIdxMask)\n" - " mat.retro_path_idx_mask = meshIdxMask\n" - " mat.retro_path_type_mask = meshTypeMask\n" - " material_dict[key] = mat\n" - " material_index.append(key)\n" - " return len(material_index)-1\n" - "\n"; - os.format(FMT_STRING("bpy.context.scene.name = '{}'\n"), entryName); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bm = bmesh.new()\n" - "height_lay = bm.faces.layers.float.new('Height')\n"; - - for (const Node& n : nodes) { - zeus::simd_floats f(n.position.simd); - os.format(FMT_STRING("bm.verts.new(({},{},{}))\n"), f[0], f[1], f[2]); - } - - os << "bm.verts.ensure_lookup_table()\n"; - - for (const Region& r : regions) { - os << "tri_verts = []\n"; - for (atUint32 i = 0; i < r.nodeCount; ++i) - os.format(FMT_STRING("tri_verts.append(bm.verts[{}])\n"), r.nodeStart + i); - - os.format(FMT_STRING("face = bm.faces.get(tri_verts)\n" - "if face is None:\n" - " face = bm.faces.new(tri_verts)\n" - " face.normal_flip()\n" - "face.material_index = select_material(0x{:04X}, 0x{:04X})\n" - "face.smooth = False\n" - "face[height_lay] = {}\n" - "\n"), - r.meshIndexMask, r.meshTypeMask, r.height); - -#if 0 - const zeus::CVector3f center = xf->multiplyOneOverW(r.centroid); - zeus::CAABox aabb(xf->multiplyOneOverW(r.aabb[0]), xf->multiplyOneOverW(r.aabb[1])); - os.format(FMT_STRING("aabb = bpy.data.objects.new('AABB', None)\n") - "aabb.location = (%f,%f,%f)\n" - "aabb.scale = (%f,%f,%f)\n" - "aabb.empty_display_type = 'CUBE'\n" - "bpy.context.scene.collection.objects.link(aabb)\n" - "centr = bpy.data.objects.new('Center', None)\n" - "centr.location = (%f,%f,%f)\n" - "bpy.context.scene.collection.objects.link(centr)\n", - aabb.min[0] + (aabb.max[0] - aabb.min[0]) / 2.f, - aabb.min[1] + (aabb.max[1] - aabb.min[1]) / 2.f, - aabb.min[2] + (aabb.max[2] - aabb.min[2]) / 2.f, - (aabb.max[0] - aabb.min[0]) / 2.f, - (aabb.max[1] - aabb.min[1]) / 2.f, - (aabb.max[2] - aabb.min[2]) / 2.f, - center.x(), center.y(), center.z()); -#endif - } - -#if 0 - for (const Node& n : nodes) { - zeus::simd_floats f(n.position.simd); - zeus::simd_floats no(n.position.simd + n.normal.simd); - os.format(FMT_STRING("v = bm.verts.new((%f,%f,%f))\n") - "v2 = bm.verts.new((%f,%f,%f))\n" - "bm.edges.new((v, v2))\n", f[0], f[1], f[2], no[0], no[1], no[2]); - } -#endif - - os << "bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.001)\n" - "path_mesh = bpy.data.meshes.new('PATH')\n" - "bm.to_mesh(path_mesh)\n" - "path_mesh_obj = bpy.data.objects.new(path_mesh.name, path_mesh)\n" - "\n" - "for mat_name in material_index:\n" - " mat = material_dict[mat_name]\n" - " path_mesh.materials.append(mat)\n" - "\n" - "bpy.context.scene.collection.objects.link(path_mesh_obj)\n" - "path_mesh_obj.display_type = 'SOLID'\n" - "bpy.context.scene.hecl_path_obj = path_mesh_obj.name\n" - "\n"; - - if (xf) { - const zeus::CMatrix4f& w = *xf; - zeus::simd_floats xfMtxF[4]; - for (int i = 0; i < 4; ++i) - w.m[i].mSimd.copy_to(xfMtxF[i]); - os.format(FMT_STRING("mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "path_mesh_obj.rotation_mode = 'QUATERNION'\n" - "path_mesh_obj.location = mtxd[0]\n" - "path_mesh_obj.rotation_quaternion = mtxd[1]\n" - "path_mesh_obj.scale = mtxd[2]\n"), - xfMtxF[0][0], xfMtxF[1][0], xfMtxF[2][0], xfMtxF[3][0], xfMtxF[0][1], xfMtxF[1][1], xfMtxF[2][1], - xfMtxF[3][1], xfMtxF[0][2], xfMtxF[1][2], xfMtxF[2][2], xfMtxF[3][2]); - } - -#if DUMP_OCTREE - { - int idx = 0; - for (const auto& n : octree) { - if (n.isLeaf) - OutputOctreeNode(os, idx, zeus::CAABox(n.aabb[0], n.aabb[1])); - ++idx; - } - } -#endif - - os.linkBackground(fmt::format(FMT_STRING("//{}"), areaPath)); - os.centerView(); - os.close(); -} - -template -bool PATH::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, - bool force, hecl::blender::Token& btok, - std::function fileChanged) { - PATH path; - path.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::PathMesh)) - return false; - - std::string areaPath; - for (const auto& ent : hecl::DirectoryEnumerator(outPath.getParentPath().getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!area_")) { - areaPath = ent.m_name; - break; - } - } - - const zeus::CMatrix4f* xf = pakRouter.lookupMAPATransform(entry.id); - path.sendToBlender(conn, pakRouter.getBestEntryName(entry, false), xf, areaPath); - return conn.saveBlend(); -} - -template -bool PATH::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const PathMesh& mesh, - hecl::blender::Token& btok) { - athena::io::MemoryReader r(mesh.data.data(), mesh.data.size()); - PATH path; - path.read(r); - if (!path.regions.empty()) { - AROTBuilder octreeBuilder; - octreeBuilder.buildPath(path); - } else { - path.octreeNodeCount = 1; - path.octree.emplace_back(); - OctreeNode& n = path.octree.back(); - n.isLeaf = 1; - n.aabb[0] = zeus::CVector3f{FLT_MAX, FLT_MAX, FLT_MAX}; - n.aabb[1] = zeus::CVector3f{-FLT_MAX, -FLT_MAX, -FLT_MAX}; - for (int i = 0; i < 8; ++i) - n.children[i] = 0xffffffff; - } - -#if DUMP_OCTREE - { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(inPath.getWithExtension(".octree.blend", true), hecl::blender::BlendType::PathMesh)) - return false; - - zeus::CMatrix4f xf; - path.sendToBlender(conn, "PATH"sv, &xf); - conn.saveBlend(); - } -#endif - - athena::io::FileWriter w(outPath.getAbsolutePath()); - path.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} - -template struct PATH; -template struct PATH; -template struct PATH; - -} // namespace DataSpec::DNAPATH \ No newline at end of file diff --git a/DataSpec/DNACommon/PATH.hpp b/DataSpec/DNACommon/PATH.hpp deleted file mode 100644 index 8058f9c5f..000000000 --- a/DataSpec/DNACommon/PATH.hpp +++ /dev/null @@ -1,112 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNAMP1/DNAMP1.hpp" -#include "DataSpec/DNAMP2/DNAMP2.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -namespace DataSpec::DNAPATH { -template -struct RegionPointers {}; -template <> -struct RegionPointers : BigDNA { - AT_DECL_DNA - Value regionIdxPtr; -}; -template <> -struct RegionPointers : BigDNA { - AT_DECL_DNA - Value unk0; - Value unk1; - Value unk2; - Value regionIdxPtr; -}; -template <> -struct RegionPointers : BigDNA { - AT_DECL_DNA - Value unk0; - Value unk1; - Value unk2; - Value regionIdxPtr; -}; - -template -struct AT_SPECIALIZE_PARMS(DataSpec::DNAMP1::PAKBridge, DataSpec::DNAMP2::PAKBridge, DataSpec::DNAMP3::PAKBridge) PATH -: BigDNA { - using PathMesh = hecl::blender::PathMesh; - - AT_DECL_DNA - Value version; - - struct Node : BigDNA { - AT_DECL_DNA - Value position; - Value normal; - }; - Value nodeCount; - Vector nodes; - - struct Link : BigDNA { - AT_DECL_DNA - Value nodeIdx; - Value regionIdx; - Value width2d; - Value oneOverWidth2d; - }; - Value linkCount; - Vector links; - - struct Region : BigDNA { - AT_DECL_DNA - Value nodeCount; - Value nodeStart; - Value linkCount; - Value linkStart; - Value meshIndexMask; - Value meshTypeMask; - Value height; - Value normal; - Value regionIdx; - Value centroid; - Value aabb[2]; - Value> pointers; - }; - Value regionCount; - Vector regions; - - Vector bitmap1; - Vector bitmap2; - - /* Unused in all games, removed in MP3 */ - Vector - ? 0 - : (((((regionCount * regionCount) + 31) / 32) - bitmap1.size()) * 2))> - bitmap3; - - Value octreeRegionLookupCount; - Vector octreeRegionLookup; - - struct OctreeNode : BigDNA { - AT_DECL_DNA - Value isLeaf; - Value aabb[2]; - Value centroid; - Value children[8]; - Value regionCount; - Value regionStart; - }; - Value octreeNodeCount; - Vector octree; - - void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName, const zeus::CMatrix4f* xf, - const std::string& areaPath); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const PathMesh& mesh, - hecl::blender::Token& btok); -}; -} // namespace DataSpec::DNAPATH diff --git a/DataSpec/DNACommon/ParticleCommon.cpp b/DataSpec/DNACommon/ParticleCommon.cpp deleted file mode 100644 index 79c1381ee..000000000 --- a/DataSpec/DNACommon/ParticleCommon.cpp +++ /dev/null @@ -1,586 +0,0 @@ -#include "ParticleCommon.hpp" - -namespace DataSpec::DNAParticle { -logvisor::Module LogModule("DataSpec::DNAParticle"); - -template struct PEImpl<_RealElementFactory>; -template struct PEImpl<_IntElementFactory>; -template struct PEImpl<_VectorElementFactory>; -template struct PEImpl<_ColorElementFactory>; -template struct PEImpl<_ModVectorElementFactory>; -template struct PEImpl<_EmitterElementFactory>; -template struct PEImpl<_UVElementFactory>; -template struct PEImpl<_UVElementFactory>; - -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_RealElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_IntElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_VectorElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ColorElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_ModVectorElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_EmitterElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) -AT_SUBSPECIALIZE_DNA_YAML(PEImpl<_UVElementFactory>) - -template <> -void REConstant::Enumerate(typename ReadYaml::StreamT& r) { - val = r.readFloat(); -} -template <> -void REConstant::Enumerate(typename WriteYaml::StreamT& w) { - w.writeFloat(val); -} -template <> -void REConstant::Enumerate(typename BinarySize::StreamT& s) { - s += 4; -} -template <> -void REConstant::Enumerate(typename Read::StreamT& r) { - val = r.readFloatBig(); -} -template <> -void REConstant::Enumerate(typename Write::StreamT& w) { - w.writeFloatBig(val); -} - -template <> -void IEConstant::Enumerate(typename ReadYaml::StreamT& r) { - val = r.readUint32(); -} -template <> -void IEConstant::Enumerate(typename WriteYaml::StreamT& w) { - w.writeUint32(val); -} -template <> -void IEConstant::Enumerate(typename BinarySize::StreamT& s) { - s += 4; -} -template <> -void IEConstant::Enumerate(typename Read::StreamT& r) { - val = r.readUint32Big(); -} -template <> -void IEConstant::Enumerate(typename Write::StreamT& w) { - w.writeUint32Big(val); -} - -template <> -void VEConstant::Enumerate(typename ReadYaml::StreamT& r) { - size_t elemCount; - if (auto v = r.enterSubVector(elemCount)) { - for (size_t i = 0; i < 3 && i < elemCount; ++i) { - if (auto rec = r.enterSubRecord()) - comps[i].read(r); - } - } -} -template <> -void VEConstant::Enumerate(typename WriteYaml::StreamT& w) { - if (auto v = w.enterSubVector()) - for (int i = 0; i < 3; ++i) - if (auto rec = w.enterSubRecord()) - comps[i].write(w); -} -template <> -void VEConstant::Enumerate(typename BinarySize::StreamT& s) { - comps[0].binarySize(s); - comps[1].binarySize(s); - comps[2].binarySize(s); -} -template <> -void VEConstant::Enumerate(typename Read::StreamT& r) { - comps[0].read(r); - comps[1].read(r); - comps[2].read(r); -} -template <> -void VEConstant::Enumerate(typename Write::StreamT& w) { - comps[0].write(w); - comps[1].write(w); - comps[2].write(w); -} - -template <> -void CEConstant::Enumerate(typename ReadYaml::StreamT& r) { - for (int i = 0; i < 4; ++i) - if (auto rec = r.enterSubRecord()) - comps[i].read(r); -} -template <> -void CEConstant::Enumerate(typename WriteYaml::StreamT& w) { - if (auto v = w.enterSubVector()) - for (int i = 0; i < 4; ++i) - if (auto rec = w.enterSubRecord()) - comps[i].write(w); -} -template <> -void CEConstant::Enumerate(typename BinarySize::StreamT& s) { - comps[0].binarySize(s); - comps[1].binarySize(s); - comps[2].binarySize(s); - comps[3].binarySize(s); -} -template <> -void CEConstant::Enumerate(typename Read::StreamT& r) { - comps[0].read(r); - comps[1].read(r); - comps[2].read(r); - comps[3].read(r); -} -template <> -void CEConstant::Enumerate(typename Write::StreamT& w) { - comps[0].write(w); - comps[1].write(w); - comps[2].write(w); - comps[3].write(w); -} - -template <> -void MVEConstant::Enumerate(typename ReadYaml::StreamT& r) { - for (int i = 0; i < 3; ++i) - if (auto rec = r.enterSubRecord()) - comps[i].read(r); -} -template <> -void MVEConstant::Enumerate(typename WriteYaml::StreamT& w) { - if (auto v = w.enterSubVector()) - for (int i = 0; i < 3; ++i) - if (auto rec = w.enterSubRecord()) - comps[i].write(w); -} -template <> -void MVEConstant::Enumerate(typename BinarySize::StreamT& s) { - comps[0].binarySize(s); - comps[1].binarySize(s); - comps[2].binarySize(s); -} -template <> -void MVEConstant::Enumerate(typename Read::StreamT& r) { - comps[0].read(r); - comps[1].read(r); - comps[2].read(r); -} -template <> -void MVEConstant::Enumerate(typename Write::StreamT& w) { - comps[0].write(w); - comps[1].write(w); - comps[2].write(w); -} - -template <> -void BoolHelper::Enumerate(typename ReadYaml::StreamT& r) { - value = r.readBool(); -} -template <> -void BoolHelper::Enumerate(typename WriteYaml::StreamT& w) { - w.writeBool(value); -} -template <> -void BoolHelper::Enumerate(typename BinarySize::StreamT& s) { - s += 5; -} -template <> -void BoolHelper::Enumerate(typename Read::StreamT& r) { - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - value = r.readBool(); - else - value = false; -} -template <> -void BoolHelper::Enumerate(typename Write::StreamT& w) { - w.writeBytes("CNST", 4); - w.writeBool(value); -} - -template struct ValueHelper; -template struct ValueHelper; - -AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) -AT_SUBSPECIALIZE_DNA_YAML(ValueHelper) - -template <> -void EESimpleEmitterTR::Enumerate(typename ReadYaml::StreamT& r) { - position.reset(); - velocity.reset(); - if (auto rec = r.enterSubRecord("ILOC")) - position.read(r); - if (auto rec = r.enterSubRecord("IVEC")) - velocity.read(r); -} -template <> -void EESimpleEmitterTR::Enumerate(typename WriteYaml::StreamT& w) { - if (auto rec = w.enterSubRecord("ILOC")) - position.write(w); - if (auto rec = w.enterSubRecord("IVEC")) - velocity.write(w); -} -template <> -void EESimpleEmitterTR::Enumerate(typename BinarySize::StreamT& s) { - s += 8; - position.binarySize(s); - velocity.binarySize(s); -} -template <> -void EESimpleEmitterTR::Enumerate(typename Read::StreamT& r) { - position.reset(); - velocity.reset(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('ILOC')) { - position.read(r); - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('IVEC')) - velocity.read(r); - } -} -template <> -void EESimpleEmitterTR::Enumerate(typename Write::StreamT& w) { - w.writeBytes("ILOC", 4); - position.write(w); - w.writeBytes("IVEC", 4); - velocity.write(w); -} - -template <> -std::string_view UVEConstant::DNAType() { - return "UVEConstant"sv; -} -template <> -std::string_view UVEConstant::DNAType() { - return "UVEConstant"sv; -} - -template -void UVEConstant::_read(typename ReadYaml::StreamT& r) { - tex.clear(); - if (auto rec = r.enterSubRecord("tex")) - tex.read(r); -} -template -void UVEConstant::_write(typename WriteYaml::StreamT& w) const { - if (auto rec = w.enterSubRecord("tex")) - tex.write(w); -} -template -void UVEConstant::_binarySize(typename BinarySize::StreamT& _s) const { - _s += 4; - tex.binarySize(_s); -} -template -void UVEConstant::_read(typename Read::StreamT& r) { - tex.clear(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - tex.read(r); -} -template -void UVEConstant::_write(typename Write::StreamT& w) const { - w.writeBytes("CNST", 4); - tex.write(w); -} - -AT_SUBSPECIALIZE_DNA_YAML(UVEConstant) -AT_SUBSPECIALIZE_DNA_YAML(UVEConstant) - -template struct UVEConstant; -template struct UVEConstant; - -template <> -std::string_view UVEAnimTexture::DNAType() { - return "UVEAnimTexture"sv; -} -template <> -std::string_view UVEAnimTexture::DNAType() { - return "UVEAnimTexture"sv; -} - -template -void UVEAnimTexture::_read(typename ReadYaml::StreamT& r) { - tex.clear(); - if (auto rec = r.enterSubRecord("tex")) - tex.read(r); - if (auto rec = r.enterSubRecord("tileW")) - tileW.read(r); - if (auto rec = r.enterSubRecord("tileH")) - tileH.read(r); - if (auto rec = r.enterSubRecord("strideW")) - strideW.read(r); - if (auto rec = r.enterSubRecord("strideH")) - strideH.read(r); - if (auto rec = r.enterSubRecord("cycleFrames")) - cycleFrames.read(r); - if (auto rec = r.enterSubRecord("loop")) - loop = r.readBool(); -} -template -void UVEAnimTexture::_write(typename WriteYaml::StreamT& w) const { - if (auto rec = w.enterSubRecord("tex")) - tex.write(w); - if (auto rec = w.enterSubRecord("tileW")) - tileW.write(w); - if (auto rec = w.enterSubRecord("tileH")) - tileH.write(w); - if (auto rec = w.enterSubRecord("strideW")) - strideW.write(w); - if (auto rec = w.enterSubRecord("strideH")) - strideH.write(w); - if (auto rec = w.enterSubRecord("cycleFrames")) - cycleFrames.write(w); - w.writeBool("loop", loop); -} -template -void UVEAnimTexture::_binarySize(typename BinarySize::StreamT& _s) const { - _s += 9; - tex.binarySize(_s); - tileW.binarySize(_s); - tileH.binarySize(_s); - strideW.binarySize(_s); - strideH.binarySize(_s); - cycleFrames.binarySize(_s); -} -template -void UVEAnimTexture::_read(typename Read::StreamT& r) { - tex.clear(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - tex.read(r); - tileW.read(r); - tileH.read(r); - strideW.read(r); - strideH.read(r); - cycleFrames.read(r); - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - loop = r.readBool(); -} -template -void UVEAnimTexture::_write(typename Write::StreamT& w) const { - w.writeBytes("CNST", 4); - tex.write(w); - tileW.write(w); - tileH.write(w); - strideW.write(w); - strideH.write(w); - cycleFrames.write(w); - w.writeBytes("CNST", 4); - w.writeBool(loop); -} - -AT_SUBSPECIALIZE_DNA_YAML(UVEAnimTexture) -AT_SUBSPECIALIZE_DNA_YAML(UVEAnimTexture) - -template struct UVEAnimTexture; -template struct UVEAnimTexture; - -template <> -std::string_view UVElementFactory::DNAType() { - return "UVElementFactory"sv; -} -template <> -std::string_view UVElementFactory::DNAType() { - return "UVElementFactory"sv; -} - -template <> -std::string_view SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::DNAType() { - return "SpawnSystemKeyframeData::SpawnSystemKeyframeInfo"sv; -} -template <> -std::string_view SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::DNAType() { - return "SpawnSystemKeyframeData::SpawnSystemKeyframeInfo"sv; -} - -template -template -void SpawnSystemKeyframeData::SpawnSystemKeyframeInfo::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"id"}, id, s); - Do(athena::io::PropId{"a"}, a, s); - Do(athena::io::PropId{"b"}, b, s); - Do(athena::io::PropId{"c"}, c, s); -} - -template <> -std::string_view SpawnSystemKeyframeData::DNAType() { - return "SpawnSystemKeyframeData"sv; -} -template <> -std::string_view SpawnSystemKeyframeData::DNAType() { - return "SpawnSystemKeyframeData"sv; -} - -template -void SpawnSystemKeyframeData::_read(typename ReadYaml::StreamT& r) { - if (auto rec = r.enterSubRecord("a")) - a = r.readUint32(); - if (auto rec = r.enterSubRecord("b")) - b = r.readUint32(); - if (auto rec = r.enterSubRecord("endFrame")) - endFrame = r.readUint32(); - if (auto rec = r.enterSubRecord("d")) - d = r.readUint32(); - spawns.clear(); - size_t spawnCount; - if (auto v = r.enterSubVector("spawns", spawnCount)) { - spawns.reserve(spawnCount); - for (const auto& child : r.getCurNode()->m_seqChildren) { - (void)child; - if (auto rec = r.enterSubRecord()) { - spawns.emplace_back(); - spawns.back().first = r.readUint32("startFrame"); - size_t systemCount; - if (auto v = r.enterSubVector("systems", systemCount)) { - spawns.back().second.reserve(systemCount); - for (const auto& in : r.getCurNode()->m_seqChildren) { - (void)in; - spawns.back().second.emplace_back(); - SpawnSystemKeyframeInfo& info = spawns.back().second.back(); - if (auto rec = r.enterSubRecord()) - info.read(r); - } - } - } - } - } -} - -template -void SpawnSystemKeyframeData::_write(typename WriteYaml::StreamT& w) const { - if (spawns.empty()) - return; - w.writeUint32("a", a); - w.writeUint32("b", b); - w.writeUint32("endFrame", endFrame); - w.writeUint32("d", d); - if (auto v = w.enterSubVector("spawns")) { - for (const auto& spawn : spawns) { - if (auto rec = w.enterSubRecord()) { - w.writeUint32("startFrame", spawn.first); - if (auto v = w.enterSubVector("systems")) - for (const auto& info : spawn.second) - if (auto rec = w.enterSubRecord()) - info.write(w); - } - } - } -} - -template -void SpawnSystemKeyframeData::_binarySize(typename BinarySize::StreamT& s) const { - s += 20; - for (const auto& spawn : spawns) { - s += 8; - for (const auto& info : spawn.second) - info.binarySize(s); - } -} - -template -void SpawnSystemKeyframeData::_read(typename Read::StreamT& r) { - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId != SBIG('CNST')) - return; - - a = r.readUint32Big(); - b = r.readUint32Big(); - endFrame = r.readUint32Big(); - d = r.readUint32Big(); - uint32_t count = r.readUint32Big(); - spawns.clear(); - spawns.reserve(count); - for (size_t i = 0; i < count; ++i) { - spawns.emplace_back(); - spawns.back().first = r.readUint32Big(); - uint32_t infoCount = r.readUint32Big(); - spawns.back().second.reserve(infoCount); - for (size_t j = 0; j < infoCount; ++j) { - spawns.back().second.emplace_back(); - spawns.back().second.back().read(r); - } - } -} - -template -void SpawnSystemKeyframeData::_write(typename Write::StreamT& w) const { - if (spawns.empty()) { - w.writeBytes("NONE", 4); - return; - } - w.writeBytes("CNST", 4); - w.writeUint32Big(a); - w.writeUint32Big(b); - w.writeUint32Big(endFrame); - w.writeUint32Big(d); - w.writeUint32Big(spawns.size()); - for (const auto& spawn : spawns) { - w.writeUint32Big(spawn.first); - w.writeUint32Big(spawn.second.size()); - for (const auto& info : spawn.second) - info.write(w); - } -} - -AT_SUBSPECIALIZE_DNA_YAML(SpawnSystemKeyframeData) -AT_SUBSPECIALIZE_DNA_YAML(SpawnSystemKeyframeData) - -template struct SpawnSystemKeyframeData; -template struct SpawnSystemKeyframeData; - -template <> -std::string_view ChildResourceFactory::DNAType() { - return "ChildResourceFactory"sv; -} -template <> -std::string_view ChildResourceFactory::DNAType() { - return "ChildResourceFactory"sv; -} - -template -void ChildResourceFactory::_read(typename ReadYaml::StreamT& r) { - id.clear(); - if (auto rec = r.enterSubRecord("CNST")) - id.read(r); -} - -template -void ChildResourceFactory::_write(typename WriteYaml::StreamT& w) const { - if (id.isValid()) - if (auto rec = w.enterSubRecord("CNST")) - id.write(w); -} - -template -void ChildResourceFactory::_binarySize(typename BinarySize::StreamT& s) const { - if (id.isValid()) - id.binarySize(s); - s += 4; -} - -template -void ChildResourceFactory::_read(typename Read::StreamT& r) { - id.clear(); - uint32_t clsId; - r.readBytesToBuf(&clsId, 4); - if (clsId == SBIG('CNST')) - id.read(r); -} - -template -void ChildResourceFactory::_write(typename Write::StreamT& w) const { - if (id.isValid()) { - w.writeBytes("CNST", 4); - id.write(w); - } else - w.writeBytes("NONE", 4); -} - -AT_SUBSPECIALIZE_DNA_YAML(ChildResourceFactory) -AT_SUBSPECIALIZE_DNA_YAML(ChildResourceFactory) - -template struct ChildResourceFactory; -template struct ChildResourceFactory; - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/ParticleCommon.hpp b/DataSpec/DNACommon/ParticleCommon.hpp deleted file mode 100644 index 950c52a7b..000000000 --- a/DataSpec/DNACommon/ParticleCommon.hpp +++ /dev/null @@ -1,1553 +0,0 @@ -#pragma once - -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace DataSpec::DNAParticle { -extern logvisor::Module LogModule; - -enum class ParticleType { - GPSM = SBIG('GPSM'), - SWSH = SBIG('SWSH'), - ELSM = SBIG('ELSM'), - DPSM = SBIG('DPSM'), - CRSM = SBIG('CRSM'), - WPSM = SBIG('WPSM') -}; - -/* - * The particle property (PP) metaclass system provides common compile-time utilities - * for storing, enumerating, and streaming particle scripts. - */ - -template -struct PPImpl : BigDNA, _Basis { - AT_DECL_EXPLICIT_DNA_YAML - - template - static constexpr bool _shouldStore(T& p, bool defaultBool) { - if constexpr (std::is_same_v) { - return p != defaultBool; - } else if constexpr (std::is_same_v) { - return p != 0xffffffff; - } else if constexpr (std::is_same_v) { - return true; - } else { - return p.operator bool(); - } - } - - constexpr void _read(athena::io::IStreamReader& r) { - constexpr FourCC RefType = uint32_t(_Basis::Type); - DNAFourCC clsId(r); - if (clsId != RefType) { - LogModule.report(logvisor::Warning, FMT_STRING("non {} provided to {} parser"), RefType, RefType); - return; - } - clsId.read(r); - while (clsId != SBIG('_END')) { - if (!_Basis::Lookup(clsId, [&](auto& p) { - using Tp = std::decay_t; - if constexpr (std::is_same_v) { - DNAFourCC tp(r); - if (tp == SBIG('CNST')) - p = r.readBool(); - } else if constexpr (std::is_same_v) { - DNAFourCC tp(r); - if (tp == SBIG('CNST')) - p = r.readUint32Big(); - } else if constexpr (std::is_same_v) { - DNAFourCC tp(r); - if (tp == SBIG('CNST')) - p = r.readFloatBig(); - } else { - p.read(r); - } - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {} @{}"), RefType, clsId, r.position()); - } - clsId.read(r); - } - } - - constexpr void _write(athena::io::IStreamWriter& w) { - constexpr DNAFourCC RefType = uint32_t(_Basis::Type); - RefType.write(w); - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - if (_shouldStore(p, defaultBool)) { - using Tp = std::decay_t; - DNAFourCC(fcc).write(w); - if constexpr (std::is_same_v) { - w.writeBytes("CNST", 4); - w.writeBool(p); - } else if constexpr (std::is_same_v) { - w.writeBytes("CNST", 4); - w.writeUint32Big(p); - } else if constexpr (std::is_same_v) { - w.writeBytes("CNST", 4); - w.writeFloatBig(p); - } else { - p.write(w); - } - } - }); - w.writeBytes("_END", 4); - } - - constexpr void _binarySize(std::size_t& s) { - constexpr DNAFourCC RefType = uint32_t(_Basis::Type); - RefType.binarySize(s); - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - if (_shouldStore(p, defaultBool)) { - using Tp = std::decay_t; - DNAFourCC(fcc).binarySize(s); - if constexpr (std::is_same_v) { - s += 5; - } else if constexpr (std::is_same_v || std::is_same_v) { - s += 8; - } else { - p.binarySize(s); - } - } - }); - s += 4; - } - - void _read(athena::io::YAMLDocReader& r) { - constexpr DNAFourCC RefType = uint32_t(_Basis::Type); - - for (const auto& [key, value] : r.getCurNode()->m_mapChildren) { - if (key == "DNAType"sv) - continue; - if (key.size() < 4) { - LogModule.report(logvisor::Warning, FMT_STRING("short FourCC in element '{}'"), key); - continue; - } - - if (auto rec = r.enterSubRecord(key)) { - const DNAFourCC clsId = key.c_str(); - if (!_Basis::Lookup(clsId, [&](auto& p) { - using Tp = std::decay_t; - if constexpr (std::is_same_v) { - p = r.readBool(); - } else if constexpr (std::is_same_v) { - p = r.readUint32(); - } else if constexpr (std::is_same_v) { - p = r.readFloat(); - } else { - p.read(r); - } - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {}"), RefType, clsId); - } - } - } - } - - constexpr void _write(athena::io::YAMLDocWriter& w) { - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - if (_shouldStore(p, defaultBool)) { - using Tp = std::decay_t; - if (auto rec = w.enterSubRecord(fcc.toStringView())) { - if constexpr (std::is_same_v) { - w.writeBool(p); - } else if constexpr (std::is_same_v) { - w.writeUint32(p); - } else if constexpr (std::is_same_v) { - w.writeFloat(p); - } else { - p.write(w); - } - } - } - }); - } - - constexpr void gatherDependencies(std::vector& deps) { - _Basis::Enumerate([&](FourCC fcc, auto& p, bool defaultBool = false) { - using Tp = std::decay_t; - if constexpr (!std::is_same_v && !std::is_same_v && !std::is_same_v) - p.gatherDependencies(deps); - }); - } - - constexpr void gatherDependencies(std::vector& deps) const { - const_cast(*this).gatherDependencies(deps); - } -}; - -template -struct PEType { - using Type = _Type; -}; - -template -struct PEImpl : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - using _PtrType = typename _Basis::PtrType; - - void _read(athena::io::IStreamReader& r) { - DNAFourCC clsId(r); - if (clsId == FOURCC('NONE')) { - m_elem.reset(); - return; - } - if (!_Basis::Lookup(clsId, [&](auto&& p) { - using Tp = std::decay_t; - m_elem = std::make_unique(); - m_elem->read(r); - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {} @{}"), _PtrType::TypeName, clsId, r.position()); - } - } - - void _write(athena::io::IStreamWriter& w) { - if (m_elem) { - w.writeBytes(m_elem->ClassID().data(), 4); - m_elem->write(w); - } else { - w.writeBytes("NONE", 4); - } - } - - void _binarySize(std::size_t& s) { - if (m_elem) - m_elem->binarySize(s); - s += 4; - } - - void _read(athena::io::YAMLDocReader& r) { - const auto& mapChildren = r.getCurNode()->m_mapChildren; - if (mapChildren.empty()) { - m_elem.reset(); - return; - } - - const auto& [key, value] = mapChildren[0]; - if (key.size() < 4) - LogModule.report(logvisor::Fatal, FMT_STRING("short FourCC in element '{}'"), key); - - if (auto rec = r.enterSubRecord(key)) { - const DNAFourCC clsId = key.c_str(); - if (!_Basis::Lookup(clsId, [&](auto&& p) { - using Tp = std::decay_t; - m_elem = std::make_unique(); - m_elem->read(r); - })) { - LogModule.report(logvisor::Fatal, FMT_STRING("Unknown {} class {}"), _PtrType::TypeName, clsId); - } - } - } - - void _write(athena::io::YAMLDocWriter& w) { - if (m_elem) - if (auto rec = w.enterSubRecord(m_elem->ClassID())) - m_elem->write(w); - } - - void gatherDependencies(std::vector& deps) const { _Basis::gatherDependencies(deps, m_elem); } - - explicit operator bool() const { return m_elem.operator bool(); } - auto* get() const { return m_elem.get(); } - auto* operator->() const { return get(); } - void reset() { m_elem.reset(); } - -private: - std::unique_ptr<_PtrType> m_elem; -}; - -struct IElement : BigDNAVYaml { - Delete _d; - ~IElement() override = default; - virtual std::string_view ClassID() const = 0; - std::string_view DNATypeV() const override { return ClassID(); } -}; - -struct IRealElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "RealElement"sv; -}; -struct RELifetimeTween; -struct REConstant; -struct RETimeChain; -struct REAdd; -struct REClamp; -struct REKeyframeEmitter; -struct REKeyframeEmitter; -struct REInitialRandom; -struct RERandom; -struct REMultiply; -struct REPulse; -struct RETimeScale; -struct RELifetimePercent; -struct RESineWave; -struct REInitialSwitch; -struct RECompareLessThan; -struct RECompareEquals; -struct REParticleAdvanceParam1; -struct REParticleAdvanceParam2; -struct REParticleAdvanceParam3; -struct REParticleAdvanceParam4; -struct REParticleAdvanceParam5; -struct REParticleAdvanceParam6; -struct REParticleAdvanceParam7; -struct REParticleAdvanceParam8; -struct REParticleSizeOrLineLength; -struct REParticleRotationOrLineWidth; -struct RESubtract; -struct REVectorMagnitude; -struct REVectorXToReal; -struct REVectorYToReal; -struct REVectorZToReal; -struct RECEXT; -struct REIntTimesReal; -struct _RealElementFactory { - using PtrType = IRealElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('LFTW'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('ADD_'): - f(PEType{}); - return true; - case SBIG('CLMP'): - f(PEType{}); - return true; - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('IRND'): - f(PEType{}); - return true; - case SBIG('RAND'): - f(PEType{}); - return true; - case SBIG('MULT'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('SCAL'): - f(PEType{}); - return true; - case SBIG('RLPT'): - f(PEType{}); - return true; - case SBIG('SINE'): - f(PEType{}); - return true; - case SBIG('ISWT'): - f(PEType{}); - return true; - case SBIG('CLTN'): - f(PEType{}); - return true; - case SBIG('CEQL'): - f(PEType{}); - return true; - case SBIG('PAP1'): - f(PEType{}); - return true; - case SBIG('PAP2'): - f(PEType{}); - return true; - case SBIG('PAP3'): - f(PEType{}); - return true; - case SBIG('PAP4'): - f(PEType{}); - return true; - case SBIG('PAP5'): - f(PEType{}); - return true; - case SBIG('PAP6'): - f(PEType{}); - return true; - case SBIG('PAP7'): - f(PEType{}); - return true; - case SBIG('PAP8'): - f(PEType{}); - return true; - case SBIG('PSLL'): - f(PEType{}); - return true; - case SBIG('PRLW'): - f(PEType{}); - return true; - case SBIG('SUB_'): - f(PEType{}); - return true; - case SBIG('VMAG'): - f(PEType{}); - return true; - case SBIG('VXTR'): - f(PEType{}); - return true; - case SBIG('VYTR'): - f(PEType{}); - return true; - case SBIG('VZTR'): - f(PEType{}); - return true; - case SBIG('CEXT'): - f(PEType{}); - return true; - case SBIG('ITRL'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using RealElementFactory = PEImpl<_RealElementFactory>; - -struct IIntElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "IntElement"sv; -}; -struct IEKeyframeEmitter; -struct IEKeyframeEmitter; -struct IEDeath; -struct IEClamp; -struct IETimeChain; -struct IEAdd; -struct IEConstant; -struct IEImpulse; -struct IELifetimePercent; -struct IEInitialRandom; -struct IEPulse; -struct IEMultiply; -struct IESampleAndHold; -struct IERandom; -struct IETimeScale; -struct IEGTCP; -struct IEModulo; -struct IESubtract; -struct _IntElementFactory { - using PtrType = IIntElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('DETH'): - f(PEType{}); - return true; - case SBIG('CLMP'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('ADD_'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('IMPL'): - f(PEType{}); - return true; - case SBIG('ILPT'): - f(PEType{}); - return true; - case SBIG('IRND'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('MULT'): - f(PEType{}); - return true; - case SBIG('SPAH'): - f(PEType{}); - return true; - case SBIG('RAND'): - f(PEType{}); - return true; - case SBIG('TSCL'): - f(PEType{}); - return true; - case SBIG('GTCP'): - f(PEType{}); - return true; - case SBIG('MODU'): - f(PEType{}); - return true; - case SBIG('SUB_'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using IntElementFactory = PEImpl<_IntElementFactory>; - -struct IVectorElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "VectorElement"sv; -}; -struct VECone; -struct VETimeChain; -struct VEAngleCone; -struct VEAdd; -struct VECircleCluster; -struct VEConstant; -struct VECircle; -struct VEKeyframeEmitter; -struct VEKeyframeEmitter; -struct VEMultiply; -struct VERealToVector; -struct VEPulse; -struct VEParticleVelocity; -struct VESPOS; -struct VEPLCO; -struct VEPLOC; -struct VEPSOR; -struct VEPSOF; -struct _VectorElementFactory { - using PtrType = IVectorElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('CONE'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('ANGC'): - f(PEType{}); - return true; - case SBIG('ADD_'): - f(PEType{}); - return true; - case SBIG('CCLU'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('CIRC'): - f(PEType{}); - return true; - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('MULT'): - f(PEType{}); - return true; - case SBIG('RTOV'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('PVEL'): - f(PEType{}); - return true; - case SBIG('SPOS'): - f(PEType{}); - return true; - case SBIG('PLCO'): - f(PEType{}); - return true; - case SBIG('PLOC'): - f(PEType{}); - return true; - case SBIG('PSOR'): - f(PEType{}); - return true; - case SBIG('PSOF'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using VectorElementFactory = PEImpl<_VectorElementFactory>; - -struct IColorElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "ColorElement"sv; -}; -struct CEKeyframeEmitter; -struct CEKeyframeEmitter; -struct CEConstant; -struct CETimeChain; -struct CEFadeEnd; -struct CEFade; -struct CEPulse; -struct _ColorElementFactory { - using PtrType = IColorElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('KEYE'): - f(PEType{}); - return true; - case SBIG('KEYP'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('CFDE'): - f(PEType{}); - return true; - case SBIG('FADE'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using ColorElementFactory = PEImpl<_ColorElementFactory>; - -struct IModVectorElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "ModVectorElement"sv; -}; -struct MVEImplosion; -struct MVEExponentialImplosion; -struct MVETimeChain; -struct MVEBounce; -struct MVEConstant; -struct MVEGravity; -struct MVEExplode; -struct MVESetPosition; -struct MVELinearImplosion; -struct MVEPulse; -struct MVEWind; -struct MVESwirl; -struct _ModVectorElementFactory { - using PtrType = IModVectorElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('IMPL'): - f(PEType{}); - return true; - case SBIG('EMPL'): - f(PEType{}); - return true; - case SBIG('CHAN'): - f(PEType{}); - return true; - case SBIG('BNCE'): - f(PEType{}); - return true; - case SBIG('CNST'): - f(PEType{}); - return true; - case SBIG('GRAV'): - f(PEType{}); - return true; - case SBIG('EXPL'): - f(PEType{}); - return true; - case SBIG('SPOS'): - f(PEType{}); - return true; - case SBIG('LMPL'): - f(PEType{}); - return true; - case SBIG('PULS'): - f(PEType{}); - return true; - case SBIG('WIND'): - f(PEType{}); - return true; - case SBIG('SWRL'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using ModVectorElementFactory = PEImpl<_ModVectorElementFactory>; - -struct IEmitterElement : IElement { - Delete _d2; - static constexpr std::string_view TypeName = "EmitterElement"sv; -}; -struct EESimpleEmitterTR; -struct EESimpleEmitter; -struct VESphere; -struct VEAngleSphere; -struct _EmitterElementFactory { - using PtrType = IEmitterElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('SETR'): - f(PEType{}); - return true; - case SBIG('SEMR'): - f(PEType{}); - return true; - case SBIG('SPHE'): - f(PEType{}); - return true; - case SBIG('ASPH'): - f(PEType{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) {} -}; -using EmitterElementFactory = PEImpl<_EmitterElementFactory>; - -struct IUVElement : IElement { - Delete _d2; - virtual void gatherDependencies(std::vector& pathsOut) const = 0; - static constexpr std::string_view TypeName = "UVElement"sv; -}; - -struct BoolHelper : IElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - bool value = false; - explicit operator bool() const { return value; } - BoolHelper& operator=(bool val) { - value = val; - return *this; - } - std::string_view ClassID() const override { return "BoolHelper"sv; } -}; - -template -struct ValueHelper : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - - void _read(athena::io::IStreamReader& r) { - hecl::DNAFourCC ValueType; - ValueType.read(r); - if (ValueType == FOURCC('CNST')) - athena::io::Read::Do({}, value.emplace(), r); - else - value = std::nullopt; - } - void _write(athena::io::IStreamWriter& w) { - if (value) { - w.writeBytes("CNST", 4); - athena::io::Write::Do({}, *value, w); - } else { - w.writeBytes("NONE", 4); - } - } - void _binarySize(std::size_t& s) { - s += 4; - if (value) - athena::io::BinarySize::Do({}, *value, s); - } - void _read(athena::io::YAMLDocReader& r) { - athena::io::ReadYaml::Do({}, value.emplace(), r); - } - void _write(athena::io::YAMLDocWriter& w) { - athena::io::WriteYaml::Do({}, *value, w); - } - - static constexpr void gatherDependencies(std::vector& pathsOut) {} - - std::optional value = {}; - void emplace(Tp val) { value.emplace(val); } - Tp operator*() const { return *value; } - explicit operator bool() const { return value.operator bool(); } -}; - -struct RELifetimeTween : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "LFTW"sv; } -}; - -struct REConstant : IRealElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - Value val; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct RETimeChain : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct REAdd : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "ADD_"sv; } -}; - -struct REClamp : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory min; - RealElementFactory max; - RealElementFactory val; - std::string_view ClassID() const override { return "CLMP"sv; } -}; - -struct REKeyframeEmitter : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct REInitialRandom : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "IRND"sv; } -}; - -struct RERandom : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "RAND"sv; } -}; - -struct REMultiply : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "MULT"sv; } -}; - -struct REPulse : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct RETimeScale : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory dv; - std::string_view ClassID() const override { return "SCAL"sv; } -}; - -struct RELifetimePercent : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory percent; - std::string_view ClassID() const override { return "RLPT"sv; } -}; - -struct RESineWave : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory frequency; - RealElementFactory amplitude; - RealElementFactory phase; - std::string_view ClassID() const override { return "SINE"sv; } -}; - -struct REInitialSwitch : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "ISWT"sv; } -}; - -struct RECompareLessThan : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory ca; - RealElementFactory cb; - RealElementFactory pass; - RealElementFactory fail; - std::string_view ClassID() const override { return "CLTN"sv; } -}; - -struct RECompareEquals : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory ca; - RealElementFactory cb; - RealElementFactory pass; - RealElementFactory fail; - std::string_view ClassID() const override { return "CEQL"sv; } -}; - -struct REParticleAdvanceParam1 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP1"sv; } -}; - -struct REParticleAdvanceParam2 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP2"sv; } -}; - -struct REParticleAdvanceParam3 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP3"sv; } -}; - -struct REParticleAdvanceParam4 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP4"sv; } -}; - -struct REParticleAdvanceParam5 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP5"sv; } -}; - -struct REParticleAdvanceParam6 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP6"sv; } -}; - -struct REParticleAdvanceParam7 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP7"sv; } -}; - -struct REParticleAdvanceParam8 : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PAP8"sv; } -}; - -struct REParticleSizeOrLineLength : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PSLL"sv; } -}; - -struct REParticleRotationOrLineWidth : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PRLW"sv; } -}; - -struct RESubtract : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "SUB_"sv; } -}; - -struct REVectorMagnitude : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VMAG"sv; } -}; - -struct REVectorXToReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VXTR"sv; } -}; - -struct REVectorYToReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VYTR"sv; } -}; - -struct REVectorZToReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory vec; - std::string_view ClassID() const override { return "VZTR"sv; } -}; - -struct RECEXT : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory index; - std::string_view ClassID() const override { return "CEXT"sv; } -}; - -struct REIntTimesReal : IRealElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "ITRL"sv; } -}; - -struct IEKeyframeEmitter : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct IEDeath : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory passthrough; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "DETH"sv; } -}; - -struct IEClamp : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory min; - IntElementFactory max; - IntElementFactory val; - std::string_view ClassID() const override { return "CLMP"sv; } -}; - -struct IETimeChain : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct IEAdd : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "ADD_"sv; } -}; - -struct IEConstant : IIntElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - Value val; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct IEImpulse : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory val; - std::string_view ClassID() const override { return "IMPL"sv; } -}; - -struct IELifetimePercent : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory percent; - std::string_view ClassID() const override { return "ILPT"sv; } -}; - -struct IEInitialRandom : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "IRND"sv; } -}; - -struct IEPulse : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct IEMultiply : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "MULT"sv; } -}; - -struct IESampleAndHold : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory waitMin; - IntElementFactory waitMax; - IntElementFactory val; - std::string_view ClassID() const override { return "SPAH"sv; } -}; - -struct IERandom : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "RAND"sv; } -}; - -struct IETimeScale : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory dv; - std::string_view ClassID() const override { return "TSCL"sv; } -}; - -struct IEGTCP : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "GTCP"sv; } -}; - -struct IEModulo : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory a; - IntElementFactory b; - std::string_view ClassID() const override { return "MODU"sv; } -}; - -struct IESubtract : IIntElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory direction; - IntElementFactory baseRadius; - std::string_view ClassID() const override { return "SUB_"sv; } -}; - -struct VECone : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - RealElementFactory b; - std::string_view ClassID() const override { return "CONE"sv; } -}; - -struct VETimeChain : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - VectorElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct VEAngleCone : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory angleXBias; - RealElementFactory angleYBias; - RealElementFactory angleXRange; - RealElementFactory angleYRange; - RealElementFactory magnitude; - std::string_view ClassID() const override { return "ANGC"sv; } -}; - -struct VEAdd : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - VectorElementFactory b; - std::string_view ClassID() const override { return "ADD_"sv; } -}; - -struct VECircleCluster : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory circleOffset; - VectorElementFactory circleNormal; - IntElementFactory cycleFrames; - RealElementFactory randomFactor; - std::string_view ClassID() const override { return "CCLU"sv; } -}; - -struct VEConstant : IVectorElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - RealElementFactory comps[3]; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct VECircle : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory circleOffset; - VectorElementFactory circleNormal; - RealElementFactory angleConstant; - RealElementFactory angleLinear; - RealElementFactory circleRadius; - std::string_view ClassID() const override { return "CIRC"sv; } -}; - -struct VEKeyframeEmitter : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct VEMultiply : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - VectorElementFactory b; - std::string_view ClassID() const override { return "MULT"sv; } -}; - -struct VERealToVector : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory a; - std::string_view ClassID() const override { return "RTOV"sv; } -}; - -struct VEPulse : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - VectorElementFactory a; - VectorElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct VEParticleVelocity : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PVEL"sv; } -}; - -struct VESPOS : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory a; - std::string_view ClassID() const override { return "SPOS"sv; } -}; - -struct VEPLCO : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PLCO"sv; } -}; - -struct VEPLOC : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PLOC"sv; } -}; - -struct VEPSOR : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PSOR"sv; } -}; - -struct VEPSOF : IVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "PSOF"sv; } -}; - -struct CEKeyframeEmitter : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - Value percentageTween; - Value unk1; - Value loop; - Value unk2; - Value loopEnd; - Value loopStart; - Value count; - Vector keys; - std::string_view ClassID() const override { return percentageTween ? "KEYP"sv : "KEYE"sv; } -}; - -struct CEConstant : IColorElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - RealElementFactory comps[4]; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct CETimeChain : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ColorElementFactory a; - ColorElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct CEFadeEnd : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ColorElementFactory a; - ColorElementFactory b; - RealElementFactory startFrame; - RealElementFactory endFrame; - std::string_view ClassID() const override { return "CFDE"sv; } -}; - -struct CEFade : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ColorElementFactory a; - ColorElementFactory b; - RealElementFactory endFrame; - std::string_view ClassID() const override { return "FADE"sv; } -}; - -struct CEPulse : IColorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - ColorElementFactory a; - ColorElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct MVEImplosion : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory implodePoint; - RealElementFactory velocityScale; - RealElementFactory maxRadius; - RealElementFactory minRadius; - BoolHelper enableMinRadius; - std::string_view ClassID() const override { return "IMPL"sv; } -}; - -struct MVEExponentialImplosion : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory implodePoint; - RealElementFactory velocityScale; - RealElementFactory maxRadius; - RealElementFactory minRadius; - BoolHelper enableMinRadius; - std::string_view ClassID() const override { return "EMPL"sv; } -}; - -struct MVETimeChain : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - ModVectorElementFactory a; - ModVectorElementFactory b; - IntElementFactory thresholdFrame; - std::string_view ClassID() const override { return "CHAN"sv; } -}; - -struct MVEBounce : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory planePoint; - VectorElementFactory planeNormal; - RealElementFactory friction; - RealElementFactory restitution; - BoolHelper dieOnPenetrate; - std::string_view ClassID() const override { return "BNCE"sv; } -}; - -struct MVEConstant : IModVectorElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - RealElementFactory comps[3]; - std::string_view ClassID() const override { return "CNST"sv; } -}; - -struct MVEGravity : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory acceleration; - std::string_view ClassID() const override { return "GRAV"sv; } -}; - -struct MVEExplode : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - RealElementFactory impulseMagnitude; - RealElementFactory falloffFactor; - std::string_view ClassID() const override { return "EXPL"sv; } -}; - -struct MVESetPosition : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory position; - std::string_view ClassID() const override { return "SPOS"sv; } -}; - -struct MVELinearImplosion : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory implodePoint; - RealElementFactory velocityScale; - RealElementFactory maxRadius; - RealElementFactory minRadius; - BoolHelper enableMinRadius; - std::string_view ClassID() const override { return "LMPL"sv; } -}; - -struct MVEPulse : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - IntElementFactory aDuration; - IntElementFactory bDuration; - ModVectorElementFactory a; - ModVectorElementFactory b; - std::string_view ClassID() const override { return "PULS"sv; } -}; - -struct MVEWind : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory windVelocity; - RealElementFactory factor; - std::string_view ClassID() const override { return "WIND"sv; } -}; - -struct MVESwirl : IModVectorElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory helixPoint; - VectorElementFactory curveBinormal; - RealElementFactory filterGain; - RealElementFactory tangentialVelocity; - std::string_view ClassID() const override { return "SWRL"sv; } -}; - -struct EESimpleEmitter : IEmitterElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory position; - VectorElementFactory velocity; - std::string_view ClassID() const override { return "SEMR"sv; } -}; - -struct VESphere : IEmitterElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory sphereOrigin; - RealElementFactory sphereRadius; - RealElementFactory magnitude; - std::string_view ClassID() const override { return "SPHE"sv; } -}; - -struct VEAngleSphere : IEmitterElement { - AT_DECL_DNA_YAMLV_NO_TYPE - VectorElementFactory sphereOrigin; - RealElementFactory angleXBias; - RealElementFactory angleYBias; - RealElementFactory angleXRange; - RealElementFactory angleYRange; - RealElementFactory sphereRadius; - RealElementFactory magnitude; - std::string_view ClassID() const override { return "ASPH"sv; } -}; - -struct EESimpleEmitterTR : EESimpleEmitter { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - std::string_view ClassID() const override { return "SETR"sv; } -}; - -template -struct UVEConstant : IUVElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - AT_SUBDECL_DNA - CastIDToZero tex; - std::string_view ClassID() const override { return "CNST"sv; } - - void gatherDependencies(std::vector& pathsOut) const override { - if (tex.isValid()) - g_curSpec->flattenDependencies(tex, pathsOut); - } -}; - -template -struct UVEAnimTexture : IUVElement { - AT_DECL_EXPLICIT_DNA_YAMLV_NO_TYPE - AT_SUBDECL_DNA - CastIDToZero tex; - IntElementFactory tileW; - IntElementFactory tileH; - IntElementFactory strideW; - IntElementFactory strideH; - IntElementFactory cycleFrames; - Value loop = false; - std::string_view ClassID() const override { return "ATEX"sv; } - - void gatherDependencies(std::vector& pathsOut) const override { - if (tex.isValid()) - g_curSpec->flattenDependencies(tex, pathsOut); - } -}; - -template -struct _UVElementFactory { - using PtrType = IUVElement; - template - static bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { - case SBIG('CNST'): - f(PEType>{}); - return true; - case SBIG('ATEX'): - f(PEType>{}); - return true; - default: - return false; - } - } - static constexpr void gatherDependencies(std::vector& pathsOut, - const std::unique_ptr& elemPtr) { - if (elemPtr) - elemPtr->gatherDependencies(pathsOut); - } -}; -template -using UVElementFactory = PEImpl<_UVElementFactory>; - -template -struct SpawnSystemKeyframeData : BigDNA { - Value a; - Value b; - Value endFrame; - Value d; - - struct SpawnSystemKeyframeInfo : BigDNA { - IDType id; - Value a; - Value b; - Value c; - AT_DECL_EXPLICIT_DNA_YAML - }; - - std::vector>> spawns; - - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - - explicit operator bool() const { return spawns.size() != 0; } - - void gatherDependencies(std::vector& pathsOut) const { - for (const auto& p : spawns) - for (const SpawnSystemKeyframeInfo& info : p.second) - g_curSpec->flattenDependencies(info.id, pathsOut); - } -}; - -template -struct ChildResourceFactory : BigDNA { - IDType id; - AT_DECL_EXPLICIT_DNA_YAML - AT_SUBDECL_DNA - explicit operator bool() const { return id.isValid(); } - void gatherDependencies(std::vector& pathsOut) const { - if (id.isValid()) - g_curSpec->flattenDependencies(id, pathsOut); - } -}; - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/RigInverter.cpp b/DataSpec/DNACommon/RigInverter.cpp deleted file mode 100644 index e1c6078ef..000000000 --- a/DataSpec/DNACommon/RigInverter.cpp +++ /dev/null @@ -1,145 +0,0 @@ -#include "DataSpec/DNACommon/RigInverter.hpp" - -#include "DataSpec/DNAMP1/CINF.hpp" -#include "DataSpec/DNAMP2/CINF.hpp" -#include "DataSpec/DNAMP3/CINF.hpp" - -#include - -namespace DataSpec::DNAANIM { - -template -RigInverter::Bone::Bone(const CINFType& cinf, const typename CINFType::Bone& origBone) -: m_origBone(origBone) { - atUint32 parentIdx = cinf.getInternalBoneIdxFromId(origBone.parentId); - zeus::CVector3f boneOrigin(origBone.origin); - zeus::CVector3f naturalTail = boneOrigin + zeus::CVector3f{0.f, 0.5f, 0.f}; - if (parentIdx != UINT32_MAX) { - const typename CINFType::Bone& pBone = cinf.bones[parentIdx]; - m_parentDelta = boneOrigin - zeus::CVector3f(pBone.origin); - } - - size_t actualChildren = 0; - for (atUint32 chId : origBone.linked) { - if (chId == origBone.parentId) - continue; - atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId); - if (chIdx != UINT32_MAX) - ++actualChildren; - } - - const std::string* bName = cinf.getBoneNameFromId(origBone.id); - bool isLCTR = false; - if (bName) - isLCTR = bName->find("_LCTR") != std::string::npos; - - if (parentIdx == UINT32_MAX) { - /* Root will always use +Y tail */ - m_tail = naturalTail; - } else if (actualChildren) { - /* Position tail to average of children */ - for (atUint32 chId : origBone.linked) { - if (chId == origBone.parentId) - continue; - atUint32 chIdx = cinf.getInternalBoneIdxFromId(chId); - if (chIdx != UINT32_MAX) { - const typename CINFType::Bone& chBone = cinf.bones[chIdx]; - m_tail += chBone.origin; - } - } - m_tail /= zeus::CVector3f(float(actualChildren)); - if ((m_tail - boneOrigin).magSquared() < 0.001f) - m_tail = naturalTail; - else if (isLCTR) - m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * (m_tail - boneOrigin).magnitude(); - } else { - /* Extrapolate by delta with parent */ - m_tail = boneOrigin + m_parentDelta; - float deltaMag = m_parentDelta.magnitude(); - if (deltaMag < 0.001f) { - deltaMag = 0.5f; - m_tail = naturalTail; - } else if (deltaMag > 0.5f) { - /* Extreme bones capped to +0.5 value */ - deltaMag = 0.5f; - m_tail = boneOrigin + m_parentDelta.normalized() * 0.5f; - } - - if (isLCTR) - m_tail = boneOrigin + zeus::CVector3f{0.f, 1.0f, 0.f} * deltaMag; - } -} - -template -RigInverter::RigInverter(const CINFType& cinf) : m_cinf(cinf) { - m_bones.reserve(cinf.bones.size()); - for (const typename CINFType::Bone& b : cinf.bones) - m_bones.emplace_back(cinf, b); -} - -template -RigInverter::RigInverter(const CINFType& cinf, - const std::unordered_map& matrices) -: m_cinf(cinf) { - m_bones.reserve(cinf.bones.size()); - for (const typename CINFType::Bone& b : cinf.bones) { - m_bones.emplace_back(cinf, b); - - const std::string* name = cinf.getBoneNameFromId(b.id); - if (name) { - auto search = matrices.find(*name); - if (search != matrices.cend()) { - zeus::CMatrix3f boneMtx(search->second[0], search->second[1], search->second[2]); - m_bones.back().m_restorer = boneMtx; - m_bones.back().m_inverter = m_bones.back().m_restorer.inverse(); - } - } - } -} - -template -zeus::CQuaternion RigInverter::invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) - return b.m_restorer * origRot * b.m_inverter; - return origRot; -} - -template -zeus::CVector3f RigInverter::invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, - bool subDelta) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) { - zeus::CVector3f localPos = origPos; - if (subDelta) - localPos -= b.m_parentDelta; - return b.m_restorer.transform(localPos); - } - return origPos; -} - -template -zeus::CQuaternion RigInverter::restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) - return b.m_inverter * origRot * b.m_restorer; - return origRot; -} - -template -zeus::CVector3f RigInverter::restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, - bool subDelta) const { - for (const Bone& b : m_bones) - if (b.m_origBone.id == boneId) { - zeus::CVector3f localPos = b.m_inverter.transform(origPos); - if (subDelta) - localPos += b.m_parentDelta; - return localPos; - } - return origPos; -} - -template class RigInverter; -template class RigInverter; - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/RigInverter.hpp b/DataSpec/DNACommon/RigInverter.hpp deleted file mode 100644 index 11e644ad3..000000000 --- a/DataSpec/DNACommon/RigInverter.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include -#include -#include - -#include -#include -#include - -namespace DataSpec::DNAANIM { - -/** One-shot process to invert CINF armature into connected rig, - * inverting rotations/translations of ANIM data to match */ -template -class RigInverter { -public: - struct Bone { - const typename CINFType::Bone& m_origBone; - zeus::CQuaternion m_inverter; - zeus::CQuaternion m_restorer; - zeus::CVector3f m_tail; - zeus::CVector3f m_parentDelta; - Bone(const CINFType& cinf, const typename CINFType::Bone& origBone); - }; - -private: - const CINFType& m_cinf; - std::vector m_bones; - -public: - RigInverter(const CINFType& cinf); - RigInverter(const CINFType& cinf, const std::unordered_map& matrices); - const CINFType& getCINF() const { return m_cinf; } - const std::vector& getBones() const { return m_bones; } - - zeus::CQuaternion invertRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const; - zeus::CVector3f invertPosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const; - - zeus::CQuaternion restoreRotation(atUint32 boneId, const zeus::CQuaternion& origRot) const; - zeus::CVector3f restorePosition(atUint32 boneId, const zeus::CVector3f& origPos, bool subDelta) const; -}; - -} // namespace DataSpec::DNAANIM diff --git a/DataSpec/DNACommon/SAVWCommon.hpp b/DataSpec/DNACommon/SAVWCommon.hpp deleted file mode 100644 index 5258c2ffd..000000000 --- a/DataSpec/DNACommon/SAVWCommon.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::SAVWCommon { -enum class EScanCategory { None, Data, Lore, Creature, Research, Artifact }; - -struct Header : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - Value areaCount; -}; - -struct EnvironmentVariable : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unk1; - Value unk2; - Value unk3; -}; - -struct Layer : BigDNA { - AT_DECL_DNA_YAML - Value areaId; - Value layer; -}; - -template -static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - SAVW savw; - savw.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(savw, writer); - return true; -} - -} // namespace DataSpec::SAVWCommon diff --git a/DataSpec/DNACommon/STRG.cpp b/DataSpec/DNACommon/STRG.cpp deleted file mode 100644 index f6d0e6aed..000000000 --- a/DataSpec/DNACommon/STRG.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "DataSpec/DNACommon/STRG.hpp" - -#include "DataSpec/DNAMP1/STRG.hpp" -#include "DataSpec/DNAMP2/STRG.hpp" -#include "DataSpec/DNAMP3/STRG.hpp" - -#include - -namespace DataSpec { - -void ISTRG::gatherDependencies(std::vector& pathsOut) const { /* TODO: parse out resource tokens */ -} - -std::unique_ptr LoadSTRG(athena::io::IStreamReader& reader) { - uint32_t magic = reader.readUint32Big(); - if (magic != 0x87654321) { - LogDNACommon.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - return {}; - } - - uint32_t version = reader.readUint32Big(); - switch (version) { - case 0: { - auto* newStrg = new DNAMP1::STRG; - newStrg->_read(reader); - return std::unique_ptr(newStrg); - } - case 1: { - auto* newStrg = new DNAMP2::STRG; - newStrg->_read(reader); - return std::unique_ptr(newStrg); - } - case 3: { - auto* newStrg = new DNAMP3::STRG; - newStrg->_read(reader); - return std::unique_ptr(newStrg); - } - default: - break; - } - return {}; -} -} // namespace DataSpec diff --git a/DataSpec/DNACommon/STRG.hpp b/DataSpec/DNACommon/STRG.hpp deleted file mode 100644 index 04fddba87..000000000 --- a/DataSpec/DNACommon/STRG.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -#include - -namespace athena::io { -class IStreamReader; -} - -namespace DataSpec { -struct ISTRG : BigDNAVYaml { - ~ISTRG() override = default; - - virtual size_t count() const = 0; - virtual std::string getUTF8(const FourCC& lang, size_t idx) const = 0; - virtual std::u16string getUTF16(const FourCC& lang, size_t idx) const = 0; - virtual int32_t lookupIdx(std::string_view name) const = 0; - - virtual void gatherDependencies(std::vector& pathsOut) const; -}; -std::unique_ptr LoadSTRG(athena::io::IStreamReader& reader); - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/SWHC.cpp b/DataSpec/DNACommon/SWHC.cpp deleted file mode 100644 index 404de21af..000000000 --- a/DataSpec/DNACommon/SWHC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/SWHC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_SWSH>; -template struct PPImpl<_SWSH>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_SWSH>) - -template <> -std::string_view SWSH::DNAType() { - return "SWSH"sv; -} - -template <> -std::string_view SWSH::DNAType() { - return "SWSH"sv; -} - -template -bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - SWSH swsh; - swsh.read(rs); - athena::io::ToYAMLStream(swsh, writer); - return true; - } - return false; -} -template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteSWSH(const SWSH& swsh, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - swsh.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteSWSH(const SWSH& swsh, const hecl::ProjectPath& outPath); -template bool WriteSWSH(const SWSH& swsh, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/SWHC.def b/DataSpec/DNACommon/SWHC.def deleted file mode 100644 index 675d8b5ec..000000000 --- a/DataSpec/DNACommon/SWHC.def +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef VECTOR_ENTRY -#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef MOD_VECTOR_ENTRY -#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef UV_ENTRY -#define UV_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) -#endif - -INT_ENTRY('PSLT', x0_PSLT) -REAL_ENTRY('TIME', x4_TIME) -REAL_ENTRY('LRAD', x8_LRAD) -REAL_ENTRY('RRAD', xc_RRAD) -INT_ENTRY('LENG', x10_LENG) -COLOR_ENTRY('COLR', x14_COLR) -INT_ENTRY('SIDE', x18_SIDE) -REAL_ENTRY('IROT', x1c_IROT) -REAL_ENTRY('ROTM', x20_ROTM) -VECTOR_ENTRY('POFS', x24_POFS) -VECTOR_ENTRY('IVEL', x28_IVEL) -VECTOR_ENTRY('NPOS', x2c_NPOS) -MOD_VECTOR_ENTRY('VELM', x30_VELM) -MOD_VECTOR_ENTRY('VLM2', x34_VLM2) -INT_ENTRY('SPLN', x38_SPLN) -UV_ENTRY('TEXR', x3c_TEXR) -INT_ENTRY('TSPN', x40_TSPN) -BOOL_ENTRY('LLRD', x44_24_LLRD, false) -BOOL_ENTRY('CROS', x44_25_CROS, true) -BOOL_ENTRY('VLS1', x44_26_VLS1, false) -BOOL_ENTRY('VLS2', x44_27_VLS2, false) -BOOL_ENTRY('SROT', x44_28_SROT, false) -BOOL_ENTRY('WIRE', x44_29_WIRE, false) -BOOL_ENTRY('TEXW', x44_30_TEXW, false) -BOOL_ENTRY('AALP', x44_31_AALP, false) -BOOL_ENTRY('ZBUF', x45_24_ZBUF, false) -BOOL_ENTRY('ORNT', x45_25_ORNT, false) -BOOL_ENTRY('CRND', x45_26_CRND, false) - -#undef ENTRY -#undef INT_ENTRY -#undef REAL_ENTRY -#undef VECTOR_ENTRY -#undef MOD_VECTOR_ENTRY -#undef COLOR_ENTRY -#undef UV_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/SWHC.hpp b/DataSpec/DNACommon/SWHC.hpp deleted file mode 100644 index 2665a56ea..000000000 --- a/DataSpec/DNACommon/SWHC.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _SWSH { - static constexpr ParticleType Type = ParticleType::SWSH; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; -#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define UV_ENTRY(name, identifier) UVElementFactory identifier; -#define BOOL_ENTRY(name, identifier, def) bool identifier = def; -#include "SWHC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); -#include "SWHC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "SWHC.def" - default: - return false; - } - } -}; -template -using SWSH = PPImpl<_SWSH>; - -template -bool ExtractSWSH(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteSWSH(const SWSH& gpsm, const hecl::ProjectPath& outPath); -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/TXTR.cpp b/DataSpec/DNACommon/TXTR.cpp deleted file mode 100644 index 12376b47a..000000000 --- a/DataSpec/DNACommon/TXTR.cpp +++ /dev/null @@ -1,1702 +0,0 @@ -#include "DataSpec/DNACommon/TXTR.hpp" - -#include -#include - -#include "DataSpec/DNACommon/PAK.hpp" - -#include -#include -#include -#include -#include - -namespace DataSpec { - -static logvisor::Module Log("libpng"); - -static int CountBits(uint32_t n) { - int ret = 0; - for (int i = 0; i < 32; ++i) { - if (((n >> i) & 1) != 0) { - ++ret; - } - } - return ret; -} - -/* Box filter algorithm (for mipmapping) */ -static void BoxFilter(const uint8_t* input, unsigned chanCount, unsigned inWidth, unsigned inHeight, uint8_t* output, - bool dxt1) { - unsigned mipWidth = 1; - unsigned mipHeight = 1; - if (inWidth > 1) { - mipWidth = inWidth / 2; - } - if (inHeight > 1) { - mipHeight = inHeight / 2; - } - - for (unsigned y = 0; y < mipHeight; ++y) { - const unsigned miplineBase = mipWidth * y; - const unsigned in1LineBase = inWidth * (y * 2); - const unsigned in2LineBase = inWidth * (y * 2 + 1); - for (unsigned x = 0; x < mipWidth; ++x) { - uint8_t* out = &output[(miplineBase + x) * chanCount]; - for (unsigned c = 0; c < chanCount; ++c) { - uint32_t tmp = 0; - tmp += input[(in1LineBase + (x * 2)) * chanCount + c]; - tmp += input[(in1LineBase + (x * 2 + 1)) * chanCount + c]; - tmp += input[(in2LineBase + (x * 2)) * chanCount + c]; - tmp += input[(in2LineBase + (x * 2 + 1)) * chanCount + c]; - out[c] = uint8_t(tmp / 4); - if (c == 3 && dxt1) { - out[c] = uint8_t(out[c] ? 0xff : 0x0); - } - } - } - } -} - -static size_t ComputeMippedTexelCount(unsigned inWidth, unsigned inHeight) { - size_t ret = 0; - while (inWidth > 0 && inHeight > 0) { - ret += inWidth * inHeight; - inWidth /= 2; - inHeight /= 2; - } - return ret; -} - -/* GX uses this upsampling technique to extract full 8-bit range */ -static constexpr uint8_t Convert3To8(uint8_t v) { - /* Swizzle bits: 00000123 -> 12312312 */ - return (v << 5) | (v << 2) | (v >> 1); -} - -static constexpr uint8_t Convert8To3(uint8_t v) { return v >> 5; } - -static constexpr uint8_t Convert4To8(uint8_t v) { - /* Swizzle bits: 00001234 -> 12341234 */ - return (v << 4) | v; -} - -static constexpr uint8_t Convert8To4(uint8_t v) { return v >> 4; } - -static constexpr uint8_t Convert5To8(uint8_t v) { - /* Swizzle bits: 00012345 -> 12345123 */ - return (v << 3) | (v >> 2); -} - -static constexpr uint8_t Convert8To5(uint8_t v) { return v >> 3; } - -static constexpr uint8_t Convert6To8(uint8_t v) { - /* Swizzle bits: 00123456 -> 12345612 */ - return (v << 2) | (v >> 4); -} - -static constexpr uint8_t Convert8To6(uint8_t v) { return v >> 2; } - -static uint8_t Lookup4BPP(const uint8_t* texels, int width, int x, int y) { - const int bwidth = (width + 7) / 8; - const int bx = x / 8; - const int by = y / 8; - const int rx = x % 8; - const int ry = y % 8; - const int bidx = by * bwidth + bx; - const uint8_t* btexels = &texels[32 * bidx]; - return btexels[ry * 4 + rx / 2] >> ((rx & 1) ? 0 : 4) & 0xf; -} - -static void Set4BPP(uint8_t* texels, int width, int x, int y, uint8_t val) { - const int bwidth = (width + 7) / 8; - const int bx = x / 8; - const int by = y / 8; - const int rx = x % 8; - const int ry = y % 8; - const int bidx = by * bwidth + bx; - uint8_t* btexels = &texels[32 * bidx]; - btexels[ry * 4 + rx / 2] |= (val & 0xf) << ((rx & 1) ? 0 : 4); -} - -static uint8_t Lookup8BPP(const uint8_t* texels, int width, int x, int y) { - int bwidth = (width + 7) / 8; - int bx = x / 8; - int by = y / 4; - int rx = x % 8; - int ry = y % 4; - int bidx = by * bwidth + bx; - const uint8_t* btexels = &texels[32 * bidx]; - return btexels[ry * 8 + rx]; -} - -static void Set8BPP(uint8_t* texels, int width, int x, int y, uint8_t val) { - const int bwidth = (width + 7) / 8; - const int bx = x / 8; - const int by = y / 4; - const int rx = x % 8; - const int ry = y % 4; - const int bidx = by * bwidth + bx; - uint8_t* btexels = &texels[32 * bidx]; - btexels[ry * 8 + rx] = val; -} - -static uint16_t Lookup16BPP(const uint8_t* texels, int width, int x, int y) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - int bidx = by * bwidth + bx; - const uint16_t* btexels = reinterpret_cast(&texels[32 * bidx]); - return btexels[ry * 4 + rx]; -} - -static void Set16BPP(uint8_t* texels, int width, int x, int y, uint16_t val) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - const int bidx = by * bwidth + bx; - auto* btexels = reinterpret_cast(&texels[32 * bidx]); - btexels[ry * 4 + rx] = val; -} - -static void LookupRGBA8(const uint8_t* texels, int width, int x, int y, uint8_t* r, uint8_t* g, uint8_t* b, - uint8_t* a) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - const int bidx = (by * bwidth + bx) * 2; - const auto* artexels = reinterpret_cast(&texels[32 * bidx]); - const auto* gbtexels = reinterpret_cast(&texels[32 * (bidx + 1)]); - const uint16_t ar = hecl::SBig(artexels[ry * 4 + rx]); - *a = ar >> 8 & 0xff; - *r = ar & 0xff; - const uint16_t gb = hecl::SBig(gbtexels[ry * 4 + rx]); - *g = gb >> 8 & 0xff; - *b = gb & 0xff; -} - -static void SetRGBA8(uint8_t* texels, int width, int x, int y, uint8_t r, uint8_t g, uint8_t b, uint8_t a) { - const int bwidth = (width + 3) / 4; - const int bx = x / 4; - const int by = y / 4; - const int rx = x % 4; - const int ry = y % 4; - const int bidx = (by * bwidth + bx) * 2; - uint16_t* artexels = reinterpret_cast(&texels[32 * bidx]); - uint16_t* gbtexels = reinterpret_cast(&texels[32 * (bidx + 1)]); - const uint16_t ar = (a << 8) | r; - artexels[ry * 4 + rx] = hecl::SBig(ar); - const uint16_t gb = (g << 8) | b; - gbtexels[ry * 4 + rx] = hecl::SBig(gb); -} - -static void DecodeI4(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width]); - // memset(buf.get(), 0, width); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - buf[x] = Convert4To8(Lookup4BPP(texels, width, x, y)); - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeI4(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint8_t[width]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - buf[x] = Lookup8BPP(texels, width, x, y); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeI8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - Set8BPP(texels, width, x, y, rgbaIn[x]); - } - rgbaIn += width; - } -} - -static void DecodeIA4(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width * 2]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - const uint8_t texel = Lookup8BPP(texels, width, x, y); - buf[x * 2] = Convert4To8(texel & 0xf); - buf[x * 2 + 1] = Convert4To8(texel >> 4 & 0xf); - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeIA4(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint16_t[width]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - buf[x] = hecl::SBig(Lookup16BPP(texels, width, x, y)); - } - png_write_row(png, reinterpret_cast(buf.get())); - } -} - -static void EncodeIA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - Set16BPP(texels, width, x, y, hecl::SBig(reinterpret_cast(rgbaIn)[x])); - } - rgbaIn += width * 2; - } -} - -static const uint8_t* DecodePalette(png_structp png, png_infop info, int numEntries, const uint8_t* data) { - const auto format = hecl::SBig(*reinterpret_cast(data)); - data += 8; - png_color cEntries[256]; - png_byte aEntries[256]; - switch (format) { - case 0: { - /* IA8 */ - for (int e = 0; e < numEntries; ++e) { - cEntries[e].red = data[e * 2]; - cEntries[e].green = data[e * 2]; - cEntries[e].blue = data[e * 2]; - aEntries[e] = data[e * 2 + 1]; - } - break; - } - case 1: { - /* RGB565 */ - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - cEntries[e].red = Convert5To8(texel >> 11 & 0x1f); - cEntries[e].green = Convert6To8(texel >> 5 & 0x3f); - cEntries[e].blue = Convert5To8(texel & 0x1f); - } - break; - } - case 2: { - /* RGB5A3 */ - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - if (texel & 0x8000) { - cEntries[e].red = Convert5To8(texel >> 10 & 0x1f); - cEntries[e].green = Convert5To8(texel >> 5 & 0x1f); - cEntries[e].blue = Convert5To8(texel & 0x1f); - aEntries[e] = 0xff; - } else { - cEntries[e].red = Convert4To8(texel >> 8 & 0xf); - cEntries[e].green = Convert4To8(texel >> 4 & 0xf); - cEntries[e].blue = Convert4To8(texel & 0xf); - aEntries[e] = Convert3To8(texel >> 12 & 0x7); - } - } - break; - } - } - png_set_PLTE(png, info, cEntries, numEntries); - if (format == 0 || format == 2) { - png_set_tRNS(png, info, aEntries, numEntries, nullptr); - } - data += numEntries * 2; - return data; -} - -static uint8_t* EncodePalette(png_structp png, png_infop info, int numEntries, uint8_t* data) { - png_colorp cEntries; - int pngNumEntries; - if (png_get_PLTE(png, info, &cEntries, &pngNumEntries) != PNG_INFO_PLTE) { - cEntries = nullptr; - pngNumEntries = 0; - } - - png_bytep aEntries; - int pngNumAEntries; - png_color_16p trans_color = nullptr; - if (png_get_tRNS(png, info, &aEntries, &pngNumAEntries, &trans_color) != PNG_INFO_tRNS) { - aEntries = nullptr; - pngNumAEntries = 0; - } - - uint32_t format = 0; /* Default IA8 */ - for (int e = 0; e < pngNumEntries; ++e) { - const png_const_colorp ent = &cEntries[e]; - if (ent->red != ent->green || ent->red != ent->blue) { - if (pngNumAEntries) { - format = 2; /* RGB565 if not greyscale and has alpha */ - } else { - format = 1; /* RGB565 if not greyscale */ - } - break; - } - } - - reinterpret_cast(data)[0] = hecl::SBig(format); - data += 4; - reinterpret_cast(data)[0] = hecl::SBig(uint16_t(numEntries)); - reinterpret_cast(data)[1] = hecl::SBig(uint16_t(1)); - data += 4; - - switch (format) { - case 0: { - /* IA8 */ - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) - data[e * 2] = cEntries[e].green; - else - data[e * 2] = 0; - if (e < pngNumAEntries) - data[e * 2 + 1] = aEntries[e]; - else - data[e * 2 + 1] = 0; - } - break; - } - case 1: { - /* RGB565 */ - uint16_t* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) { - uint16_t texel = Convert8To5(cEntries[e].red) << 11; - texel |= Convert8To6(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - data16[e] = hecl::SBig(texel); - } else { - data16[e] = 0; - } - } - break; - } - case 2: { - /* RGB5A3 */ - auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - uint8_t alpha = 0; - if (e < pngNumAEntries) { - alpha = aEntries[e]; - } - - uint16_t texel = 0; - if (alpha == 0xff) { - texel |= 0x8000; - if (e < pngNumEntries) { - texel |= Convert8To5(cEntries[e].red) << 10; - texel |= Convert8To5(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - } - } else { - if (e < pngNumEntries) { - texel |= Convert8To4(cEntries[e].red) << 8; - texel |= Convert8To4(cEntries[e].green) << 4; - texel |= Convert8To4(cEntries[e].blue); - texel |= Convert8To3(alpha << 12); - } - } - data16[e] = hecl::SBig(texel); - } - break; - } - } - data += numEntries * 2; - return data; -} - -static const uint8_t* DecodePaletteSPLT(png_structp png, png_infop info, int numEntries, const uint8_t* data) { - const auto format = hecl::SBig(*reinterpret_cast(data)); - data += 8; - png_sPLT_entry entries[256] = {}; - png_sPLT_t GXEntry = {(char*)"GXPalette", 8, entries, numEntries}; - switch (format) { - case 0: { - /* IA8 */ - GXEntry.name = (char*)"GX_IA8"; - for (int e = 0; e < numEntries; ++e) { - entries[e].red = data[e * 2]; - entries[e].green = data[e * 2]; - entries[e].blue = data[e * 2]; - entries[e].alpha = data[e * 2 + 1]; - } - break; - } - case 1: { - /* RGB565 */ - GXEntry.name = (char*)"GX_RGB565"; - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - entries[e].red = Convert5To8(texel >> 11 & 0x1f); - entries[e].green = Convert6To8(texel >> 5 & 0x3f); - entries[e].blue = Convert5To8(texel & 0x1f); - entries[e].alpha = 0xff; - } - break; - } - case 2: { - /* RGB5A3 */ - GXEntry.name = (char*)"GX_RGB5A3"; - const auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - const uint16_t texel = hecl::SBig(data16[e]); - if (texel & 0x8000) { - entries[e].red = Convert5To8(texel >> 10 & 0x1f); - entries[e].green = Convert5To8(texel >> 5 & 0x1f); - entries[e].blue = Convert5To8(texel & 0x1f); - entries[e].alpha = 0xff; - } else { - entries[e].red = Convert4To8(texel >> 8 & 0xf); - entries[e].green = Convert4To8(texel >> 4 & 0xf); - entries[e].blue = Convert4To8(texel & 0xf); - entries[e].alpha = Convert3To8(texel >> 12 & 0x7); - } - } - break; - } - } - png_set_sPLT(png, info, &GXEntry, 1); - data += numEntries * 2; - return data; -} - -static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntries, uint8_t* data) { - png_sPLT_tp palettes; - const int pngNumPalettes = png_get_sPLT(png, info, &palettes); - int pngNumEntries = 0; - png_sPLT_entryp cEntries = nullptr; - for (int i = 0; i < pngNumPalettes; ++i) { - const png_const_sPLT_tp palette = &palettes[i]; - if (strncmp(palette->name, "GX_", 3) == 0) { - pngNumEntries = palette->nentries; - cEntries = palette->entries; - break; - } - } - - uint32_t format = 2; /* Default RGB5A3 */ - for (int e = 0; e < pngNumEntries; ++e) { - const png_const_sPLT_entryp ent = &cEntries[e]; - if (ent->red != ent->green || ent->red != ent->blue) { - if (ent->alpha) { - format = 2; - break; - } else { - format = 1; - } - } - } - - reinterpret_cast(data)[0] = hecl::SBig(format); - data += 4; - reinterpret_cast(data)[0] = hecl::SBig(uint16_t(1)); - reinterpret_cast(data)[1] = hecl::SBig(uint16_t(numEntries)); - data += 4; - - switch (format) { - case 0: { - /* IA8 */ - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) { - data[e * 2] = cEntries[e].green; - data[e * 2 + 1] = cEntries[e].alpha; - } else { - data[e * 2] = 0; - data[e * 2 + 1] = 0; - } - } - break; - } - case 1: { - /* RGB565 */ - auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - if (e < pngNumEntries) { - uint16_t texel = Convert8To5(cEntries[e].red) << 11; - texel |= Convert8To6(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - data16[e] = hecl::SBig(texel); - } else { - data16[e] = 0; - } - } - break; - } - case 2: { - /* RGB5A3 */ - auto* data16 = reinterpret_cast(data); - for (int e = 0; e < numEntries; ++e) { - uint16_t texel = 0; - if (cEntries && cEntries[e].alpha == 0xff) { - texel |= 0x8000; - if (e < pngNumEntries) { - texel |= Convert8To5(cEntries[e].red) << 10; - texel |= Convert8To5(cEntries[e].green) << 5; - texel |= Convert8To5(cEntries[e].blue); - } - } else { - if (e < pngNumEntries) { - texel |= Convert8To4(cEntries[e].red) << 8; - texel |= Convert8To4(cEntries[e].green) << 4; - texel |= Convert8To4(cEntries[e].blue); - texel |= Convert8To3(cEntries[e].alpha << 12); - } - } - data16[e] = hecl::SBig(texel); - } - break; - } - } - data += numEntries * 2; - return data; -} - -static const png_color C4Colors[] = { - {0, 0, 0}, {155, 0, 0}, {0, 155, 0}, {0, 0, 155}, {155, 155, 0}, {155, 0, 155}, {0, 155, 155}, {155, 155, 155}, - {55, 55, 55}, {255, 0, 0}, {0, 255, 0}, {0, 0, 255}, {255, 255, 0}, {255, 0, 255}, {0, 255, 255}, {255, 255, 255}}; - -static void C4Palette(png_structp png, png_infop info) { png_set_PLTE(png, info, C4Colors, 16); } - -static void DecodeC4(png_structp png, png_infop info, const uint8_t* data, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - C4Palette(png, info); - const uint8_t* texels = DecodePaletteSPLT(png, info, 16, data); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width]); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - buf[x] = Lookup4BPP(texels, width, x, y); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeC4(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) { - uint8_t* texels = EncodePaletteSPLT(png, info, 16, data); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - Set4BPP(texels, width, x, y, rgbaIn[x]); - } - rgbaIn += width; - } -} - -static void DecodeC8(png_structp png, png_infop info, const uint8_t* data, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - const uint8_t* texels = DecodePalette(png, info, 256, data); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width]); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - buf[x] = Lookup8BPP(texels, width, x, y); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeC8(png_structp png, png_infop info, const uint8_t* rgbaIn, uint8_t* data, int width, int height) { - uint8_t* texels = EncodePalette(png, info, 256, data); - for (int y = 0; y < height; ++y) { - for (int x = 0; x < width; ++x) { - Set8BPP(texels, width, x, y, rgbaIn[x]); - } - rgbaIn += width; - } -} - -static void DecodeRGB565(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - std::unique_ptr buf(new uint8_t[width * 3]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); - buf[x * 3] = Convert5To8(texel >> 11 & 0x1f); - buf[x * 3 + 1] = Convert6To8(texel >> 5 & 0x3f); - buf[x * 3 + 2] = Convert5To8(texel & 0x1f); - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeRGB565(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint8_t[width * 4]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - const uint16_t texel = hecl::SBig(Lookup16BPP(texels, width, x, y)); - if (texel & 0x8000) { - buf[x * 4] = Convert5To8(texel >> 10 & 0x1f); - buf[x * 4 + 1] = Convert5To8(texel >> 5 & 0x1f); - buf[x * 4 + 2] = Convert5To8(texel & 0x1f); - buf[x * 4 + 3] = 0xff; - } else { - buf[x * 4] = Convert4To8(texel >> 8 & 0xf); - buf[x * 4 + 1] = Convert4To8(texel >> 4 & 0xf); - buf[x * 4 + 2] = Convert4To8(texel & 0xf); - buf[x * 4 + 3] = Convert3To8(texel >> 12 & 0x7); - } - } - png_write_row(png, buf.get()); - } -} - -#if 0 -static void EncodeRGB5A3(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) -{ - for (int y=height-1 ; y>=0 ; --y) - { - for (int x=0 ; x buf(new uint8_t[width * 4]); - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - LookupRGBA8(texels, width, x, y, &buf[x * 4], &buf[x * 4 + 1], &buf[x * 4 + 2], &buf[x * 4 + 3]); - } - png_write_row(png, buf.get()); - } -} - -static void EncodeRGBA8(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - for (int y = height - 1; y >= 0; --y) { - for (int x = 0; x < width; ++x) { - SetRGBA8(texels, width, x, y, rgbaIn[x * 4], rgbaIn[x * 4 + 1], rgbaIn[x * 4 + 2], rgbaIn[x * 4 + 3]); - } - rgbaIn += width * 4; - } -} - -struct DXTBlock { - uint16_t color1; - uint16_t color2; - uint8_t lines[4]; -}; - -static void DecodeCMPR(png_structp png, png_infop info, const uint8_t* texels, int width, int height) { - png_set_IHDR(png, info, width, height, 8, PNG_COLOR_TYPE_RGB_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - /* Decode 8 rows at a time */ - const int bwidth = (width + 7) / 8; - const int bpwidth = bwidth * 8; - std::unique_ptr buf(new uint32_t[bpwidth * 8]); - uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4}; - for (int y = height / 8 - 1; y >= 0; --y) { - const auto* blks = reinterpret_cast(texels + 32 * bwidth * y); - for (int x = 0; x < width; x += 8) { - uint32_t blkOut[4][4][4]; - squish::Decompress(reinterpret_cast(blkOut[0][0]), blks++, squish::kDxt1GCN); - squish::Decompress(reinterpret_cast(blkOut[1][0]), blks++, squish::kDxt1GCN); - squish::Decompress(reinterpret_cast(blkOut[2][0]), blks++, squish::kDxt1GCN); - squish::Decompress(reinterpret_cast(blkOut[3][0]), blks++, squish::kDxt1GCN); - - for (int bt = 0; bt < 4; ++bt) { - for (int by = 0; by < 4; ++by) { - std::memcpy(bTargets[bt] + x + width * by, blkOut[bt][by], 16); - } - } - } - for (int r = 7; r >= 0; --r) { - png_write_row(png, reinterpret_cast(bTargets[0] + width * r)); - } - } -} - -static void EncodeCMPR(const uint8_t* rgbaIn, uint8_t* texels, int width, int height) { - /* Encode 8 rows at a time */ - const int bwidth = (width + 7) / 8; - const int bpwidth = bwidth * 8; - std::unique_ptr buf(new uint32_t[bpwidth * 8]); - uint32_t* bTargets[4] = {buf.get(), buf.get() + 4, buf.get() + 4 * width, buf.get() + 4 * width + 4}; - for (int y = height / 8 - 1; y >= 0; --y) { - for (int r = 7; r >= 0; --r) { - std::memcpy(bTargets[0] + width * r, rgbaIn, width * 4); - rgbaIn += width * 4; - } - auto* blks = reinterpret_cast(texels + 32 * bwidth * y); - for (int x = 0; x < width; x += 8) { - uint32_t blkIn[4][4][4]; - for (int bt = 0; bt < 4; ++bt) { - for (int by = 0; by < 4; ++by) { - std::memcpy(blkIn[bt][by], bTargets[bt] + x + width * by, 16); - } - } - - squish::Compress(reinterpret_cast(blkIn[0][0]), blks++, squish::kDxt1GCN); - squish::Compress(reinterpret_cast(blkIn[1][0]), blks++, squish::kDxt1GCN); - squish::Compress(reinterpret_cast(blkIn[2][0]), blks++, squish::kDxt1GCN); - squish::Compress(reinterpret_cast(blkIn[3][0]), blks++, squish::kDxt1GCN); - } - } -} - -static void PNGErr(png_structp png, png_const_charp msg) { Log.report(logvisor::Error, FMT_STRING("{}"), msg); } - -static void PNGWarn(png_structp png, png_const_charp msg) { Log.report(logvisor::Warning, FMT_STRING("{}"), msg); } - -bool TXTR::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - const uint32_t format = rs.readUint32Big(); - const uint16_t width = rs.readUint16Big(); - const uint16_t height = rs.readUint16Big(); - const uint32_t numMips = rs.readUint32Big(); - - auto fp = hecl::FopenUnique(outPath.getAbsolutePath().data(), "wb"); - if (fp == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath()); - return false; - } - png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, PNGErr, PNGWarn); - png_init_io(png, fp.get()); - png_infop info = png_create_info_struct(png); - - png_text textStruct = {}; - textStruct.key = png_charp("metaforce_nomip"); - if (numMips == 1) - png_set_text(png, info, &textStruct, 1); - - switch (format) { - case 0: - DecodeI4(png, info, rs.data() + 12, width, height); - break; - case 1: - DecodeI8(png, info, rs.data() + 12, width, height); - break; - case 2: - DecodeIA4(png, info, rs.data() + 12, width, height); - break; - case 3: - DecodeIA8(png, info, rs.data() + 12, width, height); - break; - case 4: - DecodeC4(png, info, rs.data() + 12, width, height); - break; - case 5: - DecodeC8(png, info, rs.data() + 12, width, height); - break; - case 7: - DecodeRGB565(png, info, rs.data() + 12, width, height); - break; - case 8: - DecodeRGB5A3(png, info, rs.data() + 12, width, height); - break; - case 9: - DecodeRGBA8(png, info, rs.data() + 12, width, height); - break; - case 10: - DecodeCMPR(png, info, rs.data() + 12, width, height); - break; - } - - png_write_end(png, info); - png_write_flush(png); - png_destroy_write_struct(&png, &info); - - return true; -} - -static std::unique_ptr ReadPalette(png_structp png, png_infop info, size_t& szOut) { - std::unique_ptr ret; - png_sPLT_tp palettes; - const int paletteCount = png_get_sPLT(png, info, &palettes); - if (paletteCount != 0) { - for (int i = 0; i < paletteCount; ++i) { - const png_const_sPLT_tp palette = &palettes[i]; - if (strncmp(palette->name, "GX_", 3) == 0) { - if (palette->nentries > 16) { - /* This is a C8 palette */ - ret.reset(new uint8_t[4 * 257]); - szOut = 4 * 257; - *reinterpret_cast(ret.get()) = hecl::SBig(256); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 256; ++j) { - if (j < palette->nentries) { - const png_const_sPLT_entryp entry = &palette->entries[j]; - if (palette->depth == 16) { - *cur++ = entry->red >> 8; - *cur++ = entry->green >> 8; - *cur++ = entry->blue >> 8; - *cur++ = entry->alpha >> 8; - } else { - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = entry->alpha; - } - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } else { - /* This is a C4 palette */ - ret.reset(new uint8_t[4 * 17]); - szOut = 4 * 17; - *reinterpret_cast(ret.get()) = hecl::SBig(16); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 16; ++j) { - if (j < palette->nentries) { - const png_const_sPLT_entryp entry = &palette->entries[j]; - if (palette->depth == 16) { - *cur++ = entry->red >> 8; - *cur++ = entry->green >> 8; - *cur++ = entry->blue >> 8; - *cur++ = entry->alpha >> 8; - } else { - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = entry->alpha; - } - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } - break; - } - } - } else { - png_colorp palettes2; - int colorCount; - if (png_get_PLTE(png, info, &palettes2, &colorCount) == PNG_INFO_PLTE) { - if (colorCount > 16) { - /* This is a C8 palette */ - ret.reset(new uint8_t[4 * 257]); - szOut = 4 * 257; - *reinterpret_cast(ret.get()) = hecl::SBig(256); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 256; ++j) { - if (j < colorCount) { - const png_const_colorp entry = &palettes2[j]; - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = 0xff; - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } else { - /* This is a C4 palette */ - ret.reset(new uint8_t[4 * 17]); - szOut = 4 * 17; - *reinterpret_cast(ret.get()) = hecl::SBig(16); - uint8_t* cur = ret.get() + 4; - for (int j = 0; j < 16; ++j) { - if (j < colorCount) { - const png_const_colorp entry = &palettes2[j]; - *cur++ = entry->red; - *cur++ = entry->green; - *cur++ = entry->blue; - *cur++ = 0xff; - } else { - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - *cur++ = 0; - } - } - } - } - } - return ret; -} - -static int GetNumPaletteEntriesForGCN(png_structp png, png_infop info) { - png_sPLT_tp palettes; - const int paletteCount = png_get_sPLT(png, info, &palettes); - if (paletteCount != 0) { - for (int i = 0; i < paletteCount; ++i) { - const png_const_sPLT_tp palette = &palettes[i]; - if (strncmp(palette->name, "GX_", 3) == 0) { - if (palette->nentries > 16) { - /* This is a C8 palette */ - return 256; - } else { - /* This is a C4 palette */ - return 16; - } - } - } - } else { - png_colorp palletes2; - int colorCount; - if (png_get_PLTE(png, info, &palletes2, &colorCount) == PNG_INFO_PLTE) { - if (colorCount > 16) { - /* This is a C8 palette */ - return 256; - } else { - /* This is a C4 palette */ - return 16; - } - } - } - return 0; -} - -bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), "rb"); - if (inf == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for reading"), inPath.getAbsolutePath()); - return false; - } - - /* Validate PNG */ - char header[8]; - std::fread(header, 1, sizeof(header), inf.get()); - if (png_sig_cmp((png_const_bytep)header, 0, 8)) { - Log.report(logvisor::Error, FMT_STRING("invalid PNG signature in '{}'"), inPath.getAbsolutePath()); - return false; - } - - /* Setup PNG reader */ - png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!pngRead) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng")); - return false; - } - png_infop info = png_create_info_struct(pngRead); - if (!info) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng info")); - png_destroy_read_struct(&pngRead, nullptr, nullptr); - return false; - } - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng I/O for '{}'"), - inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - png_init_io(pngRead, inf.get()); - png_set_sig_bytes(pngRead, 8); - - png_read_info(pngRead, info); - - const png_uint_32 width = png_get_image_width(pngRead, info); - const png_uint_32 height = png_get_image_height(pngRead, info); - const png_byte colorType = png_get_color_type(pngRead, info); - const png_byte bitDepth = png_get_bit_depth(pngRead, info); - - if (width < 4 || height < 4) { - Log.report(logvisor::Error, FMT_STRING("image must be 4x4 or larger")); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Disable mipmapping if metaforce_nomip embedded */ - bool mipmap = true; - png_text* textStruct; - int numText; - png_get_text(pngRead, info, &textStruct, &numText); - for (int i = 0; i < numText; ++i) { - if (std::strcmp(textStruct[i].key, "metaforce_nomip") == 0) { - mipmap = false; - } - } - if (colorType == PNG_COLOR_TYPE_PALETTE) { - mipmap = false; - } - - /* Compute mipmap levels */ - size_t numMips = 1; - if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) { - size_t index = std::min(width, height); - while (index >>= 1) { - ++numMips; - } - } - - if (bitDepth != 8) { - Log.report(logvisor::Error, FMT_STRING("'{}' is not 8 bits-per-channel"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - size_t rowSize = 0; - size_t nComps = 4; - int nPaletteEntries = 0; - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - rowSize = width; - nComps = 1; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - rowSize = width * 2; - nComps = 2; - break; - case PNG_COLOR_TYPE_RGB: - rowSize = width * 3; - nComps = 4; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - rowSize = width * 4; - nComps = 4; - break; - case PNG_COLOR_TYPE_PALETTE: - nPaletteEntries = GetNumPaletteEntriesForGCN(pngRead, info); - rowSize = width; - nComps = 1; - break; - default: - Log.report(logvisor::Error, FMT_STRING("unsupported color type in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Intermediate row-read buf (file components) */ - std::unique_ptr rowBuf; - if (colorType == PNG_COLOR_TYPE_RGB) - rowBuf.reset(new uint8_t[rowSize]); - - /* Final mipmapped buf (RGBA components) */ - std::unique_ptr bufOut; - size_t bufLen = 0; - if (numMips > 1) - bufLen = ComputeMippedTexelCount(width, height) * nComps; - else - bufLen = width * height * nComps; - bufOut.reset(new uint8_t[bufLen]); - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Fatal, FMT_STRING("unable to read image in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Track alpha values for DXT1 eligibility */ - bool doDXT1 = (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA) && width >= 4 && height >= 4; - - /* Read into mip0 image buffer */ - for (png_uint_32 r = 0; r < height; ++r) { - if (colorType == PNG_COLOR_TYPE_RGB) { - png_read_row(pngRead, rowBuf.get(), nullptr); - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 3; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase + 1]; - bufOut[outbase + 2] = rowBuf[inbase + 2]; - bufOut[outbase + 3] = 0xff; - } - } else { - png_read_row(pngRead, &bufOut[(r * width) * nComps], nullptr); - if (colorType == PNG_COLOR_TYPE_RGB_ALPHA) { - for (unsigned i = 0; i < width; ++i) { - const size_t outbase = (r * width + i) * nComps; - if (bufOut[outbase + 3] != 0 && bufOut[outbase + 3] != 255) { - doDXT1 = false; - } - } - } - } - } - - png_destroy_read_struct(&pngRead, &info, nullptr); - inf.reset(); - - /* Reduce mipmaps to minimum allowed dimensions */ - unsigned minDimX, minDimY; - if (doDXT1) { - minDimX = minDimY = 4; - } else { - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - minDimX = 8; - minDimY = 4; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - default: - minDimX = 4; - minDimY = 4; - break; - case PNG_COLOR_TYPE_PALETTE: { - if (nPaletteEntries == 256) { - minDimX = 8; - minDimY = 4; - } else { - minDimX = minDimY = 8; - } - break; - } - } - } - { - unsigned totalPixels = 0; - unsigned filterWidth = width; - unsigned filterHeight = height; - for (size_t i = 0; i < numMips; ++i) { - totalPixels += filterWidth * filterHeight; - if (filterWidth == minDimX || filterHeight == minDimY) { - numMips = i + 1; - break; - } - filterWidth /= 2; - filterHeight /= 2; - } - bufLen = totalPixels * nComps; - } - - /* Perform box-filter mipmap */ - std::unique_ptr compOut; - size_t compLen = 0; - if (numMips > 1) { - const uint8_t* filterIn = bufOut.get(); - uint8_t* filterOut = bufOut.get() + width * height * nComps; - unsigned filterWidth = width; - unsigned filterHeight = height; - for (size_t i = 1; i < numMips; ++i) { - BoxFilter(filterIn, nComps, filterWidth, filterHeight, filterOut, doDXT1); - filterIn += filterWidth * filterHeight * nComps; - filterWidth /= 2; - filterHeight /= 2; - filterOut += filterWidth * filterHeight * nComps; - } - } - - /* Do DXT1 compression */ - int format; - if (doDXT1) { - int filterWidth = width; - int filterHeight = height; - for (size_t i = 0; i < numMips; ++i) { - compLen += squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1); - if (filterWidth == 8 || filterHeight == 8) { - numMips = i + 1; - break; - } - filterWidth /= 2; - filterHeight /= 2; - } - - compOut.reset(new uint8_t[compLen]); - - filterWidth = width; - filterHeight = height; - const uint8_t* rgbaIn = bufOut.get(); - uint8_t* blocksOut = compOut.get(); - std::memset(blocksOut, 0, compLen); - for (size_t i = 0; i < numMips; ++i) { - const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1); - EncodeCMPR(rgbaIn, blocksOut, filterWidth, filterHeight); - rgbaIn += filterWidth * filterHeight * nComps; - blocksOut += thisLen; - filterWidth /= 2; - filterHeight /= 2; - } - - format = 10; - } else { - int filterWidth = width; - int filterHeight = height; - compLen = bufLen; - if (colorType == PNG_COLOR_TYPE_PALETTE) { - if (nPaletteEntries == 16) { - compLen /= 2; - } - compLen += 8 + nPaletteEntries * 2; - } - compOut.reset(new uint8_t[compLen]); - const uint8_t* rgbaIn = bufOut.get(); - uint8_t* dataOut = compOut.get(); - std::memset(dataOut, 0, compLen); - for (size_t i = 0; i < numMips; ++i) { - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - EncodeI8(rgbaIn, dataOut, filterWidth, filterHeight); - format = 1; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - EncodeIA8(rgbaIn, dataOut, filterWidth, filterHeight); - format = 3; - break; - case PNG_COLOR_TYPE_RGB: - case PNG_COLOR_TYPE_RGB_ALPHA: - EncodeRGBA8(rgbaIn, dataOut, filterWidth, filterHeight); - format = 9; - break; - case PNG_COLOR_TYPE_PALETTE: { - if (nPaletteEntries == 256) { - EncodeC8(pngRead, info, rgbaIn, dataOut, filterWidth, filterHeight); - format = 5; - } else { - EncodeC4(pngRead, info, rgbaIn, dataOut, filterWidth, filterHeight); - format = 4; - } - break; - } - default: - break; - } - rgbaIn += filterWidth * filterHeight * nComps; - dataOut += filterWidth * filterHeight * nComps; - filterWidth /= 2; - filterHeight /= 2; - } - } - - /* Do write out */ - athena::io::FileWriter outf(outPath.getAbsolutePath(), true, false); - if (outf.hasError()) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath()); - return false; - } - - outf.writeInt32Big(format); - outf.writeInt16Big(width); - outf.writeInt16Big(height); - outf.writeInt32Big(numMips); - outf.writeUBytes(compOut.get(), compLen); - - return true; -} - -bool TXTR::CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - auto inf = hecl::FopenUnique(inPath.getAbsolutePath().data(), "rb"); - if (inf == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for reading"), inPath.getAbsolutePath()); - return false; - } - - /* Validate PNG */ - char header[8]; - std::fread(header, 1, sizeof(header), inf.get()); - if (png_sig_cmp((png_const_bytep)header, 0, 8)) { - Log.report(logvisor::Error, FMT_STRING("invalid PNG signature in '{}'"), inPath.getAbsolutePath()); - return false; - } - - /* Setup PNG reader */ - png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!pngRead) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng")); - return false; - } - png_infop info = png_create_info_struct(pngRead); - if (!info) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng info")); - png_destroy_read_struct(&pngRead, nullptr, nullptr); - return false; - } - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Error, FMT_STRING("unable to initialize libpng I/O for '{}'"), - inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - png_init_io(pngRead, inf.get()); - png_set_sig_bytes(pngRead, 8); - - png_read_info(pngRead, info); - - const png_uint_32 width = png_get_image_width(pngRead, info); - const png_uint_32 height = png_get_image_height(pngRead, info); - const png_byte colorType = png_get_color_type(pngRead, info); - const png_byte bitDepth = png_get_bit_depth(pngRead, info); - - /* Disable mipmapping if metaforce_nomip embedded */ - bool mipmap = true; - png_text* textStruct; - int numText; - png_get_text(pngRead, info, &textStruct, &numText); - for (int i = 0; i < numText; ++i) { - if (std::strcmp(textStruct[i].key, "metaforce_nomip") == 0) { - mipmap = false; - } - } - if (colorType == PNG_COLOR_TYPE_PALETTE) { - mipmap = false; - } - - /* Compute mipmap levels */ - size_t numMips = 1; - if (mipmap && CountBits(width) == 1 && CountBits(height) == 1) { - size_t index = std::min(width, height); - while (index >>= 1) { - ++numMips; - } - } - - if (bitDepth != 8) { - Log.report(logvisor::Error, FMT_STRING("'{}' is not 8 bits-per-channel"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - std::unique_ptr paletteBuf; - size_t paletteSize = 0; - - size_t rowSize = 0; - size_t nComps = 4; - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - rowSize = width; - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - rowSize = width * 2; - break; - case PNG_COLOR_TYPE_RGB: - rowSize = width * 3; - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - rowSize = width * 4; - break; - case PNG_COLOR_TYPE_PALETTE: - rowSize = width; - nComps = 1; - paletteBuf = ReadPalette(pngRead, info, paletteSize); - break; - default: - Log.report(logvisor::Error, FMT_STRING("unsupported color type in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Intermediate row-read buf (file components) */ - std::unique_ptr rowBuf(new uint8_t[rowSize]); - - /* Final mipmapped buf (RGBA components) */ - std::unique_ptr bufOut; - size_t bufLen = 0; - if (numMips > 1) - bufLen = ComputeMippedTexelCount(width, height) * nComps; - else - bufLen = width * height * nComps; - bufOut.reset(new uint8_t[bufLen]); - - if (setjmp(png_jmpbuf(pngRead))) { - Log.report(logvisor::Fatal, FMT_STRING("unable to read image in '{}'"), inPath.getAbsolutePath()); - png_destroy_read_struct(&pngRead, &info, nullptr); - return false; - } - - /* Track alpha values for DXT1 eligibility */ - bool doDXT = (colorType == PNG_COLOR_TYPE_RGB || colorType == PNG_COLOR_TYPE_RGB_ALPHA) && width >= 4 && height >= 4; - bool doDXT3 = false; - - /* Read and make RGBA */ - for (int r = height - 1; r >= 0; --r) { - png_read_row(pngRead, rowBuf.get(), nullptr); - switch (colorType) { - case PNG_COLOR_TYPE_GRAY: - for (unsigned i = 0; i < width; ++i) { - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[i]; - bufOut[outbase + 1] = rowBuf[i]; - bufOut[outbase + 2] = rowBuf[i]; - bufOut[outbase + 3] = rowBuf[i]; - } - break; - case PNG_COLOR_TYPE_GRAY_ALPHA: - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 2; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase]; - bufOut[outbase + 2] = rowBuf[inbase]; - bufOut[outbase + 3] = rowBuf[inbase + 1]; - } - break; - case PNG_COLOR_TYPE_RGB: - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 3; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase + 1]; - bufOut[outbase + 2] = rowBuf[inbase + 2]; - bufOut[outbase + 3] = 0xff; - } - break; - case PNG_COLOR_TYPE_RGB_ALPHA: - for (unsigned i = 0; i < width; ++i) { - const size_t inbase = i * 4; - const size_t outbase = (r * width + i) * 4; - bufOut[outbase] = rowBuf[inbase]; - bufOut[outbase + 1] = rowBuf[inbase + 1]; - bufOut[outbase + 2] = rowBuf[inbase + 2]; - bufOut[outbase + 3] = rowBuf[inbase + 3]; - if (rowBuf[inbase + 3] != 0 && rowBuf[inbase + 3] != 255) - doDXT = false; - else if (rowBuf[inbase + 3] == 0) - doDXT3 = true; - } - break; - case PNG_COLOR_TYPE_PALETTE: - for (unsigned i = 0; i < width; ++i) - bufOut[r * width + i] = rowBuf[i]; - break; - default: - break; - } - } - - png_destroy_read_struct(&pngRead, &info, nullptr); - inf.reset(); - - /* Perform box-filter mipmap */ - if (numMips > 1) { - const uint8_t* filterIn = bufOut.get(); - uint8_t* filterOut = bufOut.get() + width * height * nComps; - unsigned filterWidth = width; - unsigned filterHeight = height; - for (size_t i = 1; i < numMips; ++i) { - BoxFilter(filterIn, nComps, filterWidth, filterHeight, filterOut, doDXT); - filterIn += filterWidth * filterHeight * nComps; - filterWidth /= 2; - filterHeight /= 2; - filterOut += filterWidth * filterHeight * nComps; - } - } - - /* Do DXT compression */ - std::unique_ptr compOut; - size_t compLen = 0; - if (doDXT) { - int compFlags = doDXT3 ? squish::kDxt3 : squish::kDxt1; - int filterWidth = width; - int filterHeight = height; - size_t i; - for (i = 0; i < numMips; ++i) { - compLen += squish::GetStorageRequirements(filterWidth, filterHeight, compFlags); - if (filterWidth == 4 || filterHeight == 4) { - ++i; - break; - } - filterWidth /= 2; - filterHeight /= 2; - } - numMips = i; - - compOut.reset(new uint8_t[compLen]); - - filterWidth = width; - filterHeight = height; - const uint8_t* rgbaIn = bufOut.get(); - uint8_t* blocksOut = compOut.get(); - for (i = 0; i < numMips; ++i) { - const int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, compFlags); - squish::CompressImage(rgbaIn, filterWidth, filterHeight, blocksOut, compFlags); - rgbaIn += filterWidth * filterHeight * nComps; - blocksOut += thisLen; - filterWidth /= 2; - filterHeight /= 2; - } - } - - /* Do write out */ - athena::io::FileWriter outf(outPath.getAbsolutePath(), true, false); - if (outf.hasError()) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), outPath.getAbsolutePath()); - return false; - } - - int format; - if (paletteBuf && paletteSize) - format = 17; - else if (compOut) - format = doDXT3 ? 19 : 18; - else - format = 16; - outf.writeInt32Big(format); - outf.writeInt16Big(width); - outf.writeInt16Big(height); - outf.writeInt32Big(numMips); - if (paletteBuf && paletteSize) - outf.writeUBytes(paletteBuf.get(), paletteSize); - if (compOut) - outf.writeUBytes(compOut.get(), compLen); - else - outf.writeUBytes(bufOut.get(), bufLen); - - return true; -} - -template -void DataSpec::TXTR::PaletteMeta::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"format"}, format, s); - Do(athena::io::PropId{"elementCount"}, elementCount, s); - Do(athena::io::PropId{"dolphinHash"}, dolphinHash, s); -} - -AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::PaletteMeta) - -std::string_view DataSpec::TXTR::PaletteMeta::DNAType() { return "DataSpec::TXTR::PaletteMeta"sv; } - -template -void DataSpec::TXTR::Meta::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"format"}, format, s); - Do(athena::io::PropId{"mips"}, mips, s); - Do(athena::io::PropId{"width"}, width, s); - Do(athena::io::PropId{"height"}, height, s); - Do(athena::io::PropId{"dolphinHash"}, dolphinHash, s); - Do(athena::io::PropId{"hasPalette"}, hasPalette, s); - if (hasPalette) - Do(athena::io::PropId{"palette"}, palette, s); -} - -AT_SPECIALIZE_DNA_YAML(DataSpec::TXTR::Meta) - -std::string_view DataSpec::TXTR::Meta::DNAType() { return "DataSpec::TXTR::Meta"sv; } - -static const atInt32 RetroToDol[11]{0, 1, 2, 3, 8, 9, -1, 4, 5, 6, 14}; - -TXTR::Meta TXTR::GetMetaData(DataSpec::PAKEntryReadStream& rs) { - const atUint32 retroFormat = rs.readUint32Big(); - const atUint32 format = RetroToDol[retroFormat]; - if (format == UINT32_MAX) - return {}; - - Meta meta; - meta.format = retroFormat; - meta.width = rs.readUint16Big(); - meta.height = rs.readUint16Big(); - meta.mips = rs.readUint32Big(); - atUint32 textureSize = meta.width * meta.height; - if (format == 8 || format == 9) { - meta.hasPalette = true; - PaletteMeta& palMeta = meta.palette; - palMeta.format = rs.readUint32Big(); - const atUint16 palWidth = rs.readUint16Big(); - const atUint16 palHeight = rs.readUint16Big(); - palMeta.elementCount = palWidth * palHeight; - const atUint32 palSize = atUint32(palWidth * palHeight * 2); - if (format == 8) - textureSize /= 2; - std::unique_ptr palData(new u8[palSize]); - rs.readUBytesToBuf(palData.get(), palSize); - palMeta.dolphinHash = XXH64(palData.get(), palSize, 0); - } else { - switch (format) { - case 0: // I4 - case 14: // DXT1 - textureSize /= 2; - break; - case 3: - case 4: - case 5: - textureSize *= 2; - break; - case 6: - textureSize *= 4; - break; - default: - break; - } - } - std::unique_ptr textureData(new u8[textureSize]); - rs.readUBytesToBuf(textureData.get(), textureSize); - meta.dolphinHash = XXH64(textureData.get(), textureSize, 0); - - return meta; -} - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/TXTR.hpp b/DataSpec/DNACommon/TXTR.hpp deleted file mode 100644 index 8a69e6efb..000000000 --- a/DataSpec/DNACommon/TXTR.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec { -class PAKEntryReadStream; - -struct TXTR { - struct PaletteMeta : BigDNAVYaml { - AT_DECL_EXPLICIT_DNA_YAMLV - Value format = UINT_MAX; - Value elementCount = 0; - Value dolphinHash = 0; - }; - struct Meta : BigDNAVYaml { - AT_DECL_EXPLICIT_DNA_YAMLV - Value format = UINT_MAX; - Value mips = 0; - Value width = 0; - Value height = 0; - Value dolphinHash = 0; - Value hasPalette = false; - PaletteMeta palette; - }; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); - static bool CookPC(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); - static TXTR::Meta GetMetaData(PAKEntryReadStream& rs); -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweak.hpp b/DataSpec/DNACommon/Tweaks/ITweak.hpp deleted file mode 100644 index 7a3f04709..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweak.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace hecl { -class CVarManager; -} -namespace DataSpec { -struct ITweak : BigDNA { - - virtual void initCVars(hecl::CVarManager*) {} -}; -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/ITweakPlayerControl.hpp b/DataSpec/DNACommon/Tweaks/ITweakPlayerControl.hpp deleted file mode 100644 index 6f523e10c..000000000 --- a/DataSpec/DNACommon/Tweaks/ITweakPlayerControl.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "ITweak.hpp" - -namespace DataSpec { - -struct ITweakPlayerControl : ITweak { - virtual atUint32 GetMapping(atUint32) const = 0; -}; - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/Tweaks/TweakWriter.hpp b/DataSpec/DNACommon/Tweaks/TweakWriter.hpp deleted file mode 100644 index fd09d4c3e..000000000 --- a/DataSpec/DNACommon/Tweaks/TweakWriter.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../PAK.hpp" - -namespace DataSpec { - -template -bool WriteTweak(const T& tweak, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - tweak.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} - -template -bool ExtractTweak(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - T tweak; - tweak.read(rs); - athena::io::ToYAMLStream(tweak, writer); - return true; - } - return false; -} - -} // namespace DataSpec diff --git a/DataSpec/DNACommon/WPSC.cpp b/DataSpec/DNACommon/WPSC.cpp deleted file mode 100644 index c801d8789..000000000 --- a/DataSpec/DNACommon/WPSC.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "DataSpec/DNACommon/WPSC.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAParticle { - -template struct PPImpl<_WPSM>; -template struct PPImpl<_WPSM>; - -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) -AT_SUBSPECIALIZE_DNA_YAML(PPImpl<_WPSM>) - -template <> -std::string_view WPSM::DNAType() { - return "WPSM"sv; -} - -template <> -std::string_view WPSM::DNAType() { - return "WPSM"sv; -} - -template -bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - athena::io::FileWriter writer(outPath.getAbsolutePath()); - if (writer.isOpen()) { - WPSM wpsm; - wpsm.read(rs); - athena::io::ToYAMLStream(wpsm, writer); - return true; - } - return false; -} -template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); -template bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath(), true, false); - if (w.hasError()) - return false; - wpsm.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} -template bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); -template bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNACommon/WPSC.def b/DataSpec/DNACommon/WPSC.def deleted file mode 100644 index 04b6ce33f..000000000 --- a/DataSpec/DNACommon/WPSC.def +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef ENTRY -#define ENTRY(name, identifier) -#endif - -#ifndef INT_ENTRY -#define INT_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef U32_ENTRY -#define U32_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef REAL_ENTRY -#define REAL_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef VECTOR_ENTRY -#define VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef MOD_VECTOR_ENTRY -#define MOD_VECTOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef COLOR_ENTRY -#define COLOR_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef UV_ENTRY -#define UV_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef RES_ENTRY -#define RES_ENTRY(name, identifier) ENTRY(name, identifier) -#endif - -#ifndef BOOL_ENTRY -#define BOOL_ENTRY(name, identifier, def) ENTRY(name, identifier) -#endif - -VECTOR_ENTRY('IORN', x0_IORN) -VECTOR_ENTRY('IVEC', x4_IVEC) -VECTOR_ENTRY('PSOV', x8_PSOV) -MOD_VECTOR_ENTRY('PSVM', xc_PSVM) -INT_ENTRY('PSLT', x14_PSLT) -VECTOR_ENTRY('PSCL', x18_PSCL) -COLOR_ENTRY('PCOL', x1c_PCOL) -VECTOR_ENTRY('POFS', x20_POFS) -VECTOR_ENTRY('OFST', x24_OFST) - -REAL_ENTRY('TRAT', x30_TRAT) -RES_ENTRY('APSM', x34_APSM) -RES_ENTRY('APS2', x44_APS2) -RES_ENTRY('ASW1', x54_ASW1) -RES_ENTRY('ASW2', x64_ASW2) -RES_ENTRY('ASW3', x74_ASW3) -RES_ENTRY('OHEF', x84_OHEF) -RES_ENTRY('COLR', x94_COLR) -U32_ENTRY('PJFX', xa8_PJFX) -REAL_ENTRY('RNGE', xac_RNGE) -REAL_ENTRY('FOFF', xb0_FOFF) - -BOOL_ENTRY('VMD2', x10_VMD2, false) -BOOL_ENTRY('APSO', x28_APSO, false) -BOOL_ENTRY('HOMG', x29_HOMG, false) -BOOL_ENTRY('AP11', x2a_AP11, false) -BOOL_ENTRY('AP21', x2b_AP21, false) -BOOL_ENTRY('AS11', x2c_AS11, false) -BOOL_ENTRY('AS12', x2d_AS12, false) -BOOL_ENTRY('AS13', x2e_AS13, false) -BOOL_ENTRY('EWTR', xa4_EWTR, true) -BOOL_ENTRY('LWTR', xa5_LWTR, true) -BOOL_ENTRY('SWTR', xa6_SWTR, true) -BOOL_ENTRY('FC60', xunk_FC60, false) -BOOL_ENTRY('SPS1', xunk_SPS1, false) -BOOL_ENTRY('SPS2', xunk_SPS2, false) - -#undef ENTRY -#undef INT_ENTRY -#undef U32_ENTRY -#undef REAL_ENTRY -#undef VECTOR_ENTRY -#undef MOD_VECTOR_ENTRY -#undef COLOR_ENTRY -#undef UV_ENTRY -#undef RES_ENTRY -#undef BOOL_ENTRY diff --git a/DataSpec/DNACommon/WPSC.hpp b/DataSpec/DNACommon/WPSC.hpp deleted file mode 100644 index 8b1490b02..000000000 --- a/DataSpec/DNACommon/WPSC.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ParticleCommon.hpp" - -namespace DataSpec { -class PAKEntryReadStream; -} - -namespace hecl { -class ProjectPath; -} - -namespace DataSpec::DNAParticle { - -template -struct _WPSM { - static constexpr ParticleType Type = ParticleType::WPSM; - -#define INT_ENTRY(name, identifier) IntElementFactory identifier; -#define U32_ENTRY(name, identifier) uint32_t identifier = ~0; -#define REAL_ENTRY(name, identifier) RealElementFactory identifier; -#define VECTOR_ENTRY(name, identifier) VectorElementFactory identifier; -#define MOD_VECTOR_ENTRY(name, identifier) ModVectorElementFactory identifier; -#define COLOR_ENTRY(name, identifier) ColorElementFactory identifier; -#define UV_ENTRY(name, identifier) UVElementFactory identifier; -#define RES_ENTRY(name, identifier) ChildResourceFactory identifier; -#define BOOL_ENTRY(name, identifier, def) bool identifier = def; -#include "WPSC.def" - - template - void constexpr Enumerate(_Func f) { -#define ENTRY(name, identifier) f(FOURCC(name), identifier); -#define BOOL_ENTRY(name, identifier, def) f(FOURCC(name), identifier, def); -#include "WPSC.def" - } - - template - bool constexpr Lookup(FourCC fcc, _Func f) { - switch (fcc.toUint32()) { -#define ENTRY(name, identifier) \ - case SBIG(name): \ - f(identifier); \ - return true; -#include "WPSC.def" - default: - return false; - } - } -}; -template -using WPSM = PPImpl<_WPSM>; - -template -bool ExtractWPSM(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - -template -bool WriteWPSM(const WPSM& wpsm, const hecl::ProjectPath& outPath); - -} // namespace DataSpec::DNAParticle diff --git a/DataSpec/DNAMP1/AFSM.cpp b/DataSpec/DNAMP1/AFSM.cpp deleted file mode 100644 index 8ddefe59c..000000000 --- a/DataSpec/DNAMP1/AFSM.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "AFSM.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void AFSM::State::Transition::Enumerate(typename Read::StreamT& r) { - triggerCount = r.readUint32Big(); - int i = 0; - r.enumerate(triggers, triggerCount, [&](athena::io::IStreamReader& in, Trigger& tr) { - tr.first = i == 0; - tr.read(in); - i++; - }); -} - -template <> -void AFSM::State::Transition::Enumerate(typename Write::StreamT& w) { - w.writeInt32Big(triggerCount); - w.enumerate(triggers); -} - -template <> -void AFSM::State::Transition::Enumerate(typename ReadYaml::StreamT& r) { - int i = 0; - /* triggers */ - triggerCount = r.enumerate("triggers", triggers, [&](athena::io::YAMLDocReader& in, Trigger& tr) { - tr.first = i == 0; - tr.read(in); - i++; - }); -} - -template <> -void AFSM::State::Transition::Enumerate(typename WriteYaml::StreamT& w) { - /* triggers */ - w.enumerate("triggers", triggers); -} - -template <> -void AFSM::State::Transition::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - for (const Trigger& trig : triggers) - trig.binarySize(s); -} - -std::string_view AFSM::State::Transition::DNAType() { return "DNAMP1::AFSM::Transition"sv; } - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* name */ - name = __dna_reader.readString(-1); - /* parameter */ - parameter = __dna_reader.readFloatBig(); - if (first) { - /* targetState */ - targetState = __dna_reader.readUint32Big(); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* name */ - __dna_writer.writeString(name, -1); - /* parameter */ - __dna_writer.writeFloatBig(parameter); - if (first) { - /* targetState */ - __dna_writer.writeUint32Big(targetState); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::YAMLDocReader& __dna_docin) { - /* name */ - name = __dna_docin.readString("name"); - /* parameter */ - parameter = __dna_docin.readFloat("parameter"); - if (first) { - /* targetState */ - targetState = __dna_docin.readUint32("targetState"); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(athena::io::YAMLDocWriter& __dna_docout) { - /* name */ - __dna_docout.writeString("name", name); - /* parameter */ - __dna_docout.writeFloat("parameter", parameter); - if (first) { - /* targetState */ - __dna_docout.writeUint32("targetState", targetState); - } -} - -template <> -void AFSM::State::Transition::Trigger::Enumerate(size_t& __isz) { - __isz += name.size() + 1; - __isz += (first ? 8 : 4); -} - -std::string_view AFSM::State::Transition::Trigger::DNAType() { return "DNAMP1::AFSM::State::Transition::Trigger"sv; } - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/AFSM.hpp b/DataSpec/DNAMP1/AFSM.hpp deleted file mode 100644 index 5dd6e2684..000000000 --- a/DataSpec/DNAMP1/AFSM.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct AFSM : public BigDNA { - AT_DECL_DNA_YAML - Value stateCount; - Vector, AT_DNA_COUNT(stateCount)> stateNames; - Value triggerCount; - - struct State : public BigDNA { - AT_DECL_DNA_YAML - Value transitionCount; - struct Transition : public BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - Value triggerCount; - - struct Trigger : public BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - bool first = false; - String<-1> name; - Value parameter; - Value targetState; - }; - Vector triggers; - }; - Vector transitions; - }; - Vector states; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - AFSM afsm; - afsm.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(afsm, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - AFSM afsm; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(afsm, reader); - athena::io::FileWriter ws(outPath.getAbsolutePath()); - afsm.write(ws); - return true; - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/AGSC.cpp b/DataSpec/DNAMP1/AGSC.cpp deleted file mode 100644 index 0078f94eb..000000000 --- a/DataSpec/DNAMP1/AGSC.cpp +++ /dev/null @@ -1,266 +0,0 @@ -#include "AGSC.hpp" -#include "amuse/AudioGroup.hpp" -#include "amuse/AudioGroupData.hpp" - -extern "C" const uint8_t Atomic_H[]; -extern "C" const uint8_t BetaBeetle_H[]; -extern "C" const uint8_t Bird_H[]; -extern "C" const uint8_t BloodFlower_H[]; -extern "C" const uint8_t Burrower_H[]; -extern "C" const uint8_t ChozoGhost_H[]; -extern "C" const uint8_t ChubbWeed_H[]; -extern "C" const uint8_t CineBoots_H[]; -extern "C" const uint8_t CineGeneral_H[]; -extern "C" const uint8_t CineGun_H[]; -extern "C" const uint8_t CineMorphball_H[]; -extern "C" const uint8_t CineSuit_H[]; -extern "C" const uint8_t CineVisor_H[]; -extern "C" const uint8_t Crater_H[]; -extern "C" const uint8_t Crystallite_H[]; -extern "C" const uint8_t Drones_H[]; -extern "C" const uint8_t EliteSpacePirate_H[]; -extern "C" const uint8_t FireFlea_H[]; -extern "C" const uint8_t Flaaghra_H[]; -extern "C" const uint8_t FlickerBat_H[]; -extern "C" const uint8_t FlyingPirate_H[]; -extern "C" const uint8_t FrontEnd_H[]; -extern "C" const uint8_t GagantuanBeatle_H[]; -extern "C" const uint8_t Gnats_H[]; -extern "C" const uint8_t Gryzbee_H[]; -extern "C" const uint8_t IceCrack_H[]; -extern "C" const uint8_t IceWorld_H[]; -extern "C" const uint8_t InjuredPirates_H[]; -extern "C" const uint8_t IntroBoss_H[]; -extern "C" const uint8_t IntroWorld_H[]; -extern "C" const uint8_t JellyZap_H[]; -extern "C" const uint8_t LavaWorld_H[]; -extern "C" const uint8_t Magdolite_H[]; -extern "C" const uint8_t Metaree_H[]; -extern "C" const uint8_t MetroidPrime_H[]; -extern "C" const uint8_t Metroid_H[]; -extern "C" const uint8_t MinesWorld_H[]; -extern "C" const uint8_t MiscSamus_H[]; -extern "C" const uint8_t Misc_H[]; -extern "C" const uint8_t OmegaPirate_H[]; -extern "C" const uint8_t OverWorld_H[]; -extern "C" const uint8_t Parasite_H[]; -extern "C" const uint8_t PhazonGun_H[]; -extern "C" const uint8_t Phazon_H[]; -extern "C" const uint8_t PuddleSpore_H[]; -extern "C" const uint8_t PuddleToad_H[]; -extern "C" const uint8_t Puffer_H[]; -extern "C" const uint8_t ReactorDoor_H[]; -extern "C" const uint8_t Ridley_H[]; -extern "C" const uint8_t Ripper_H[]; -extern "C" const uint8_t RuinsWorld_H[]; -extern "C" const uint8_t SamusShip_H[]; -extern "C" const uint8_t Scarab_H[]; -extern "C" const uint8_t Seedling_H[]; -extern "C" const uint8_t SheeGoth_H[]; -extern "C" const uint8_t SnakeWeed_H[]; -extern "C" const uint8_t Sova_H[]; -extern "C" const uint8_t SpacePirate_H[]; -extern "C" const uint8_t SpankWeed_H[]; -extern "C" const uint8_t Thardus_H[]; -extern "C" const uint8_t TheEnd_H[]; -extern "C" const uint8_t Torobyte_H[]; -extern "C" const uint8_t Triclops_H[]; -extern "C" const uint8_t Turret_H[]; -extern "C" const uint8_t UI_H[]; -extern "C" const uint8_t WarWasp_H[]; -extern "C" const uint8_t Weapons_H[]; -extern "C" const uint8_t ZZZ_H[]; -extern "C" const uint8_t Zoomer_H[]; -extern "C" const uint8_t lumigek_H[]; -extern "C" const uint8_t test_H[]; - -namespace DataSpec::DNAMP1 { - -using namespace std::literals; - -static const std::pair Headers[] = {{"Atomic"sv, Atomic_H}, - {"BetaBeetle"sv, BetaBeetle_H}, - {"Bird"sv, Bird_H}, - {"BloodFlower"sv, BloodFlower_H}, - {"Burrower"sv, Burrower_H}, - {"ChozoGhost"sv, ChozoGhost_H}, - {"ChubbWeed"sv, ChubbWeed_H}, - {"CineBoots"sv, CineBoots_H}, - {"CineGeneral"sv, CineGeneral_H}, - {"CineGun"sv, CineGun_H}, - {"CineMorphball"sv, CineMorphball_H}, - {"CineSuit"sv, CineSuit_H}, - {"CineVisor"sv, CineVisor_H}, - {"Crater"sv, Crater_H}, - {"Crystallite"sv, Crystallite_H}, - {"Drones"sv, Drones_H}, - {"EliteSpacePirate"sv, EliteSpacePirate_H}, - {"FireFlea"sv, FireFlea_H}, - {"Flaaghra"sv, Flaaghra_H}, - {"FlickerBat"sv, FlickerBat_H}, - {"FlyingPirate"sv, FlyingPirate_H}, - {"FrontEnd"sv, FrontEnd_H}, - {"GagantuanBeatle"sv, GagantuanBeatle_H}, - {"Gnats"sv, Gnats_H}, - {"Gryzbee"sv, Gryzbee_H}, - {"IceCrack"sv, IceCrack_H}, - {"IceWorld"sv, IceWorld_H}, - {"InjuredPirates"sv, InjuredPirates_H}, - {"IntroBoss"sv, IntroBoss_H}, - {"IntroWorld"sv, IntroWorld_H}, - {"JellyZap"sv, JellyZap_H}, - {"LavaWorld"sv, LavaWorld_H}, - {"Magdolite"sv, Magdolite_H}, - {"Metaree"sv, Metaree_H}, - {"MetroidPrime"sv, MetroidPrime_H}, - {"Metroid"sv, Metroid_H}, - {"MinesWorld"sv, MinesWorld_H}, - {"MiscSamus"sv, MiscSamus_H}, - {"Misc"sv, Misc_H}, - {"OmegaPirate"sv, OmegaPirate_H}, - {"OverWorld"sv, OverWorld_H}, - {"Parasite"sv, Parasite_H}, - {"Phazon"sv, Phazon_H}, - {"PhazonGun"sv, PhazonGun_H}, - {"PuddleSpore"sv, PuddleSpore_H}, - {"PuddleToad"sv, PuddleToad_H}, - {"Puffer"sv, Puffer_H}, - {"ReactorDoor"sv, ReactorDoor_H}, - {"Ridley"sv, Ridley_H}, - {"Ripper"sv, Ripper_H}, - {"RuinsWorld"sv, RuinsWorld_H}, - {"SamusShip"sv, SamusShip_H}, - {"Scarab"sv, Scarab_H}, - {"Seedling"sv, Seedling_H}, - {"SheeGoth"sv, SheeGoth_H}, - {"SnakeWeed"sv, SnakeWeed_H}, - {"Sova"sv, Sova_H}, - {"SpacePirate"sv, SpacePirate_H}, - {"SpankWeed"sv, SpankWeed_H}, - {"Thardus"sv, Thardus_H}, - {"TheEnd"sv, TheEnd_H}, - {"Torobyte"sv, Torobyte_H}, - {"Triclops"sv, Triclops_H}, - {"Turret"sv, Turret_H}, - {"UI"sv, UI_H}, - {"WarWasp"sv, WarWasp_H}, - {"Weapons"sv, Weapons_H}, - {"ZZZ"sv, ZZZ_H}, - {"Zoomer"sv, Zoomer_H}, - {"lumigek"sv, lumigek_H}, - {"test"sv, test_H}}; - -bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) { - dir.makeDirChain(true); - - Header head; - head.read(rs); - - uint32_t poolLen = rs.readUint32Big(); - auto pool = rs.readUBytes(poolLen); - - uint32_t projLen = rs.readUint32Big(); - auto proj = rs.readUBytes(projLen); - - uint32_t sampLen = rs.readUint32Big(); - auto samp = rs.readUBytes(sampLen); - - uint32_t sdirLen = rs.readUint32Big(); - auto sdir = rs.readUBytes(sdirLen); - - amuse::AudioGroupData data(proj.get(), projLen, pool.get(), poolLen, sdir.get(), sdirLen, samp.get(), sampLen, - amuse::GCNDataTag{}); - - /* Load into amuse representation */ - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - amuse::AudioGroupDatabase group(data); - group.setGroupPath(dir.getAbsolutePath()); - - /* Extract samples */ - group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp()); - - /* Import C headers */ - auto search = std::lower_bound(std::cbegin(Headers), std::cend(Headers), head.groupName, - [](const auto& a, const auto& b) { return a.first < b; }); - if (search != std::cend(Headers) && search->first == head.groupName) - group.importCHeader((char*)search->second); - - /* Write out project/pool */ - { - auto projd = group.getProj().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!project.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(projd.data(), projd.size()); - } - - { - auto poold = group.getPool().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!pool.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(poold.data(), poold.size()); - } - - return true; -} - -static std::atomic_bool DidCook = {false}; - -bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& refOutPath) { - /* This will cook all AGSCs in the local directory, ensuring unique ObjectIDs - * across all Amuse subprojects */ - if (DidCook.exchange(true)) - return true; /* We've already cooked all AGSCs */ - - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - - auto parentDir = dir.getParentPath(); - auto outParentDir = refOutPath.getParentPath(); - for (const auto& ent : dir.getParentPath().enumerateDir()) { - if (!ent.m_isDir) - continue; - hecl::ProjectPath path(parentDir, ent.m_name); - if (IsPathAudioGroup(path)) { - hecl::ProjectPath outPath(outParentDir, ent.m_name); - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - - Header head; - head.audioDir = "Audio/"sv; - auto lastComp = path.getLastComponent(); - auto str = fmt::format(FMT_STRING("_{:8X}"), path.parsedHash32()); - auto it = lastComp.rfind(str); - if (it != std::string_view::npos) { - lastComp = lastComp.substr(0, it); - } - head.groupName = lastComp; - head.write(w); - - amuse::AudioGroupDatabase group(path.getAbsolutePath()); - - auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir()); - auto pool = group.getPool().toData(); - auto sdirSamp = group.getSdir().toGCNData(group); - - w.writeUint32Big(pool.size()); - w.writeUBytes(pool.data(), pool.size()); - - w.writeUint32Big(proj.size()); - w.writeUBytes(proj.data(), proj.size()); - - w.writeUint32Big(sdirSamp.second.size()); - w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size()); - - w.writeUint32Big(sdirSamp.first.size()); - w.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size()); - } - } - - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/AGSC.hpp b/DataSpec/DNAMP1/AGSC.hpp deleted file mode 100644 index 7c480e5e5..000000000 --- a/DataSpec/DNAMP1/AGSC.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -class AGSC { -public: - struct Header : BigDNA { - AT_DECL_DNA - String<-1> audioDir; - String<-1> groupName; - }; - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ANCS.cpp b/DataSpec/DNAMP1/ANCS.cpp deleted file mode 100644 index 3de05dd7d..000000000 --- a/DataSpec/DNAMP1/ANCS.cpp +++ /dev/null @@ -1,1442 +0,0 @@ -#include "ANCS.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP1; -extern hecl::Database::DataSpecEntry SpecEntMP1PC; - -namespace DNAMP1 { - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::IStreamReader& reader) { - parmType = reader.readUint32Big(); - weightFunction = reader.readUint32Big(); - weight = reader.readFloatBig(); - switch (DataType(parmType)) { - case DataType::Int32: - range[0].int32 = reader.readInt32Big(); - range[1].int32 = reader.readInt32Big(); - break; - case DataType::UInt32: - case DataType::Enum: - range[0].uint32 = reader.readUint32Big(); - range[1].uint32 = reader.readUint32Big(); - break; - case DataType::Float: - range[0].float32 = reader.readFloatBig(); - range[1].float32 = reader.readFloatBig(); - break; - case DataType::Bool: - range[0].bool1 = reader.readBool(); - range[1].bool1 = reader.readBool(); - break; - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::IStreamWriter& writer) { - writer.writeUint32Big(parmType); - writer.writeUint32Big(weightFunction); - writer.writeFloatBig(weight); - switch (DataType(parmType)) { - case DataType::Int32: - writer.writeInt32Big(range[0].int32); - writer.writeInt32Big(range[1].int32); - break; - case DataType::UInt32: - case DataType::Enum: - writer.writeUint32Big(range[0].uint32); - writer.writeUint32Big(range[1].uint32); - break; - case DataType::Float: - writer.writeFloatBig(range[0].float32); - writer.writeFloatBig(range[1].float32); - break; - case DataType::Bool: - writer.writeBool(range[0].bool1); - writer.writeBool(range[1].bool1); - break; - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate(size_t& __isz) { - __isz += 12; - switch (DataType(parmType)) { - case DataType::Int32: - case DataType::UInt32: - case DataType::Enum: - case DataType::Float: - __isz += 8; - break; - case DataType::Bool: - __isz += 2; - break; - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::YAMLDocReader& reader) { - parmType = reader.readUint32("parmType"); - weightFunction = reader.readUint32("weightFunction"); - weight = reader.readFloat("weight"); - size_t parmValCount; - if (auto v = reader.enterSubVector("range", parmValCount)) { - switch (DataType(parmType)) { - case DataType::Int32: - range[0].int32 = reader.readInt32(); - range[1].int32 = reader.readInt32(); - break; - case DataType::UInt32: - case DataType::Enum: - range[0].uint32 = reader.readUint32(); - range[1].uint32 = reader.readUint32(); - break; - case DataType::Float: - range[0].float32 = reader.readFloat(); - range[1].float32 = reader.readFloat(); - break; - case DataType::Bool: - range[0].bool1 = reader.readBool(); - range[1].bool1 = reader.readBool(); - break; - default: - break; - } - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::Enumerate( - athena::io::YAMLDocWriter& writer) { - writer.writeUint32("parmType", parmType); - writer.writeUint32("weightFunction", weightFunction); - writer.writeFloat("weight", weight); - if (auto v = writer.enterSubVector("range")) { - switch (DataType(parmType)) { - case DataType::Int32: - writer.writeInt32(range[0].int32); - writer.writeInt32(range[1].int32); - break; - case DataType::UInt32: - case DataType::Enum: - writer.writeUint32(range[0].uint32); - writer.writeUint32(range[1].uint32); - break; - case DataType::Float: - writer.writeFloat(range[0].float32); - writer.writeFloat(range[1].float32); - break; - case DataType::Bool: - writer.writeBool(range[0].bool1); - writer.writeBool(range[1].bool1); - break; - } - } -} - -std::string_view ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::DNAType() { - return "DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo"sv; -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::IStreamReader& reader) { - id = reader.readUint32Big(); - atUint32 parmInfoCount = reader.readUint32Big(); - atUint32 animInfoCount = reader.readUint32Big(); - - reader.enumerate(parmInfos, parmInfoCount); - - animInfos.clear(); - animInfos.reserve(animInfoCount); - reader.enumerate(animInfos, animInfoCount, - [this, parmInfoCount](athena::io::IStreamReader& reader, AnimInfo& ai) { - ai.id = reader.readUint32Big(); - ai.parmVals.reserve(parmInfoCount); - for (const ParmInfo& pi : parmInfos) { - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - ai.parmVals.emplace_back(reader.readInt32Big()); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - ai.parmVals.emplace_back(reader.readUint32Big()); - break; - case ParmInfo::DataType::Float: - ai.parmVals.emplace_back(reader.readFloatBig()); - break; - case ParmInfo::DataType::Bool: - ai.parmVals.emplace_back(reader.readBool()); - break; - default: - break; - } - } - }); -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::IStreamWriter& writer) { - writer.writeUint32Big(id); - writer.writeUint32Big(parmInfos.size()); - writer.writeUint32Big(animInfos.size()); - - for (const ParmInfo& pi : parmInfos) - pi.write(writer); - - for (const AnimInfo& ai : animInfos) { - writer.writeUint32Big(ai.id); - auto it = ai.parmVals.begin(); - for (const ParmInfo& pi : parmInfos) { - ParmInfo::Parm pVal; - if (it != ai.parmVals.end()) - pVal = *it++; - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - writer.writeInt32Big(pVal.int32); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - writer.writeUint32Big(pVal.uint32); - break; - case ParmInfo::DataType::Float: - writer.writeFloatBig(pVal.float32); - break; - case ParmInfo::DataType::Bool: - writer.writeBool(pVal.bool1); - break; - default: - break; - } - } - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate(size_t& __isz) { - __isz += 12; - for (const ParmInfo& pi : parmInfos) - pi.binarySize(__isz); - - __isz += animInfos.size() * 4; - for (const ParmInfo& pi : parmInfos) { - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - case ParmInfo::DataType::Float: - __isz += animInfos.size() * 4; - break; - case ParmInfo::DataType::Bool: - __isz += animInfos.size(); - break; - default: - break; - } - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::YAMLDocReader& reader) { - id = reader.readUint32("id"); - - size_t parmInfoCount = reader.enumerate("parmInfos", parmInfos); - - reader.enumerate("animInfos", animInfos, - [this, parmInfoCount](athena::io::YAMLDocReader& reader, AnimInfo& ai) { - ai.id = reader.readUint32("id"); - ai.parmVals.reserve(parmInfoCount); - size_t parmValCount; - if (auto v = reader.enterSubVector("parms", parmValCount)) { - for (const ParmInfo& pi : parmInfos) { - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - ai.parmVals.emplace_back(reader.readInt32()); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - ai.parmVals.emplace_back(reader.readUint32()); - break; - case ParmInfo::DataType::Float: - ai.parmVals.emplace_back(reader.readFloat()); - break; - case ParmInfo::DataType::Bool: - ai.parmVals.emplace_back(reader.readBool()); - break; - default: - break; - } - } - } - }); -} - -template <> -void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::Enumerate( - athena::io::YAMLDocWriter& writer) { - writer.writeUint32("id", id); - - writer.enumerate("parmInfos", parmInfos); - - writer.enumerate("animInfos", animInfos, [this](athena::io::YAMLDocWriter& writer, const AnimInfo& ai) { - writer.writeUint32("id", ai.id); - auto it = ai.parmVals.begin(); - if (auto v = writer.enterSubVector("parms")) { - for (const ParmInfo& pi : parmInfos) { - ParmInfo::Parm pVal; - if (it != ai.parmVals.end()) - pVal = *it++; - switch (ParmInfo::DataType(pi.parmType)) { - case ParmInfo::DataType::Int32: - writer.writeInt32(pVal.int32); - break; - case ParmInfo::DataType::UInt32: - case ParmInfo::DataType::Enum: - writer.writeUint32(pVal.uint32); - break; - case ParmInfo::DataType::Float: - writer.writeFloat(pVal.float32); - break; - case ParmInfo::DataType::Bool: - writer.writeBool(pVal.bool1); - break; - default: - break; - } - } - } - }); -} - -std::string_view ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::DNAType() { - return "DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState"sv; -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::IStreamReader& reader) { - idx = reader.readUint32Big(); - atUint16 sectionCount = reader.readUint16Big(); - name = reader.readString(); - cmdl.read(reader); - cskr.read(reader); - cinf.read(reader); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - pasDatabase.read(reader); - - atUint32 partCount = reader.readUint32Big(); - reader.enumerate(partResData.part, partCount); - - atUint32 swhcCount = reader.readUint32Big(); - reader.enumerate(partResData.swhc, swhcCount); - - atUint32 unkCount = reader.readUint32Big(); - reader.enumerate(partResData.unk, unkCount); - - partResData.elsc.clear(); - if (sectionCount > 5) { - atUint32 elscCount = reader.readUint32Big(); - reader.enumerate(partResData.elsc, elscCount); - } - - unk1 = reader.readUint32Big(); - - animAABBs.clear(); - if (sectionCount > 1) { - atUint32 aabbCount = reader.readUint32Big(); - reader.enumerate(animAABBs, aabbCount); - } - - effects.clear(); - if (sectionCount > 2) { - atUint32 effectCount = reader.readUint32Big(); - reader.enumerate(effects, effectCount); - } - - if (sectionCount > 3) { - cmdlIce.read(reader); - cskrIce.read(reader); - } - - animIdxs.clear(); - if (sectionCount > 4) { - atUint32 aidxCount = reader.readUint32Big(); - reader.enumerateBig(animIdxs, aidxCount); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::IStreamWriter& writer) { - writer.writeUint32Big(idx); - - atUint16 sectionCount; - if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16Big(sectionCount); - - writer.writeString(name); - cmdl.write(writer); - cskr.write(writer); - cinf.write(writer); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - pasDatabase.write(writer); - - writer.writeUint32Big(partResData.part.size()); - writer.enumerate(partResData.part); - - writer.writeUint32Big(partResData.swhc.size()); - writer.enumerate(partResData.swhc); - - writer.writeUint32Big(partResData.unk.size()); - writer.enumerate(partResData.unk); - - if (sectionCount > 5) { - writer.writeUint32Big(partResData.elsc.size()); - writer.enumerate(partResData.elsc); - } - - writer.writeUint32Big(unk1); - - if (sectionCount > 1) { - writer.writeUint32Big(animAABBs.size()); - writer.enumerate(animAABBs); - } - - if (sectionCount > 2) { - writer.writeUint32Big(effects.size()); - writer.enumerate(effects); - } - - if (sectionCount > 3) { - cmdlIce.write(writer); - cskrIce.write(writer); - } - - if (sectionCount > 4) { - writer.writeUint32Big(animIdxs.size()); - for (atUint32 idx : animIdxs) - writer.writeUint32Big(idx); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(size_t& __isz) { - __isz += 6; - - atUint16 sectionCount; - if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - - __isz += name.size() + 1; - __isz += 12; - - __isz += 4; - for (const Animation& a : animations) - a.binarySize(__isz); - - pasDatabase.binarySize(__isz); - - __isz += 4; - for (const UniqueID32& id : partResData.part) - id.binarySize(__isz); - - __isz += 4; - for (const UniqueID32& id : partResData.swhc) - id.binarySize(__isz); - - __isz += 4; - for (const UniqueID32& id : partResData.unk) - id.binarySize(__isz); - - if (sectionCount > 5) { - __isz += 4; - for (const UniqueID32& id : partResData.elsc) - id.binarySize(__isz); - } - - __isz += 4; - - if (sectionCount > 1) { - __isz += 4; - for (const ActionAABB& aabb : animAABBs) - aabb.binarySize(__isz); - } - - if (sectionCount > 2) { - __isz += 4; - for (const Effect& e : effects) - e.binarySize(__isz); - } - - if (sectionCount > 3) - __isz += 8; - - if (sectionCount > 4) - __isz += 4 + animIdxs.size() * 4; -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::YAMLDocReader& reader) { - idx = reader.readUint32("idx"); - atUint16 sectionCount = reader.readUint16("sectionCount"); - name = reader.readString("name"); - reader.enumerate("cmdl", cmdl); - - reader.enumerate("animations", animations); - - reader.enumerate("pasDatabase", pasDatabase); - - reader.enumerate("part", partResData.part); - - reader.enumerate("swhc", partResData.swhc); - - reader.enumerate("unk", partResData.unk); - - partResData.elsc.clear(); - if (sectionCount > 5) { - reader.enumerate("elsc", partResData.elsc); - } - - unk1 = reader.readUint32("unk1"); - - animAABBs.clear(); - if (sectionCount > 1) { - reader.enumerate("part", animAABBs); - } - - effects.clear(); - if (sectionCount > 2) { - reader.enumerate("effects", effects); - } - - if (sectionCount > 3) { - reader.enumerate("cmdlIce", cmdlIce); - } - - animIdxs.clear(); - if (sectionCount > 4) { - reader.enumerate("animIdxs", animIdxs); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(athena::io::YAMLDocWriter& writer) { - writer.writeUint32("idx", idx); - - atUint16 sectionCount; - if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16("sectionCount", sectionCount); - - writer.writeString("name", name); - writer.enumerate("cmdl", cmdl); - - writer.enumerate("animations", animations); - - writer.enumerate("pasDatabase", pasDatabase); - - writer.enumerate("part", partResData.part); - - writer.enumerate("swhc", partResData.swhc); - - writer.enumerate("unk", partResData.unk); - - if (sectionCount > 5) { - writer.enumerate("elsc", partResData.elsc); - } - - writer.writeUint32("unk1", unk1); - - if (sectionCount > 1) { - writer.enumerate("animAABBs", animAABBs); - } - - if (sectionCount > 2) { - writer.enumerate("effects", effects); - } - - if (sectionCount > 3) { - writer.enumerate("cmdlIce", cmdlIce); - } - - if (sectionCount > 4) { - writer.enumerate("animIdxs", animIdxs); - } -} - -std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() { return "DNAMP1::ANCS::CharacterSet::CharacterInfo"sv; } - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::IStreamReader& reader) { - const auto type = IMetaAnim::Type(reader.readUint32Big()); - switch (type) { - case IMetaAnim::Type::Primitive: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Blend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::PhaseBlend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Random: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Sequence: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - m_anim.reset(); - break; - } -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::IStreamWriter& writer) { - if (!m_anim) - return; - writer.writeInt32Big(atUint32(m_anim->m_type)); - m_anim->write(writer); -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(size_t& __isz) { - if (!m_anim) - return; - __isz += 4; - m_anim->binarySize(__isz); -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::YAMLDocReader& reader) { - std::string type = reader.readString("type"); - std::transform(type.begin(), type.end(), type.begin(), tolower); - if (type == "primitive") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "blend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "phaseblend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "random") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "sequence") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else { - m_anim.reset(); - } -} - -template <> -void ANCS::AnimationSet::MetaAnimFactory::Enumerate(athena::io::YAMLDocWriter& writer) { - if (!m_anim) - return; - writer.writeString("type", m_anim->m_typeStr); - m_anim->write(writer); -} - -std::string_view ANCS::AnimationSet::MetaAnimFactory::DNAType() { - return "DNAMP1::ANCS::AnimationSet::MetaAnimFactory"sv; -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::IStreamReader& reader) { - IMetaTrans::Type type(IMetaTrans::Type(reader.readUint32Big())); - switch (type) { - case IMetaTrans::Type::MetaAnim: - m_trans = std::make_unique(); - m_trans->read(reader); - break; - case IMetaTrans::Type::Trans: - m_trans = std::make_unique(); - m_trans->read(reader); - break; - case IMetaTrans::Type::PhaseTrans: - m_trans = std::make_unique(); - m_trans->read(reader); - break; - case IMetaTrans::Type::NoTrans: - default: - m_trans.reset(); - break; - } -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::IStreamWriter& writer) { - if (!m_trans) { - writer.writeInt32Big(atUint32(IMetaTrans::Type::NoTrans)); - return; - } - writer.writeInt32Big(atUint32(m_trans->m_type)); - m_trans->write(writer); -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(size_t& __isz) { - __isz += 4; - if (!m_trans) - return; - m_trans->binarySize(__isz); -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::YAMLDocReader& reader) { - std::string type = reader.readString("type"); - std::transform(type.begin(), type.end(), type.begin(), tolower); - if (type == "metaanim") { - m_trans = std::make_unique(); - m_trans->read(reader); - } else if (type == "trans") { - m_trans = std::make_unique(); - m_trans->read(reader); - } else if (type == "phasetrans") { - m_trans = std::make_unique(); - m_trans->read(reader); - } else { - m_trans.reset(); - } -} - -template <> -void ANCS::AnimationSet::MetaTransFactory::Enumerate(athena::io::YAMLDocWriter& writer) { - if (!m_trans) { - writer.writeString("type", "NoTrans"); - return; - } - writer.writeString("type", m_trans->m_typeStr ? m_trans->m_typeStr : "NoTrans"); - m_trans->write(writer); -} - -std::string_view ANCS::AnimationSet::MetaTransFactory::DNAType() { - return "DNAMP1::ANCS::AnimationSet::MetaTransFactory"sv; -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::IStreamReader& reader) { - atUint16 sectionCount = reader.readUint16Big(); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - atUint32 transitionCount = reader.readUint32Big(); - reader.enumerate(transitions, transitionCount); - defaultTransition.read(reader); - - additiveAnims.clear(); - if (sectionCount > 1) { - atUint32 additiveAnimCount = reader.readUint32Big(); - reader.enumerate(additiveAnims, additiveAnimCount); - additiveDefaultFadeInDur = reader.readFloatBig(); - additiveDefaultFadeOutDur = reader.readFloatBig(); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - atUint32 halfTransitionCount = reader.readUint32Big(); - reader.enumerate(halfTransitions, halfTransitionCount); - } - - animResources.clear(); - if (sectionCount > 3) { - atUint32 animResourcesCount = reader.readUint32Big(); - reader.enumerate(animResources, animResourcesCount); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::IStreamWriter& writer) { - atUint16 sectionCount; - if (animResources.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16Big(sectionCount); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - writer.writeUint32Big(transitions.size()); - writer.enumerate(transitions); - defaultTransition.write(writer); - - if (sectionCount > 1) { - writer.writeUint32Big(additiveAnims.size()); - writer.enumerate(additiveAnims); - writer.writeFloatBig(additiveDefaultFadeInDur); - writer.writeFloatBig(additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.writeUint32Big(halfTransitions.size()); - writer.enumerate(halfTransitions); - } - - if (sectionCount > 3) { - writer.writeUint32Big(animResources.size()); - writer.enumerate(animResources); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(size_t& __isz) { - atUint16 sectionCount; - if (animResources.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - __isz += 6; - for (const Animation& a : animations) - a.binarySize(__isz); - - __isz += 4; - for (const Transition& t : transitions) - t.binarySize(__isz); - defaultTransition.binarySize(__isz); - - if (sectionCount > 1) { - __isz += 4; - for (const AdditiveAnimationInfo& aa : additiveAnims) - aa.binarySize(__isz); - __isz += 8; - } - - if (sectionCount > 2) { - __isz += 4; - for (const HalfTransition& ht : halfTransitions) - ht.binarySize(__isz); - } - - if (sectionCount > 3) { - __isz += 4; - for (const AnimationResources& ar : animResources) - ar.binarySize(__isz); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::YAMLDocReader& reader) { - atUint16 sectionCount = reader.readUint16("sectionCount"); - - reader.enumerate("animations", animations); - - reader.enumerate("transitions", transitions); - reader.enumerate("defaultTransition", defaultTransition); - - additiveAnims.clear(); - if (sectionCount > 1) { - reader.enumerate("additiveAnims", additiveAnims); - additiveDefaultFadeInDur = reader.readFloat("additiveDefaultFadeInDur"); - additiveDefaultFadeOutDur = reader.readFloat("additiveDefaultFadeOutDur"); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - reader.enumerate("halfTransitions", halfTransitions); - } - - animResources.clear(); - if (sectionCount > 3) { - reader.enumerate("animResources", animResources); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(athena::io::YAMLDocWriter& writer) { - atUint16 sectionCount; - if (animResources.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16("sectionCount", sectionCount); - - writer.enumerate("animations", animations); - - writer.enumerate("transitions", transitions); - writer.enumerate("defaultTransition", defaultTransition); - - if (sectionCount > 1) { - writer.enumerate("additiveAnims", additiveAnims); - writer.writeFloat("additiveDefaultFadeInDur", additiveDefaultFadeInDur); - writer.writeFloat("additiveDefaultFadeOutDur", additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.enumerate("halfTransitions", halfTransitions); - } - - if (sectionCount > 3) { - writer.enumerate("animResources", animResources); - } -} - -void ANCS::AnimationSet::MetaAnimPrimitive::gatherPrimitives( - PAKRouter* pakRouter, std::map>& out) { - if (!pakRouter) { - out[animIdx] = {animName, animId, UniqueID32(), false}; - return; - } - - const nod::Node* node; - const PAK::Entry* entry = pakRouter->lookupEntry(animId, &node, true); - if (!entry) { - out[animIdx] = {animName, animId, UniqueID32(), false}; - return; - } - - PAKEntryReadStream rs = entry->beginReadStream(*node); - out[animIdx] = {animName, animId, ANIM::GetEVNTId(rs), false}; -} - -std::string_view ANCS::AnimationSet::DNAType() { return "DNAMP1::ANCS::AnimationSet"sv; } - -bool ANCS::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - hecl::ProjectPath::Type blendType = blendPath.getPathType(); - - ANCS ancs; - ancs.read(rs); - - if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { - if (force || yamlType == hecl::ProjectPath::Type::None) { - athena::io::FileWriter writer(yamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(ancs, writer); - } - - if (force || blendType == hecl::ProjectPath::Type::None) { - DNAANCS::ReadANCSToBlender, ANCS, MaterialSet, DNACMDL::SurfaceHeader_1, 2>( - btok, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); - } - } - - return true; -} - -bool ANCS::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor) { - /* Search for yaml */ - hecl::ProjectPath yamlPath = inPath.getWithExtension(".yaml", true); - if (!yamlPath.isFile()) - Log.report(logvisor::Fatal, FMT_STRING("'{}' not found as file"), yamlPath.getRelativePath()); - - athena::io::FileReader reader(yamlPath.getAbsolutePath()); - if (!reader.isOpen()) - Log.report(logvisor::Fatal, FMT_STRING("can't open '{}' for reading"), yamlPath.getRelativePath()); - - if (!athena::io::ValidateFromYAMLStream(reader)) { - Log.report(logvisor::Fatal, FMT_STRING("'{}' is not DNAMP1::ANCS type"), yamlPath.getRelativePath()); - } - - athena::io::YAMLDocReader yamlReader; - if (!yamlReader.parse(&reader)) { - Log.report(logvisor::Fatal, FMT_STRING("unable to parse '{}'"), yamlPath.getRelativePath()); - } - ANCS ancs; - ancs.read(yamlReader); - - /* Set Character Resource IDs */ - for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters) { - ch.cmdl = UniqueID32{}; - ch.cskr = UniqueID32{}; - ch.cinf = UniqueID32{}; - ch.cmdlIce = UniqueID32Zero{}; - ch.cskrIce = UniqueID32Zero{}; - - int subtypeIdx = 0; - ch.animAABBs.clear(); - for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { - if (sub.name == ch.name) { - if (!sub.cskrId.empty()) { - ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), ch.name, sub.cskrId)); - } else { - ch.cskr = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), ch.name)); - } - - /* Add subtype AABBs */ - ch.animAABBs.reserve(actor.actions.size()); - for (const DNAANCS::Action& act : actor.actions) { - const auto& sourceAABB = act.subtypeAABBs[subtypeIdx]; - ch.animAABBs.emplace_back(); - auto& destAABB = ch.animAABBs.back(); - destAABB.name = act.name; - destAABB.aabb[0] = sourceAABB.first.val; - destAABB.aabb[1] = sourceAABB.second.val; - } - - if (sub.armature >= 0) { - const DNAANCS::Armature& arm = actor.armatures[sub.armature]; - ch.cinf = arm.path; - ch.cmdl = sub.mesh; - auto search = std::find_if(sub.overlayMeshes.cbegin(), sub.overlayMeshes.cend(), - [](const auto& p) { return p.name == "ICE"; }); - if (search != sub.overlayMeshes.cend()) { - ch.cmdlIce = search->mesh; - if (!search->cskrId.empty()) { - ch.cskrIce = inPath.ensureAuxInfo( - fmt::format(FMT_STRING("{}.{}_{}.CSKR"), ch.name, search->name, search->cskrId)); - } else { - ch.cskrIce = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.{}.CSKR"), ch.name, search->name)); - } - } - } - - break; - } - ++subtypeIdx; - } - - std::sort(ch.animAABBs.begin(), ch.animAABBs.end(), - [](const ANCS::CharacterSet::CharacterInfo::ActionAABB& a, - const ANCS::CharacterSet::CharacterInfo::ActionAABB& b) { return a.name < b.name; }); - } - - /* Set Animation Resource IDs */ - ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) { - for (const DNAANCS::Action& act : actor.actions) { - if (act.name == prim.animName) { - hecl::ProjectPath pathOut; - if (!act.animId.empty()) { - pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), prim.animName, act.animId)); - } else { - inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), prim.animName)); - } - prim.animId = pathOut; - break; - } - } - return true; - }); - - /* Gather ANIM resources */ - hecl::DirectoryEnumerator dEnum(inPath.getParentPath().getAbsolutePath()); - ancs.animationSet.animResources.reserve(actor.actions.size()); - for (const DNAANCS::Action& act : actor.actions) { - hecl::ProjectPath pathOut; - if (!act.animId.empty()) { - pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.name, act.animId)); - } else { - pathOut = inPath.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), act.name)); - } - - ancs.animationSet.animResources.emplace_back(); - ancs.animationSet.animResources.back().animId = pathOut; - - /* Check for associated EVNT YAML */ - std::string testPrefix( - inPath.getWithExtension(fmt::format(FMT_STRING(".{}_"), act.name).c_str(), true).getLastComponent()); - hecl::ProjectPath evntYamlPath; - for (const auto& ent : dEnum) { - if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) && - hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) { - evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name); - break; - } - } - if (evntYamlPath.isFile()) { - evntYamlPath = evntYamlPath.ensureAuxInfo(""); - ancs.animationSet.animResources.back().evntId = evntYamlPath; - } - } - - /* Write out ANCS */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - ancs.write(w); - - return true; -} - -static const std::regex regCskrNameId(R"((.*)_[0-9a-fA-F]{8}\.CSKR)", - std::regex::ECMAScript | std::regex::optimize); -static const std::regex regCskrName(R"((.*)\.CSKR)", std::regex::ECMAScript | std::regex::optimize); - -bool ANCS::CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc) { - auto auxInfo = inPath.getAuxInfo(); - std::match_results match; - if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) && - !std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName)) - return false; - - std::string subName = match[1].str(); - std::string overName; - auto dotPos = subName.rfind('.'); - if (dotPos != std::string::npos) { - overName = std::string(subName.begin() + dotPos + 1, subName.end()); - subName = std::string(subName.begin(), subName.begin() + dotPos); - } - - /* Build bone ID map */ - std::unordered_map boneIdMap; - for (const DNAANCS::Armature& arm : actor.armatures) { - CINF cinf(*arm.armature, boneIdMap); - } - - const DNAANCS::Actor::Subtype* subtype = nullptr; - if (subName != "ATTACH") { - for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { - if (sub.name == subName) { - subtype = ⊂ - break; - } - } - if (!subtype) - Log.report(logvisor::Fatal, FMT_STRING("unable to find subtype '{}'"), subName); - } - - const hecl::ProjectPath* modelPath = nullptr; - if (subName == "ATTACH") { - const DNAANCS::Actor::Attachment* attachment = nullptr; - for (const DNAANCS::Actor::Attachment& att : actor.attachments) { - if (att.name == overName) { - attachment = &att; - break; - } - } - if (!attachment) - Log.report(logvisor::Fatal, FMT_STRING("unable to find attachment '{}'"), overName); - modelPath = &attachment->mesh; - } else if (overName.empty()) { - modelPath = &subtype->mesh; - } else { - for (const auto& overlay : subtype->overlayMeshes) - if (overlay.name == overName) { - modelPath = &overlay.mesh; - break; - } - } - if (!modelPath) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve model path of {}:{}"), subName, overName); - - if (!modelPath->isFile()) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve '{}'"), modelPath->getRelativePath()); - - hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1).getWithExtension(".skinint"); - if (!skinIntPath.isFileOrGlob() || skinIntPath.getModtime() < modelPath->getModtime()) - if (!modelCookFunc(*modelPath)) - Log.report(logvisor::Fatal, FMT_STRING("unable to cook '{}'"), modelPath->getRelativePath()); - - std::vector>, uint32_t>> skins; - uint32_t posCount = 0; - uint32_t normCount = 0; - athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024 * 32, false); - if (!skinIO.hasError()) { - std::vector boneNames; - uint32_t boneNameCount = skinIO.readUint32Big(); - boneNames.reserve(boneNameCount); - for (uint32_t i = 0; i < boneNameCount; ++i) - boneNames.push_back(skinIO.readString()); - - uint32_t skinCount = skinIO.readUint32Big(); - skins.resize(skinCount); - for (uint32_t i = 0; i < skinCount; ++i) { - std::pair>, uint32_t>& virtualBone = skins[i]; - uint32_t bindCount = skinIO.readUint32Big(); - virtualBone.first.reserve(bindCount); - for (uint32_t j = 0; j < bindCount; ++j) { - uint32_t bIdx = skinIO.readUint32Big(); - float weight = skinIO.readFloatBig(); - const std::string& name = boneNames[bIdx]; - auto search = boneIdMap.find(name); - if (search == boneIdMap.cend()) - Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath()); - virtualBone.first.emplace_back(search->second, weight); - } - virtualBone.second = skinIO.readUint32Big(); - } - - posCount = skinIO.readUint32Big(); - normCount = skinIO.readUint32Big(); - - skinIO.close(); - } - - athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath()); - - skinOut.writeUint32Big(skins.size()); - for (auto& virtuaBone : skins) { - skinOut.writeUint32Big(virtuaBone.first.size()); - for (auto& bind : virtuaBone.first) { - skinOut.writeUint32Big(bind.first); - skinOut.writeFloatBig(bind.second); - } - skinOut.writeUint32Big(virtuaBone.second); - } - - skinOut.writeUint32Big(0xffffffff); - skinOut.writeUint32Big(posCount); - skinOut.writeUint32Big(0xffffffff); - skinOut.writeUint32Big(normCount); - - return true; -} - -bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc) { - auto auxInfo = inPath.getAuxInfo(); - std::match_results match; - if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrNameId) && - !std::regex_search(auxInfo.begin(), auxInfo.end(), match, regCskrName)) - return false; - - std::string subName = match[1].str(); - std::string overName; - auto dotPos = subName.rfind('.'); - if (dotPos != std::string::npos) { - overName = std::string(subName.begin() + dotPos + 1, subName.end()); - subName = std::string(subName.begin(), subName.begin() + dotPos); - } - - /* Build bone ID map */ - std::unordered_map boneIdMap; - for (const DNAANCS::Armature& arm : actor.armatures) { - CINF cinf(*arm.armature, boneIdMap); - } - - const DNAANCS::Actor::Subtype* subtype = nullptr; - if (subName != "ATTACH") { - for (const DNAANCS::Actor::Subtype& sub : actor.subtypes) { - if (sub.name == subName) { - subtype = ⊂ - break; - } - } - if (!subtype) - Log.report(logvisor::Fatal, FMT_STRING("unable to find subtype '{}'"), subName); - } - - const hecl::ProjectPath* modelPath = nullptr; - if (subName == "ATTACH") { - const DNAANCS::Actor::Attachment* attachment = nullptr; - for (const DNAANCS::Actor::Attachment& att : actor.attachments) { - if (att.name == overName) { - attachment = &att; - break; - } - } - if (!attachment) - Log.report(logvisor::Fatal, FMT_STRING("unable to find attachment '{}'"), overName); - modelPath = &attachment->mesh; - } else if (overName.empty()) { - modelPath = &subtype->mesh; - } else { - for (const auto& overlay : subtype->overlayMeshes) - if (overlay.name == overName) { - modelPath = &overlay.mesh; - break; - } - } - if (!modelPath) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve model path of {}:{}"), subName, overName); - - if (!modelPath->isFile()) - Log.report(logvisor::Fatal, FMT_STRING("unable to resolve '{}'"), modelPath->getRelativePath()); - - hecl::ProjectPath skinIntPath = modelPath->getCookedPath(SpecEntMP1PC).getWithExtension(".skinint"); - if (!skinIntPath.isFileOrGlob() || skinIntPath.getModtime() < modelPath->getModtime()) - if (!modelCookFunc(*modelPath)) - Log.report(logvisor::Fatal, FMT_STRING("unable to cook '{}'"), modelPath->getRelativePath()); - - uint32_t bankCount = 0; - std::vector> skinBanks; - std::vector boneNames; - std::vector>> skins; - atUint64 uniquePoolIndexLen = 0; - std::unique_ptr uniquePoolIndexData; - athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024 * 32, false); - if (!skinIO.hasError()) { - bankCount = skinIO.readUint32Big(); - skinBanks.reserve(bankCount); - for (uint32_t i = 0; i < bankCount; ++i) { - skinBanks.emplace_back(); - std::vector& bonesOut = skinBanks.back(); - uint32_t boneCount = skinIO.readUint32Big(); - bonesOut.reserve(boneCount); - for (uint32_t j = 0; j < boneCount; ++j) { - uint32_t idx = skinIO.readUint32Big(); - bonesOut.push_back(idx); - } - } - - uint32_t boneNameCount = skinIO.readUint32Big(); - boneNames.reserve(boneNameCount); - for (uint32_t i = 0; i < boneNameCount; ++i) - boneNames.push_back(skinIO.readString()); - - uint32_t skinCount = skinIO.readUint32Big(); - skins.resize(skinCount); - for (uint32_t i = 0; i < skinCount; ++i) { - std::vector>& virtualBone = skins[i]; - uint32_t bindCount = skinIO.readUint32Big(); - virtualBone.reserve(bindCount); - for (uint32_t j = 0; j < bindCount; ++j) { - uint32_t bIdx = skinIO.readUint32Big(); - float weight = skinIO.readFloatBig(); - const std::string& name = boneNames[bIdx]; - auto search = boneIdMap.find(name); - if (search == boneIdMap.cend()) - Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath()); - virtualBone.emplace_back(search->second, weight); - } - } - - uniquePoolIndexLen = skinIO.length() - skinIO.position(); - uniquePoolIndexData = skinIO.readUBytes(uniquePoolIndexLen); - - skinIO.close(); - } - - athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath()); - - skinOut.writeUint32Big(bankCount); - for (const std::vector& bank : skinBanks) { - skinOut.writeUint32Big(bank.size()); - for (uint32_t bIdx : bank) { - const std::string& name = boneNames[bIdx]; - auto search = boneIdMap.find(name); - if (search == boneIdMap.cend()) - Log.report(logvisor::Fatal, FMT_STRING("unable to find bone '{}' in {}"), name, inPath.getRelativePath()); - skinOut.writeUint32Big(search->second); - } - } - - skinOut.writeUint32Big(skins.size()); - for (auto& virtuaBone : skins) { - skinOut.writeUint32Big(virtuaBone.size()); - for (auto& bind : virtuaBone) { - skinOut.writeUint32Big(bind.first); - skinOut.writeFloatBig(bind.second); - } - } - - if (uniquePoolIndexLen) - skinOut.writeUBytes(uniquePoolIndexData.get(), uniquePoolIndexLen); - - return true; -} - -static const std::regex regAnimNameId(R"((.*)_[0-9a-fA-F]{8}\.ANIM)", - std::regex::ECMAScript | std::regex::optimize); -static const std::regex regAnimName(R"((.*)\.ANIM)", std::regex::ECMAScript | std::regex::optimize); - -bool ANCS::CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - hecl::blender::DataStream& ds, bool pc) { - auto auxInfo = inPath.getAuxInfo(); - std::match_results match; - if (!std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimNameId) && - !std::regex_search(auxInfo.begin(), auxInfo.end(), match, regAnimName)) - return false; - - std::string actName = match[1].str(); - DNAANCS::Action action = ds.compileActionChannelsOnly(actName); - - if (!actor.armatures.size()) - Log.report(logvisor::Fatal, FMT_STRING("0 armatures in {}"), inPath.getRelativePath()); - - /* Build bone ID map */ - std::unordered_map boneIdMap; - std::optional rigCinf; - std::optional> rigInv; - for (const DNAANCS::Armature& arm : actor.armatures) { - if (!rigInv) { - rigCinf.emplace(*arm.armature, boneIdMap); - auto matrices = ds.getBoneMatrices(arm.name); - rigInv.emplace(*rigCinf, matrices); - } else { - CINF cinf(*arm.armature, boneIdMap); - } - } - - ANIM anim(action, boneIdMap, *rigInv, pc); - - /* Check for associated EVNT YAML */ - std::string testPrefix( - inPath.getWithExtension(fmt::format(FMT_STRING(".{}_"), actName).c_str(), true).getLastComponent()); - hecl::ProjectPath evntYamlPath; - for (const auto& ent : hecl::DirectoryEnumerator(inPath.getParentPath().getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, testPrefix.c_str()) && - hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) { - evntYamlPath = hecl::ProjectPath(inPath.getParentPath(), ent.m_name); - break; - } - } - if (evntYamlPath.isFile()) { - evntYamlPath = evntYamlPath.ensureAuxInfo(""); - anim.m_anim->evnt = evntYamlPath; - } - - /* Write out ANIM resource */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - anim.write(w); - return true; -} - -} // namespace DNAMP1 -} // namespace DataSpec diff --git a/DataSpec/DNAMP1/ANCS.hpp b/DataSpec/DNAMP1/ANCS.hpp deleted file mode 100644 index 9e00da1e4..000000000 --- a/DataSpec/DNAMP1/ANCS.hpp +++ /dev/null @@ -1,420 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" -#include "CMDLMaterials.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" -#include "ANIM.hpp" -#include "EVNT.hpp" -#include "athena/FileReader.hpp" - -namespace DataSpec::DNAMP1 { - -struct ANCS : BigDNA { - using CINFType = CINF; - using CSKRType = CSKR; - using ANIMType = ANIM; - - AT_DECL_DNA_YAML - Value version; - - struct CharacterSet : BigDNA { - AT_DECL_DNA_YAML - Value version; - Value characterCount; - struct CharacterInfo : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - - atUint32 idx; - std::string name; - UniqueID32 cmdl; - UniqueID32 cskr; - UniqueID32 cinf; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - String<-1> strA; - String<-1> strB; - }; - std::vector animations; - - struct PASDatabase : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value animStateCount; - Value defaultState; - struct AnimState : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - atUint32 id; - - struct ParmInfo : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - enum class DataType { Int32 = 0, UInt32 = 1, Float = 2, Bool = 3, Enum = 4 }; - union Parm { - atInt32 int32; - atUint32 uint32; - float float32; - bool bool1; - Parm() : int32(0) {} - Parm(atInt32 val) : int32(val) {} - Parm(atUint32 val) : uint32(val) {} - Parm(float val) : float32(val) {} - Parm(bool val) : bool1(val) {} - }; - - atUint32 parmType; - atUint32 weightFunction; - float weight; - Parm range[2]; - }; - std::vector parmInfos; - - struct AnimInfo { - atUint32 id; - std::vector parmVals; - }; - std::vector animInfos; - }; - Vector animStates; - } pasDatabase; - - struct ParticleResData { - std::vector part; - std::vector swhc; - std::vector unk; - std::vector elsc; - } partResData; - - atUint32 unk1 = 0; - - struct ActionAABB : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value aabb[2]; - }; - std::vector animAABBs; - - struct Effect : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value compCount; - struct EffectComponent : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - DNAFourCC type; - UniqueID32 id; - String<-1> locator; - Value scale; - Value parentMode; - Value flags; - }; - Vector comps; - }; - std::vector effects; - - UniqueID32Zero cmdlIce; - UniqueID32Zero cskrIce; - - std::vector animIdxs; - }; - Vector characters; - } characterSet; - - struct AnimationSet : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - - struct MetaAnimPrimitive; - struct IMetaAnim : BigDNAVYaml { - Delete expl; - enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type; - const char* m_typeStr; - IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {} - virtual void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) = 0; - virtual bool enumeratePrimitives(const std::function& func) = 0; - }; - struct MetaAnimFactory : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - std::unique_ptr m_anim; - }; - struct MetaAnimPrimitive : IMetaAnim { - AT_DECL_DNA_YAMLV - MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} - - UniqueID32 animId; - Value animIdx; - String<-1> animName; - Value unk1; - Value unk2; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override; - - bool enumeratePrimitives(const std::function& func) override { - return func(*this); - } - }; - struct MetaAnimBlend : IMetaAnim { - MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - animA.m_anim->gatherPrimitives(pakRouter, out); - animB.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - if (!animA.m_anim->enumeratePrimitives(func)) - return false; - if (!animB.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - struct MetaAnimPhaseBlend : IMetaAnim { - MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - animA.m_anim->gatherPrimitives(pakRouter, out); - animB.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - if (!animA.m_anim->enumeratePrimitives(func)) - return false; - if (!animB.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - struct MetaAnimRandom : IMetaAnim { - MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {} - AT_DECL_DNA_YAMLV - Value animCount; - struct Child : BigDNA { - AT_DECL_DNA - MetaAnimFactory anim; - Value probability; - }; - Vector children; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - for (const auto& child : children) - child.anim.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - for (auto& child : children) - if (!child.anim.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - struct MetaAnimSequence : IMetaAnim { - MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {} - AT_DECL_DNA_YAMLV - Value animCount; - Vector children; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - for (const auto& child : children) - child.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - for (auto& child : children) - if (!child.m_anim->enumeratePrimitives(func)) - return false; - return true; - } - }; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - MetaAnimFactory metaAnim; - }; - std::vector animations; - - struct IMetaTrans : BigDNAVYaml { - Delete expl; - enum class Type { - MetaAnim = 0, - Trans = 1, - PhaseTrans = 2, - NoTrans = 3, - } m_type; - const char* m_typeStr; - IMetaTrans(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {} - virtual void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) {} - virtual bool enumeratePrimitives(const std::function& func) { return true; } - }; - struct MetaTransFactory : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - std::unique_ptr m_trans; - }; - struct MetaTransMetaAnim : IMetaTrans { - MetaTransMetaAnim() : IMetaTrans(Type::MetaAnim, "MetaAnim") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory anim; - - void gatherPrimitives(PAKRouter* pakRouter, - std::map>& out) override { - anim.m_anim->gatherPrimitives(pakRouter, out); - } - - bool enumeratePrimitives(const std::function& func) override { - return anim.m_anim->enumeratePrimitives(func); - } - }; - struct MetaTransTrans : IMetaTrans { - MetaTransTrans() : IMetaTrans(Type::Trans, "Trans") {} - AT_DECL_DNA_YAMLV - Value transDurTime; - Value transDurTimeMode; - Value unk2; - Value runA; - Value flags; - }; - struct MetaTransPhaseTrans : IMetaTrans { - MetaTransPhaseTrans() : IMetaTrans(Type::PhaseTrans, "PhaseTrans") {} - AT_DECL_DNA_YAMLV - Value transDurTime; - Value transDurTimeMode; - Value unk2; - Value runA; - Value flags; - }; - - struct Transition : BigDNA { - AT_DECL_DNA_YAML - Value unk; - Value animIdxA; - Value animIdxB; - MetaTransFactory metaTrans; - }; - std::vector transitions; - MetaTransFactory defaultTransition; - - struct AdditiveAnimationInfo : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - Value fadeInDur; - Value fadeOutDur; - }; - std::vector additiveAnims; - - float additiveDefaultFadeInDur = 0.0; - float additiveDefaultFadeOutDur = 0.0; - - struct HalfTransition : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - MetaTransFactory metaTrans; - }; - std::vector halfTransitions; - - struct AnimationResources : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 animId; - UniqueID32 evntId; - }; - std::vector animResources; - } animationSet; - - void getCharacterResInfo(std::vector>& out) const { - out.clear(); - out.reserve(characterSet.characters.size()); - for (const CharacterSet::CharacterInfo& ci : characterSet.characters) { - out.emplace_back(); - DNAANCS::CharacterResInfo& chOut = out.back(); - chOut.name = ci.name; - chOut.cmdl = ci.cmdl; - chOut.cskr = ci.cskr; - chOut.cinf = ci.cinf; - - if (ci.cmdlIce.isValid()) - chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce)); - } - } - - void getAnimationResInfo(PAKRouter* pakRouter, - std::map>& out) const { - out.clear(); - for (const AnimationSet::Animation& ai : animationSet.animations) - if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get()) - anim->gatherPrimitives(pakRouter, out); - for (const AnimationSet::Transition& ti : animationSet.transitions) - if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get()) - trans->gatherPrimitives(pakRouter, out); - if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get()) - trans->gatherPrimitives(pakRouter, out); - } - - void enumeratePrimitives(const std::function& func) { - for (const AnimationSet::Animation& ai : animationSet.animations) - if (AnimationSet::IMetaAnim* anim = ai.metaAnim.m_anim.get()) - anim->enumeratePrimitives(func); - for (const AnimationSet::Transition& ti : animationSet.transitions) - if (AnimationSet::IMetaTrans* trans = ti.metaTrans.m_trans.get()) - trans->enumeratePrimitives(func); - if (AnimationSet::IMetaTrans* trans = animationSet.defaultTransition.m_trans.get()) - trans->enumeratePrimitives(func); - } - - void gatherDependencies(std::vector& pathsOut, int charIdx) const { - auto doCi = [&](const CharacterSet::CharacterInfo& ci) { - for (const auto& id : ci.partResData.part) - g_curSpec->flattenDependencies(id, pathsOut); - for (const auto& id : ci.partResData.swhc) - g_curSpec->flattenDependencies(id, pathsOut); - for (const auto& id : ci.partResData.unk) - g_curSpec->flattenDependencies(id, pathsOut); - for (const auto& id : ci.partResData.elsc) - g_curSpec->flattenDependencies(id, pathsOut); - }; - if (charIdx < 0) - for (const CharacterSet::CharacterInfo& ci : characterSet.characters) - doCi(ci); - else if (charIdx < characterSet.characters.size()) - doCi(characterSet.characters[charIdx]); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor); - - static bool CookCSKR(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc); - static bool CookCSKRPC(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - const std::function& modelCookFunc); - - static bool CookANIM(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNAANCS::Actor& actor, - hecl::blender::DataStream& ds, bool pc); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ANIM.cpp b/DataSpec/DNAMP1/ANIM.cpp deleted file mode 100644 index 7768ec25c..000000000 --- a/DataSpec/DNAMP1/ANIM.cpp +++ /dev/null @@ -1,624 +0,0 @@ -#include "ANIM.hpp" -#include "zeus/CVector3f.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -using ANIMOutStream = hecl::blender::ANIMOutStream; - -void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig) const { - os.format(FMT_STRING("act.hecl_fps = round({})\n" - "act.hecl_looping = {}\n"), - (1.0f / mainInterval), looping ? "True" : "False"); - - auto kit = chanKeys.begin(); - - std::vector fixedRotKeys; - std::vector fixedTransKeys; - - for (const std::pair& bone : bones) { - const std::string* bName = rig.getCINF().getBoneNameFromId(bone.first); - if (!bName) { - ++kit; - if (bone.second) - ++kit; - continue; - } - - os.format(FMT_STRING("bone_string = '{}'\n"), *bName); - os << "action_group = act.groups.new(bone_string)\n" - "\n" - "rotCurves = []\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, " - "action_group=bone_string))\n" - "\n"; - - if (bone.second) - os << "transCurves = []\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, " - "action_group=bone_string))\n" - "\n"; - - ANIMOutStream ao = os.beginANIMCurve(); - - { - const std::vector& rotKeys = *kit++; - fixedRotKeys.clear(); - fixedRotKeys.resize(rotKeys.size()); - - for (int c = 0; c < 4; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : rotKeys) - fixedRotKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CQuaternion& rot : fixedRotKeys) - rot = rig.invertRotation(bone.first, rot); - - for (int c = 0; c < 4; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Rotate, c, rotKeys.size()); - for (const zeus::CQuaternion& val : fixedRotKeys) - ao.write(*frameit++, val[c]); - } - } - - if (bone.second) { - const std::vector& transKeys = *kit++; - fixedTransKeys.clear(); - fixedTransKeys.resize(transKeys.size()); - - for (int c = 0; c < 3; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : transKeys) - fixedTransKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CVector3f& t : fixedTransKeys) - t = rig.invertPosition(bone.first, t, true); - - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Translate, c, fixedTransKeys.size()); - for (const zeus::CVector3f& val : fixedTransKeys) - ao.write(*frameit++, val[c]); - } - } - } -} - -UniqueID32 ANIM::GetEVNTId(athena::io::IStreamReader& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: { - ANIM0 anim0; - anim0.read(reader); - return anim0.evnt; - } - case 2: - case 3: - reader.seek(4); - return reader.readUint32Big(); - default: - Log.report(logvisor::Error, FMT_STRING("unrecognized ANIM version")); - break; - } - return {}; -} - -template <> -void ANIM::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case 2: - m_anim = std::make_unique(false); - m_anim->read(reader); - break; - case 3: - m_anim = std::make_unique(true); - m_anim->read(reader); - break; - default: - Log.report(logvisor::Error, FMT_STRING("unrecognized ANIM version")); - break; - } -} - -template <> -void ANIM::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_anim->m_version); - m_anim->write(writer); -} - -template <> -void ANIM::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - m_anim->binarySize(s); -} - -std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; } - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - - frames.clear(); - frames.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - frames.push_back(k); - - std::map boneMap; - for (size_t b = 0; b < head.boneSlotCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx == 0xff) - continue; - boneMap[idx] = b; - } - - atUint32 boneCount = reader.readUint32Big(); - bones.clear(); - bones.reserve(boneCount); - channels.clear(); - for (size_t b = 0; b < boneCount; ++b) { - bones.emplace_back(boneMap[b], false); - atUint8 idx = reader.readUByte(); - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - if (idx != 0xff) { - bones.back().second = true; - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - } - } - - reader.readUint32Big(); - chanKeys.clear(); - chanKeys.reserve(channels.size()); - for (const std::pair& bone : bones) { - chanKeys.emplace_back(); - std::vector& keys = chanKeys.back(); - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec4fBig()); - - if (bone.second) - chanKeys.emplace_back(); - } - - reader.readUint32Big(); - auto kit = chanKeys.begin(); - for (const std::pair& bone : bones) { - ++kit; - if (bone.second) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - } - - evnt.read(reader); -} - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamWriter& writer) { - Header head; - head.unk0 = 0; - head.unk1 = 0; - head.unk2 = 0; - head.keyCount = frames.size(); - head.duration = head.keyCount * mainInterval; - head.interval = mainInterval; - - atUint32 maxId = 0; - for (const std::pair& bone : bones) - maxId = std::max(maxId, bone.first); - head.boneSlotCount = maxId + 1; - head.write(writer); - - for (size_t s = 0; s < head.boneSlotCount; ++s) { - size_t boneIdx = 0; - bool found = false; - for (const std::pair& bone : bones) { - if (s == bone.first) { - writer.writeUByte(boneIdx); - found = true; - break; - } - ++boneIdx; - } - if (!found) - writer.writeUByte(0xff); - } - - writer.writeUint32Big(bones.size()); - size_t boneIdx = 0; - for (const std::pair& bone : bones) { - if (bone.second) - writer.writeUByte(boneIdx); - else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size() * head.keyCount); - auto cit = chanKeys.begin(); - atUint32 transKeyCount = 0; - for (const std::pair& bone : bones) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec4fBig(atVec4f{(*kit++).simd}); - if (bone.second) { - transKeyCount += head.keyCount; - ++cit; - } - } - - writer.writeUint32Big(transKeyCount); - cit = chanKeys.begin(); - for (const std::pair& bone : bones) { - ++cit; - if (bone.second) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - } - - evnt.write(writer); -} - -template <> -void ANIM::ANIM0::Enumerate(size_t& __isz) { - Header head; - - atUint32 maxId = 0; - for (const std::pair& bone : bones) - maxId = std::max(maxId, bone.first); - - head.binarySize(__isz); - __isz += maxId + 1; - __isz += bones.size() + 4; - - __isz += 8; - for (const std::pair& bone : bones) { - __isz += head.keyCount * 16; - if (bone.second) - __isz += head.keyCount * 12; - } - - __isz += 4; -} - -std::string_view ANIM::ANIM2::DNAType() { return "ANIM2"sv; } - -template <> -void ANIM::ANIM2::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - evnt = head.evnt; - mainInterval = head.interval; - looping = bool(head.looping); - - WordBitmap keyBmp; - keyBmp.read(reader, head.keyBitmapBitCount); - frames.clear(); - atUint32 frameAccum = 0; - for (bool bit : keyBmp) { - if (bit) - frames.push_back(frameAccum); - ++frameAccum; - } - reader.seek(8); - - bones.clear(); - bones.reserve(head.boneChannelCount); - channels.clear(); - channels.reserve(head.boneChannelCount); - atUint32 keyframeCount = 0; - - if (m_version == 3) { - for (size_t b = 0; b < head.boneChannelCount; ++b) { - ChannelDescPC desc; - desc.read(reader); - bones.emplace_back(desc.id, desc.keyCount2 != 0); - - if (desc.keyCount1) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chan.id = desc.id; - chan.i[0] = atInt32(desc.QinitRX) >> 8; - chan.q[0] = desc.QinitRX & 0xff; - chan.i[1] = atInt32(desc.QinitRY) >> 8; - chan.q[1] = desc.QinitRY & 0xff; - chan.i[2] = atInt32(desc.QinitRZ) >> 8; - chan.q[2] = desc.QinitRZ & 0xff; - } - keyframeCount = std::max(keyframeCount, desc.keyCount1); - - if (desc.keyCount2) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.id = desc.id; - chan.i[0] = atInt32(desc.QinitTX) >> 8; - chan.q[0] = desc.QinitTX & 0xff; - chan.i[1] = atInt32(desc.QinitTY) >> 8; - chan.q[1] = desc.QinitTY & 0xff; - chan.i[2] = atInt32(desc.QinitTZ) >> 8; - chan.q[2] = desc.QinitTZ & 0xff; - } - } - } else { - for (size_t b = 0; b < head.boneChannelCount; ++b) { - ChannelDesc desc; - desc.read(reader); - bones.emplace_back(desc.id, desc.keyCount2 != 0); - - if (desc.keyCount1) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chan.id = desc.id; - chan.i[0] = desc.initRX; - chan.q[0] = desc.qRX; - chan.i[1] = desc.initRY; - chan.q[1] = desc.qRY; - chan.i[2] = desc.initRZ; - chan.q[2] = desc.qRZ; - } - keyframeCount = std::max(keyframeCount, atUint32(desc.keyCount1)); - - if (desc.keyCount2) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.id = desc.id; - chan.i[0] = desc.initTX; - chan.q[0] = desc.qTX; - chan.i[1] = desc.initTY; - chan.q[1] = desc.qTY; - chan.i[2] = desc.initTZ; - chan.q[2] = desc.qTZ; - } - } - } - - size_t bsSize = DNAANIM::ComputeBitstreamSize(keyframeCount, channels); - std::unique_ptr bsData = reader.readUBytes(bsSize); - DNAANIM::BitstreamReader bsReader; - chanKeys = bsReader.read(bsData.get(), keyframeCount, channels, head.rotDiv, head.translationMult, 0.f); -} - -template <> -void ANIM::ANIM2::Enumerate(athena::io::IStreamWriter& writer) { - Header head; - head.evnt = evnt; - head.unk0 = 1; - head.interval = mainInterval; - head.rootBoneId = 3; - head.looping = looping; - head.unk3 = 1; - - WordBitmap keyBmp; - size_t frameCount = 0; - for (atUint32 frame : frames) { - if (!keyBmp.getBit(frame)) { - keyBmp.setBit(frame); - frameCount += 1; - } - } - head.keyBitmapBitCount = keyBmp.getBitCount(); - head.duration = frames.back() * mainInterval; - head.boneChannelCount = bones.size(); - - size_t keyframeCount = frameCount - 1; - std::vector qChannels = channels; - DNAANIM::BitstreamWriter bsWriter; - size_t bsSize; - float scaleMult; - std::unique_ptr bsData = - bsWriter.write(chanKeys, keyframeCount, qChannels, m_version == 3 ? 0x7fffff : 0x7fff, head.rotDiv, - head.translationMult, scaleMult, bsSize); - - /* Tally up buffer size */ - size_t scratchSize = 0; - head.binarySize(scratchSize); - keyBmp.binarySize(scratchSize); - scratchSize += bsSize; - if (m_version == 3) { - for (const std::pair& bone : bones) { - ChannelDescPC desc; - desc.keyCount1 = keyframeCount; - if (bone.second) - desc.keyCount2 = keyframeCount; - desc.binarySize(scratchSize); - } - } else { - for (const std::pair& bone : bones) { - ChannelDesc desc; - desc.keyCount1 = keyframeCount; - if (bone.second) - desc.keyCount2 = keyframeCount; - desc.binarySize(scratchSize); - } - } - head.scratchSize = scratchSize; - - head.write(writer); - keyBmp.write(writer); - writer.writeUint32Big(head.boneChannelCount); - writer.writeUint32Big(head.boneChannelCount); - auto cit = qChannels.begin(); - - if (m_version == 3) { - for (const std::pair& bone : bones) { - ChannelDescPC desc; - desc.id = bone.first; - DNAANIM::Channel& chan = *cit++; - desc.keyCount1 = keyframeCount; - desc.QinitRX = (chan.i[0] << 8) | chan.q[0]; - desc.QinitRY = (chan.i[1] << 8) | chan.q[1]; - desc.QinitRZ = (chan.i[2] << 8) | chan.q[2]; - if (bone.second) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount2 = keyframeCount; - desc.QinitTX = (chan.i[0] << 8) | chan.q[0]; - desc.QinitTY = (chan.i[1] << 8) | chan.q[1]; - desc.QinitTZ = (chan.i[2] << 8) | chan.q[2]; - } - desc.write(writer); - } - } else { - for (const std::pair& bone : bones) { - ChannelDesc desc; - desc.id = bone.first; - DNAANIM::Channel& chan = *cit++; - desc.keyCount1 = keyframeCount; - desc.initRX = chan.i[0]; - desc.qRX = chan.q[0]; - desc.initRY = chan.i[1]; - desc.qRY = chan.q[1]; - desc.initRZ = chan.i[2]; - desc.qRZ = chan.q[2]; - if (bone.second) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount2 = keyframeCount; - desc.initTX = chan.i[0]; - desc.qTX = chan.q[0]; - desc.initTY = chan.i[1]; - desc.qTY = chan.q[1]; - desc.initTZ = chan.i[2]; - desc.qTZ = chan.q[2]; - } - desc.write(writer); - } - } - - writer.writeUBytes(bsData.get(), bsSize); -} - -template <> -void ANIM::ANIM2::Enumerate(size_t& __isz) { - Header head; - - WordBitmap keyBmp; - for (atUint32 frame : frames) - keyBmp.setBit(frame); - - head.binarySize(__isz); - keyBmp.binarySize(__isz); - __isz += 8; - if (m_version == 3) { - for (const std::pair& bone : bones) { - __isz += 24; - if (bone.second) - __isz += 12; - } - } else { - for (const std::pair& bone : bones) { - __isz += 17; - if (bone.second) - __isz += 9; - } - } - - __isz += DNAANIM::ComputeBitstreamSize(frames.size(), channels); -} - -ANIM::ANIM(const BlenderAction& act, const std::unordered_map& idMap, - const DNAANIM::RigInverter& rig, bool pc) { - m_anim = std::make_unique(pc); - IANIM& newAnim = *m_anim; - newAnim.looping = act.looping; - - newAnim.bones.reserve(act.channels.size()); - size_t extChanCount = 0; - std::unordered_set addedBones; - addedBones.reserve(act.channels.size()); - for (const BlenderAction::Channel& chan : act.channels) { - auto search = idMap.find(chan.boneName); - if (search == idMap.cend()) { - Log.report(logvisor::Warning, FMT_STRING("unable to find id for bone '{}'"), chan.boneName); - continue; - } - if (addedBones.find(search->second) != addedBones.cend()) - continue; - addedBones.insert(search->second); - - extChanCount += std::max(zeus::PopCount(chan.attrMask), 2); - newAnim.bones.emplace_back(search->second, (chan.attrMask & 0x2) != 0); - } - - newAnim.frames.reserve(act.frames.size()); - for (int32_t frame : act.frames) - newAnim.frames.push_back(frame); - - newAnim.channels.reserve(extChanCount); - newAnim.chanKeys.reserve(extChanCount); - - for (const BlenderAction::Channel& chan : act.channels) { - auto search = idMap.find(chan.boneName); - if (search == idMap.cend()) - continue; - - newAnim.channels.emplace_back(); - DNAANIM::Channel& newChan = newAnim.channels.back(); - newChan.type = DNAANIM::Channel::Type::Rotation; - newChan.id = search->second; - - newAnim.chanKeys.emplace_back(); - std::vector& rotVals = newAnim.chanKeys.back(); - rotVals.reserve(chan.keys.size()); - float sign = 0.f; - for (const BlenderAction::Channel::Key& key : chan.keys) { - zeus::CQuaternion q(key.rotation.val); - q = rig.restoreRotation(newChan.id, q); - if (sign == 0.f) - sign = q.w() < 0.f ? -1.f : 1.f; - q *= sign; - q.normalize(); - rotVals.emplace_back(q.mSimd); - } - - if (chan.attrMask & 0x2) { - newAnim.channels.emplace_back(); - DNAANIM::Channel& newChan = newAnim.channels.back(); - newChan.type = DNAANIM::Channel::Type::Translation; - newChan.id = search->second; - - newAnim.chanKeys.emplace_back(); - std::vector& transVals = newAnim.chanKeys.back(); - transVals.reserve(chan.keys.size()); - for (const BlenderAction::Channel::Key& key : chan.keys) { - zeus::CVector3f pos(key.position.val); - pos = rig.restorePosition(newChan.id, pos, true); - transVals.emplace_back(pos.mSimd); - } - } - } - - /* Retro's original data uses microsecond precision */ - newAnim.mainInterval = std::trunc(act.interval * 1000000.0) / 1000000.0; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ANIM.hpp b/DataSpec/DNAMP1/ANIM.hpp deleted file mode 100644 index e1983ebe5..000000000 --- a/DataSpec/DNAMP1/ANIM.hpp +++ /dev/null @@ -1,214 +0,0 @@ -#pragma once - -#include "DNAMP1.hpp" -#include "DataSpec/DNACommon/ANIM.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "CINF.hpp" -#include "EVNT.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" - -namespace DataSpec::DNAMP1 { - -struct ANIM : BigDNA { - AT_DECL_EXPLICIT_DNA - - static UniqueID32 GetEVNTId(athena::io::IStreamReader& r); - - struct IANIM : BigDNAV { - Delete expl; - atUint32 m_version; - IANIM(atUint32 version) : m_version(version) {} - - std::vector> bones; - std::vector frames; - std::vector channels; - std::vector> chanKeys; - float mainInterval = 0.0; - UniqueID32Zero evnt; - bool looping = false; - - void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter& rig) const; - }; - - struct ANIM0 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM0() : IANIM(0) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value duration; - Value unk0; - Value interval; - Value unk1; - Value keyCount; - Value unk2; - Value boneSlotCount; - }; - }; - - struct ANIM2 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM2(bool pc) : IANIM(pc ? 3 : 2) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value scratchSize; - UniqueID32Zero evnt; - Value unk0 = 1; - Value duration; - Value interval; - Value rootBoneId = 3; - Value looping = 0; - Value rotDiv; - Value translationMult; - Value boneChannelCount; - Value unk3; - Value keyBitmapBitCount; - }; - - struct ChannelDesc : BigDNA { - Delete expl; - Value id = 0; - Value keyCount1 = 0; - Value initRX = 0; - Value qRX = 0; - Value initRY = 0; - Value qRY = 0; - Value initRZ = 0; - Value qRZ = 0; - Value keyCount2 = 0; - Value initTX = 0; - Value qTX = 0; - Value initTY = 0; - Value qTY = 0; - Value initTZ = 0; - Value qTZ = 0; - - void read(athena::io::IStreamReader& reader) { - id = reader.readUint32Big(); - keyCount1 = reader.readUint16Big(); - initRX = reader.readInt16Big(); - qRX = reader.readUByte(); - initRY = reader.readInt16Big(); - qRY = reader.readUByte(); - initRZ = reader.readInt16Big(); - qRZ = reader.readUByte(); - keyCount2 = reader.readUint16Big(); - if (keyCount2) { - initTX = reader.readInt16Big(); - qTX = reader.readUByte(); - initTY = reader.readInt16Big(); - qTY = reader.readUByte(); - initTZ = reader.readInt16Big(); - qTZ = reader.readUByte(); - } - } - void write(athena::io::IStreamWriter& writer) const { - writer.writeUint32Big(id); - writer.writeUint16Big(keyCount1); - writer.writeInt16Big(initRX); - writer.writeUByte(qRX); - writer.writeInt16Big(initRY); - writer.writeUByte(qRY); - writer.writeInt16Big(initRZ); - writer.writeUByte(qRZ); - writer.writeUint16Big(keyCount2); - if (keyCount2) { - writer.writeInt16Big(initTX); - writer.writeUByte(qTX); - writer.writeInt16Big(initTY); - writer.writeUByte(qTY); - writer.writeInt16Big(initTZ); - writer.writeUByte(qTZ); - } - } - void binarySize(size_t& __isz) const { - __isz += 17; - if (keyCount2) - __isz += 9; - } - }; - - struct ChannelDescPC : BigDNA { - Delete expl; - Value id = 0; - Value keyCount1 = 0; - Value QinitRX = 0; - Value QinitRY = 0; - Value QinitRZ = 0; - Value keyCount2 = 0; - Value QinitTX = 0; - Value QinitTY = 0; - Value QinitTZ = 0; - - void read(athena::io::IStreamReader& reader) { - id = reader.readUint32Big(); - keyCount1 = reader.readUint32Big(); - QinitRX = reader.readUint32Big(); - QinitRY = reader.readUint32Big(); - QinitRZ = reader.readUint32Big(); - keyCount2 = reader.readUint32Big(); - if (keyCount2) { - QinitTX = reader.readUint32Big(); - QinitTY = reader.readUint32Big(); - QinitTZ = reader.readUint32Big(); - } - } - void write(athena::io::IStreamWriter& writer) const { - writer.writeUint32Big(id); - writer.writeUint32Big(keyCount1); - writer.writeUint32Big(QinitRX); - writer.writeUint32Big(QinitRY); - writer.writeUint32Big(QinitRZ); - writer.writeUint32Big(keyCount2); - if (keyCount2) { - writer.writeUint32Big(QinitTX); - writer.writeUint32Big(QinitTY); - writer.writeUint32Big(QinitTZ); - } - } - void binarySize(size_t& __isz) const { - __isz += 24; - if (keyCount2) - __isz += 12; - } - }; - }; - - std::unique_ptr m_anim; - - void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, bool) const { - m_anim->sendANIMToBlender(os, rig); - } - - bool isLooping() const { - if (!m_anim) - return false; - return m_anim->looping; - } - - void extractEVNT(const DNAANCS::AnimationResInfo& animInfo, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, bool force) const { - if (m_anim->evnt.isValid()) { - hecl::ProjectPath evntYamlPath = outPath.getWithExtension( - fmt::format(FMT_STRING(".{}_{}.evnt.yaml"), animInfo.name, m_anim->evnt).c_str(), true); - hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType(); - - if (force || evntYamlType == hecl::ProjectPath::Type::None) { - EVNT evnt; - if (pakRouter.lookupAndReadDNA(m_anim->evnt, evnt, true)) { - athena::io::FileWriter writer(evntYamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(evnt, writer); - } - } - } - } - - using BlenderAction = hecl::blender::Action; - - ANIM() = default; - ANIM(const BlenderAction& act, const std::unordered_map& idMap, - const DNAANIM::RigInverter& rig, bool pc); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CINF.cpp b/DataSpec/DNAMP1/CINF.cpp deleted file mode 100644 index 4a4773147..000000000 --- a/DataSpec/DNAMP1/CINF.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "CINF.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (const Bone& b : bones) { - if (b.id == id) - return idx; - ++idx; - } - return -1; -} - -atUint32 CINF::getBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (atUint32 bid : boneIds) { - if (bid == id) - return idx; - ++idx; - } - return 0; -} - -const std::string* CINF::getBoneNameFromId(atUint32 id) const { - for (const Name& name : names) - if (id == name.boneId) - return &name.name; - return nullptr; -} - -void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const { - for (atUint32 bid : boneIds) { - for (const Name& name : names) { - if (name.boneId == bid) { - os.format(FMT_STRING("obj.vertex_groups.new(name='{}')\n"), name.name); - break; - } - } - } -} - -void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const { - DNAANIM::RigInverter inverter(*this); - - os.format(FMT_STRING("arm = bpy.data.armatures.new('CINF_{}')\n" - "arm_obj = bpy.data.objects.new(arm.name, arm)\n" - "bpy.context.scene.collection.objects.link(arm_obj)\n" - "bpy.context.view_layer.objects.active = arm_obj\n" - "bpy.ops.object.mode_set(mode='EDIT')\n" - "arm_bone_table = {{}}\n"), - cinfId); - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) { - zeus::simd_floats originF(bone.m_origBone.origin.simd); - zeus::simd_floats tailF(bone.m_tail.mSimd); - os.format(FMT_STRING("bone = arm.edit_bones.new('{}')\n" - "bone.head = ({},{},{})\n" - "bone.tail = ({},{},{})\n" - "bone.use_inherit_scale = False\n" - "arm_bone_table[{}] = bone\n"), - *getBoneNameFromId(bone.m_origBone.id), originF[0], originF[1], originF[2], tailF[0], tailF[1], tailF[2], - bone.m_origBone.id); - } - - for (const Bone& bone : bones) - if (bone.parentId != 2) - os.format(FMT_STRING("arm_bone_table[{}].parent = arm_bone_table[{}]\n"), bone.id, bone.parentId); - - os << "bpy.ops.object.mode_set(mode='OBJECT')\n"; - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) - os.format(FMT_STRING("arm_obj.pose.bones['{}'].rotation_mode = 'QUATERNION'\n"), - *getBoneNameFromId(bone.m_origBone.id)); -} - -std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId) { return fmt::format(FMT_STRING("CINF_{}"), cinfId); } - -int CINF::RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, - std::map& nameMap) { - int selId; - auto search = idMap.find(bone->name); - if (search == idMap.end()) { - selId = curId++; - idMap.emplace(std::make_pair(bone->name, selId)); - } else - selId = search->second; - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = selId; - boneOut.id = selId; - boneOut.parentId = parent; - boneOut.origin = bone->origin; - boneOut.linkedCount = bone->children.size() + 1; - boneOut.linked.reserve(boneOut.linkedCount); - - const BlenderBone* child; - boneOut.linked.push_back(parent); - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId, idMap, nameMap)); - - return boneOut.id; -} - -CINF::CINF(const Armature& armature, std::unordered_map& idMap) { - idMap.reserve(armature.bones.size()); - bones.reserve(armature.bones.size()); - - std::map nameMap; - - const BlenderBone* bone = armature.getRoot(); - if (bone) { - if (bone->children.size()) { - int curId = 4; - const BlenderBone* child; - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - RecursiveAddArmatureBone(armature, child, 3, curId, idMap, nameMap); - } - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = 3; - boneOut.id = 3; - boneOut.parentId = 2; - boneOut.origin = bone->origin; - idMap.emplace(std::make_pair(bone->name, 3)); - - if (bone->children.size()) { - boneOut.linkedCount = 2; - boneOut.linked = {2, 4}; - } else { - boneOut.linkedCount = 1; - boneOut.linked = {2}; - } - } - - boneCount = bones.size(); - - names.reserve(nameMap.size()); - nameCount = nameMap.size(); - for (const auto& name : nameMap) { - names.emplace_back(); - Name& nameOut = names.back(); - nameOut.name = name.first; - nameOut.boneId = name.second; - } - - boneIdCount = boneCount; - boneIds.reserve(boneIdCount); - for (auto it = bones.crbegin(); it != bones.crend(); ++it) - boneIds.push_back(it->id); -} - -bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - if (!force && outPath.isFile()) - return true; - - auto& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Armature)) - return false; - auto os = conn.beginPythonOut(true); - - os.format(FMT_STRING("import bpy\n" - "from mathutils import Vector\n" - "bpy.context.scene.name = 'CINF_{}'\n" - "bpy.context.scene.hecl_arm_obj = bpy.context.scene.name\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n"), - entry.id); - - CINF cinf; - cinf.read(rs); - cinf.sendCINFToBlender(os, entry.id); - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -bool CINF::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature) { - std::unordered_map boneIdMap; - CINF cinf(armature, boneIdMap); - - /* Write out CINF resource */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - cinf.write(w); - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CINF.hpp b/DataSpec/DNAMP1/CINF.hpp deleted file mode 100644 index 877b401c2..000000000 --- a/DataSpec/DNAMP1/CINF.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct CINF : BigDNA { - AT_DECL_DNA - Value boneCount; - struct Bone : BigDNA { - AT_DECL_DNA - Value id; - Value parentId; - Value origin; - Value linkedCount; - Vector linked; - }; - Vector bones; - - Value boneIdCount; - Vector boneIds; - - Value nameCount; - struct Name : BigDNA { - AT_DECL_DNA - String<-1> name; - Value boneId; - }; - Vector names; - - atUint32 getInternalBoneIdxFromId(atUint32 id) const; - atUint32 getBoneIdxFromId(atUint32 id) const; - const std::string* getBoneNameFromId(atUint32 id) const; - void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const; - void sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const; - static std::string GetCINFArmatureName(const UniqueID32& cinfId); - - CINF() = default; - using Armature = hecl::blender::Armature; - using BlenderBone = hecl::blender::Bone; - - int RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, std::map& nameMap); - - CINF(const Armature& armature, std::unordered_map& idMap); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CMDL.cpp b/DataSpec/DNAMP1/CMDL.cpp deleted file mode 100644 index caae1808f..000000000 --- a/DataSpec/DNAMP1/CMDL.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include "CMDL.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - /* Check for RigPair */ - CINF cinf; - CSKR cskr; - using RigPair = std::pair, std::pair>; - RigPair loadRp = {}; - if (const typename CharacterAssociations::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) { - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - loadRp.first = {rp->cskr, &cskr}; - loadRp.second = {rp->cinf, &cinf}; - } - - /* Do extract */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_1, 2>( - conn, rs, pakRouter, entry, dataSpec, loadRp); - conn.saveBlend(); - -#if 0 - /* Cook and re-extract test */ - hecl::ProjectPath tempOut = outPath.getWithExtension(".recook", true); - hecl::blender::Connection::DataStream ds = conn.beginData(); - DNACMDL::Mesh mesh = ds.compileMesh(hecl::TopologyTriStrips, -1); - ds.close(); - DNACMDL::WriteCMDL(tempOut, outPath, mesh); - - athena::io::FileReader reader(tempOut.getAbsolutePath()); - hecl::ProjectPath tempBlend = outPath.getWithExtension(".recook.blend", true); - if (!conn.createBlend(tempBlend, hecl::blender::Connection::TypeMesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, std::pair, DNACMDL::SurfaceHeader_1_2, 2> - (conn, reader, pakRouter, entry, dataSpec, loadRp); - return conn.saveBlend(); -#elif 0 - /* HMDL cook test */ - hecl::ProjectPath tempOut = outPath.getWithExtension(".recook", true); - hecl::blender::Connection::DataStream ds = conn.beginData(); - DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16); - ds.close(); - DNACMDL::WriteHMDLCMDL(tempOut, outPath, mesh); -#endif - - return true; -} - -bool CMDL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) { - if (!mesh.skins.empty()) { - DNACMDL::Mesh skinMesh = mesh.getContiguousSkinningVersion(); - if (!DNACMDL::WriteCMDL(outPath, inPath, skinMesh)) - return false; - - /* Output skinning intermediate */ - auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin(); - athena::io::FileWriter writer(outPath.getWithExtension(".skinint").getAbsolutePath()); - writer.writeUint32Big(skinMesh.boneNames.size()); - for (const std::string& boneName : skinMesh.boneNames) - writer.writeString(boneName); - - writer.writeUint32Big(skinMesh.skins.size()); - for (const auto& skin : skinMesh.skins) { - size_t numBinds = skinMesh.countSkinBinds(skin); - writer.writeUint32Big(numBinds); - for (size_t i = 0; i < numBinds; ++i) { - writer.writeUint32Big(skin[i].vg_idx); - writer.writeFloatBig(skin[i].weight); - } - writer.writeUint32Big(*vertCountIt++); - } - writer.writeUint32Big(skinMesh.pos.size()); - writer.writeUint32Big(skinMesh.norm.size()); - } else if (!DNACMDL::WriteCMDL(outPath, inPath, mesh)) - return false; - return true; -} - -bool CMDL::HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh) { - hecl::blender::PoolSkinIndex poolSkinIndex; - if (mesh.skins.size()) { - if (!DNACMDL::WriteHMDLCMDL(outPath, inPath, mesh, poolSkinIndex)) - return false; - - /* Output skinning intermediate */ - athena::io::FileWriter writer(outPath.getWithExtension(".skinint").getAbsolutePath()); - writer.writeUint32Big(mesh.skinBanks.banks.size()); - for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks) { - writer.writeUint32Big(sb.m_boneIdxs.size()); - for (uint32_t bind : sb.m_boneIdxs) - writer.writeUint32Big(bind); - } - writer.writeUint32Big(mesh.boneNames.size()); - for (const std::string& boneName : mesh.boneNames) - writer.writeString(boneName); - - /* CVirtualBone structure just like original (for CPU skinning) */ - writer.writeUint32Big(mesh.skins.size()); - for (auto& s : mesh.skins) { - size_t numBinds = mesh.countSkinBinds(s); - writer.writeUint32Big(numBinds); - for (size_t i = 0; i < numBinds; ++i) { - writer.writeUint32Big(s[i].vg_idx); - writer.writeFloatBig(s[i].weight); - } - } - - /* Write indirection table mapping pool verts to CVirtualBones */ - writer.writeUint32Big(poolSkinIndex.m_poolSz); - for (uint32_t i = 0; i < poolSkinIndex.m_poolSz; ++i) - writer.writeUint32Big(poolSkinIndex.m_poolToSkinIndex[i]); - } else if (!DNACMDL::WriteHMDLCMDL(outPath, inPath, mesh, - poolSkinIndex)) - return false; - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CMDL.hpp b/DataSpec/DNAMP1/CMDL.hpp deleted file mode 100644 index a176b2d6d..000000000 --- a/DataSpec/DNAMP1/CMDL.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "CMDLMaterials.hpp" -#include "DNAMP1.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" - -#include - -namespace DataSpec::DNAMP1 { - -struct CMDL { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, - PAK::Entry& entry) { - DNACMDL::NameCMDL, MaterialSet>(rs, pakRouter, entry, dataSpec); - } - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh); - - static bool HMDLCook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const DNACMDL::Mesh& mesh); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CMDLMaterials.cpp b/DataSpec/DNAMP1/CMDLMaterials.cpp deleted file mode 100644 index 85738eb55..000000000 --- a/DataSpec/DNAMP1/CMDLMaterials.cpp +++ /dev/null @@ -1,1240 +0,0 @@ -#include "CMDLMaterials.hpp" -#include "../DNAMP2/CMDLMaterials.hpp" -#include "hecl/Blender/Connection.hpp" - -using Stream = hecl::blender::PyOutStream; - -namespace DataSpec::DNAMP1 { -using Material = MaterialSet::Material; - -void MaterialSet::RegisterMaterialProps(Stream& out) { - out << "bpy.types.Material.retro_depth_sort = bpy.props.BoolProperty(name='Retro: Transparent Depth Sort')\n" - "bpy.types.Material.retro_alpha_test = bpy.props.BoolProperty(name='Retro: Punchthrough Alpha')\n" - "bpy.types.Material.retro_samus_reflection = bpy.props.BoolProperty(name='Retro: Samus Reflection')\n" - "bpy.types.Material.retro_depth_write = bpy.props.BoolProperty(name='Retro: Depth Write')\n" - "bpy.types.Material.retro_samus_reflection_persp = bpy.props.BoolProperty(name='Retro: Samus Reflection " - "Perspective')\n" - "bpy.types.Material.retro_shadow_occluder = bpy.props.BoolProperty(name='Retro: Shadow Occluder')\n" - "bpy.types.Material.retro_samus_reflection_indirect = bpy.props.BoolProperty(name='Retro: Samus Reflection " - "Indirect Texture')\n" - "bpy.types.Material.retro_lightmapped = bpy.props.BoolProperty(name='Retro: Lightmapped')\n" - "\n"; -} - -void Material::AddTexture(Stream& out, GX::TexGenSrc type, int mtxIdx, uint32_t texIdx, bool diffuse) { - std::string mtxLabel; - if (mtxIdx == -1) - mtxLabel = "IDENTITY"; - else - mtxLabel = fmt::format(FMT_STRING("MTX_{}"), mtxIdx); - - std::string texLabel; - if (diffuse) - texLabel = "Diffuse"; - else - texLabel = "Texture"; - - out.format(FMT_STRING("# Texture\n" - "tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n" - "tex_node.label = '{} {}'\n" - "texture_nodes.append(tex_node)\n"), - texLabel, texIdx); - - if (texIdx != 0xff) - out.format(FMT_STRING("tex_node.image = tex_maps[{}]\n"), texIdx); - - if (type == GX::TG_POS) - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Window'], tex_node.inputs['Vector']))\n"; - else if (type == GX::TG_NRM) - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Normal'], tex_node.inputs['Vector']))\n"; - else if (type >= GX::TG_TEX0 && type <= GX::TG_TEX7) { - uint8_t texIdx = type - GX::TG_TEX0; - out.format( - FMT_STRING("tex_uv_node = new_nodetree.nodes.new('ShaderNodeUVMap')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['UV'], tex_node.inputs['Vector']))\n" - "tex_uv_node.uv_map = 'UV_{}'\n"), - texIdx); - } - - out.format(FMT_STRING("tex_uv_node.label = '{}'\n"), mtxLabel); - - out << "gridder.place_node(tex_uv_node, 0)\n" - "gridder.place_node(tex_node, 0)\n" - "tex_uv_node.location[0] -= 120\n" - "tex_node.location[0] += 120\n" - "tex_node.location[1] += 176\n" - "\n"; -} - -void Material::AddTextureAnim(Stream& out, UVAnimation::Mode type, unsigned idx, const float* vals) { - switch (type) { - case UVAnimation::Mode::MvInvNoTranslation: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode0NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx); - break; - case UVAnimation::Mode::MvInv: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode1NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx); - break; - case UVAnimation::Mode::Scroll: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode2Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = ({},{},0)\n" - " node.inputs[2].default_value = ({},{},0)\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3]); - break; - case UVAnimation::Mode::Rotation: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode3Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1]); - break; - case UVAnimation::Mode::HStrip: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode4Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " node.inputs[3].default_value = {}\n" - " node.inputs[4].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3]); - break; - case UVAnimation::Mode::VStrip: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode5Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " node.inputs[3].default_value = {}\n" - " node.inputs[4].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3]); - break; - case UVAnimation::Mode::Model: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode6NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx); - break; - case UVAnimation::Mode::CylinderEnvironment: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode7NodeN']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1]); - break; - case UVAnimation::Mode::Eight: - out.format(FMT_STRING("for link in list(tex_links):\n" - " if link.from_node.label == 'MTX_{}':\n" - " tex_links.remove(link)\n" - " soc_from = link.from_socket\n" - " soc_to = link.to_socket\n" - " node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - " node.node_tree = bpy.data.node_groups['RetroUVMode8Node']\n" - " node.location[0] = link.from_node.location[0] + 50\n" - " node.location[1] = link.from_node.location[1] - 50\n" - " node.inputs[1].default_value = {}\n" - " node.inputs[2].default_value = {}\n" - " node.inputs[3].default_value = {}\n" - " node.inputs[4].default_value = {}\n" - " node.inputs[5].default_value = {}\n" - " node.inputs[6].default_value = {}\n" - " node.inputs[7].default_value = {}\n" - " node.inputs[8].default_value = {}\n" - " node.inputs[9].default_value = {}\n" - " new_nodetree.links.remove(link)\n" - " new_nodetree.links.new(soc_from, node.inputs[0])\n" - " new_nodetree.links.new(node.outputs[0], soc_to)\n\n"), - idx, vals[0], vals[1], vals[2], vals[3], vals[4], vals[5], vals[6], vals[7], vals[8]); - break; - default: - break; - } -} - -void Material::AddKcolor(Stream& out, const GX::Color& col, unsigned idx) { - out.format(FMT_STRING("kcolors[{}] = ({}, {}, {}, {})\n" - "kalphas[{}] = {}\n" - "\n"), - idx, (float)col.color[0] / (float)0xff, (float)col.color[1] / (float)0xff, - (float)col.color[2] / (float)0xff, (float)col.color[3] / (float)0xff, idx, - (float)col.color[3] / (float)0xff); -} - -template -static uint32_t _HashTextureConfig(const MAT& mat) { - XXH32_state_t xxHash; - XXH32_reset(&xxHash, 0); - for (uint32_t i = 0; i < mat.tevStageCount; ++i) { - const auto& stage = mat.tevStages[i]; - XXH32_update(&xxHash, &stage.ciFlags, sizeof(stage.ciFlags)); - XXH32_update(&xxHash, &stage.aiFlags, sizeof(stage.aiFlags)); - XXH32_update(&xxHash, &stage.ccFlags, sizeof(stage.ccFlags)); - XXH32_update(&xxHash, &stage.acFlags, sizeof(stage.acFlags)); - XXH32_update(&xxHash, &stage.kaInput, sizeof(stage.kaInput)); - XXH32_update(&xxHash, &stage.kcInput, sizeof(stage.kcInput)); - XXH32_update(&xxHash, &stage.rascInput, sizeof(stage.rascInput)); - } - bool hasInd = mat.flags.samusReflectionIndirectTexture(); - XXH32_update(&xxHash, &hasInd, sizeof(hasInd)); - bool hasLm = mat.flags.lightmap(); - XXH32_update(&xxHash, &hasLm, sizeof(hasLm)); - return XXH32_digest(&xxHash); -} - -static const char* ToString(GX::TevColorArg arg) { - switch (arg) { - case GX::CC_CPREV: - return "CC_CPREV"; - case GX::CC_APREV: - return "CC_APREV"; - case GX::CC_C0: - return "CC_C0"; - case GX::CC_A0: - return "CC_A0"; - case GX::CC_C1: - return "CC_C1"; - case GX::CC_A1: - return "CC_A1"; - case GX::CC_C2: - return "CC_C2"; - case GX::CC_A2: - return "CC_A2"; - case GX::CC_TEXC: - return "CC_TEXC"; - case GX::CC_TEXA: - return "CC_TEXA"; - case GX::CC_RASC: - return "CC_RASC"; - case GX::CC_RASA: - return "CC_RASA"; - case GX::CC_ONE: - return "CC_ONE"; - case GX::CC_HALF: - return "CC_HALF"; - case GX::CC_KONST: - return "CC_KONST"; - case GX::CC_ZERO: - return "CC_ZERO"; - default: - return "UNKNOWN"; - } -} - -static const char* ToString(GX::TevAlphaArg arg) { - switch (arg) { - case GX::CA_APREV: - return "CA_APREV"; - case GX::CA_A0: - return "CA_A0"; - case GX::CA_A1: - return "CA_A1"; - case GX::CA_A2: - return "CA_A2"; - case GX::CA_TEXA: - return "CA_TEXA"; - case GX::CA_RASA: - return "CA_RASA"; - case GX::CA_KONST: - return "CA_KONST"; - case GX::CA_ZERO: - return "CA_ZERO"; - default: - return "UNKNOWN"; - } -} - -static const char* ToString(GX::TevRegID arg) { - switch (arg) { - case GX::TEVPREV: - return "TEVPREV"; - case GX::TEVREG0: - return "TEVREG0"; - case GX::TEVREG1: - return "TEVREG1"; - case GX::TEVREG2: - return "TEVREG2"; - default: - return "UNKNOWN"; - } -} - -// FIXME remove; bug with fmtlib 8.0.0 & AppleClang 12.0.5 -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-local-typedef" -#endif -template -static void _DescribeTEV(const MAT& mat) { - for (uint32_t i = 0; i < mat.tevStageCount; ++i) { - const auto& stage = mat.tevStages[i]; - fmt::print(stderr, FMT_STRING("A:{} B:{} C:{} D:{} -> {} | A:{} B:{} C:{} D:{} -> {}\n"), - ToString(stage.colorInA()), ToString(stage.colorInB()), ToString(stage.colorInC()), - ToString(stage.colorInD()), ToString(stage.colorOpOutReg()), ToString(stage.alphaInA()), - ToString(stage.alphaInB()), ToString(stage.alphaInC()), ToString(stage.alphaInD()), - ToString(stage.alphaOpOutReg())); - } - bool hasInd = mat.flags.samusReflectionIndirectTexture(); - bool hasLm = mat.flags.lightmap(); - fmt::print(stderr, FMT_STRING("HasIndirect: {} HasLightmap: {}\n"), hasInd, hasLm); -} -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -struct TexLink { - const char* shaderInput; - int texidx; - bool alpha; - TexLink(const char* shaderInput, int texidx = -1, bool alpha = false) - : shaderInput(shaderInput), texidx(texidx), alpha(alpha) {} -}; - -struct ExtendedSpecularLink { - int texidx; - ExtendedSpecularLink(int texidx = -1) : texidx(texidx) {} -}; - -struct KColLink { - const char* shaderInput; - int kcidx; - bool alpha; - KColLink(const char* shaderInput, int kcidx = 0, bool alpha = false) - : shaderInput(shaderInput), kcidx(kcidx), alpha(alpha) {} -}; - -struct WhiteColorLink { - const char* shaderInput; - explicit WhiteColorLink(const char* shaderInput) : shaderInput(shaderInput) {} -}; - -static void _GenerateRootShader(Stream& out, int) { /* End of shader links */ -} - -template -static void _GenerateRootShader(Stream& out, int tidx, TexLink tex, Targs... args) { - int texIdx = tex.texidx == -1 ? tidx : tex.texidx; - out << "texture_nodes[" << texIdx << "].name = '" << tex.shaderInput << "'\n"; - out << "texture_nodes[" << texIdx << "].label = '" << tex.shaderInput << "'\n"; - out << "new_nodetree.links.new(texture_nodes[" << texIdx << "].outputs['" << (tex.alpha ? "Alpha" : "Color") - << "'], node.inputs['" << tex.shaderInput << "'])\n"; - if (tex.texidx == -1) - ++tidx; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, int tidx, ExtendedSpecularLink tex, Targs... args) { - int texIdx = tex.texidx == -1 ? tidx : tex.texidx; - out << "texture_nodes[" << texIdx << "].name = 'Specular'\n"; - out << "texture_nodes[" << texIdx << "].label = 'Specular'\n"; - out << "new_nodetree.links.new(texture_nodes[" << texIdx << "].outputs['Color'], node.inputs['Specular'])\n"; - out << "new_nodetree.links.new(texture_nodes[" << texIdx << "].outputs['Alpha'], node.inputs['ExtendedSpecular'])\n"; - if (tex.texidx == -1) - ++tidx; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, int tidx, KColLink kcol, Targs... args) { - out << "node.inputs['" << kcol.shaderInput << "'].default_value = " << (kcol.alpha ? "kalphas[" : "kcolors[") - << kcol.kcidx << "]\n"; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, int tidx, WhiteColorLink wcol, Targs... args) { - out << "node.inputs['" << wcol.shaderInput << "'].default_value = (1.0, 1.0, 1.0, 1.0)\n"; - _GenerateRootShader(out, tidx, args...); -} - -template -static void _GenerateRootShader(Stream& out, const char* type, Targs... args) { - out << "node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - "node.name = 'Output'\n" - "node.node_tree = bpy.data.node_groups['" - << type - << "']\n" - "gridder.place_node(node, 1)\n" - "new_nodetree.links.new(node.outputs['Surface'], blend_node.inputs['Surface'])\n"; - _GenerateRootShader(out, 0, args...); -} - -static TexLink operator"" _tex(const char* str, size_t) { return TexLink(str); } -static TexLink operator"" _texa(const char* str, size_t) { return TexLink(str, -1, true); } -static KColLink operator"" _kcol(const char* str, size_t) { return KColLink(str); } -static KColLink operator"" _kcola(const char* str, size_t) { return KColLink(str, 0, true); } - -template -static void _ConstructMaterial(Stream& out, const MAT& material, unsigned groupIdx, unsigned matIdx) { - unsigned i; - - out.format(FMT_STRING("new_material = bpy.data.materials.new('MAT_{}_{}')\n"), groupIdx, matIdx); - out << "new_material.use_fake_user = True\n" - "new_material.use_nodes = True\n" - "new_material.use_backface_culling = True\n" - "new_material.blend_method = 'BLEND'\n" - "new_nodetree = new_material.node_tree\n" - "for n in new_nodetree.nodes:\n" - " new_nodetree.nodes.remove(n)\n" - "\n" - "gridder = hecl.Nodegrid(new_nodetree)\n" - "\n" - "texture_nodes = []\n" - "kcolors = {}\n" - "kalphas = {}\n" - "tex_links = []\n" - "\n"; - - /* Material Flags */ - out.format(FMT_STRING("new_material.retro_depth_sort = {}\n" - "new_material.retro_alpha_test = {}\n" - "new_material.retro_samus_reflection = {}\n" - "new_material.retro_depth_write = {}\n" - "new_material.retro_samus_reflection_persp = {}\n" - "new_material.retro_shadow_occluder = {}\n" - "new_material.retro_samus_reflection_indirect = {}\n" - "new_material.retro_lightmapped = {}\n" - "new_material.diffuse_color = (1, 1, 1, {})\n"), - material.flags.depthSorting() ? "True" : "False", material.flags.alphaTest() ? "True" : "False", - material.flags.samusReflection() ? "True" : "False", material.flags.depthWrite() ? "True" : "False", - material.flags.samusReflectionSurfaceEye() ? "True" : "False", - material.flags.shadowOccluderMesh() ? "True" : "False", - material.flags.samusReflectionIndirectTexture() ? "True" : "False", - material.flags.lightmap() ? "True" : "False", material.flags.shadowOccluderMesh() ? "0" : "1"); - - /* Texture Indices */ - out << "tex_maps = []\n"; - for (atUint32 idx : material.textureIdxs) - out.format(FMT_STRING("tex_maps.append(texmap_list[{}])\n"), idx); - - /* KColor entries */ - if (material.flags.konstValuesEnabled()) { - unsigned i = 0; - for (const GX::Color& col : material.konstColors) - Material::AddKcolor(out, col, i++); - } - - /* Blend factors */ - out << "blend_node = new_nodetree.nodes.new('ShaderNodeGroup')\n" - "blend_node.name = 'Blend'\n" - "gridder.place_node(blend_node, 2)\n"; - using BlendFactor = Material::BlendFactor; - if (material.blendDstFac != BlendFactor::BL_ZERO) { - if (material.blendDstFac == BlendFactor::BL_ONE) - out << "blend_node.node_tree = bpy.data.node_groups['HECLAdditiveOutput']\n"; - else - out << "blend_node.node_tree = bpy.data.node_groups['HECLBlendOutput']\n"; - } else { - out << "blend_node.node_tree = bpy.data.node_groups['HECLOpaqueOutput']\n" - "new_material.blend_method = 'OPAQUE'\n"; - } - - /* Add texture maps/tcgs */ - unsigned addedTcgs = 0; - bool diffuseStage = false; - for (i = 0; i < material.tevStageCount; ++i) { - if (material.tevStageTexInfo[i].tcgSlot != 0xff && !(addedTcgs >> material.tevStageTexInfo[i].tcgSlot & 1)) { - const Material::TexCoordGen& tcg = material.tcgs[material.tevStageTexInfo[i].tcgSlot]; - GX::TexMtx mtx = tcg.mtx(); - int mtxIdx = -1; - if (mtx >= GX::TEXMTX0 && mtx <= GX::TEXMTX9) - mtxIdx = (mtx - GX::TEXMTX0) / 3; - Material::AddTexture(out, tcg.source(), mtxIdx, material.tevStageTexInfo[i].texSlot, diffuseStage); - addedTcgs |= 1 << material.tevStageTexInfo[i].tcgSlot; - } - diffuseStage = material.tevStages[i].colorOpOutReg() == GX::TEVREG0; - } - - /* Indirect texture node */ - if (material.flags.samusReflectionIndirectTexture()) - Material::AddTexture(out, GX::TexGenSrc::TG_POS, -1, material.indTexSlot[0], false); - - /* Select appropriate root shader and link textures */ - uint32_t hash = _HashTextureConfig(material); - switch (hash) { - case 0x03FEE002: /* RetroShader: Diffuse, Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Reflection"_tex); - break; - case 0x0473AE40: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex); - break; - case 0x072D2CB3: /* RetroShader: Diffuse, Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, WhiteColorLink("Specular"), - "Reflection"_tex); - break; - case 0x07AA75D7: /* RetroShader: Diffuse, Emissive, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 0, true)); - break; - case 0x0879D346: /* RetroShader: KColorDiffuse, Alpha=Texture */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Alpha"_tex); - break; - case 0x0DA256BB: /* Lightmap, Diffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - "Alpha"_kcola); - break; - case 0x11C41DA4: /* RetroDynamicCharacterShader: Diffuse, DynamicMaskTex, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicCharacterShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0x1218F83E: /* RetroShader: ObjLightmap, Diffuse, ExtendedSpecular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, ExtendedSpecularLink(), "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0x129B8578: /* RetroShader: KColorDiffuse, Emissive, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Emissive"_tex, "Alpha"_kcola); - break; - case 0x15A00948: /* RetroShader: Diffuse, Emissive, Specular, ExtendedSpecular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "ExtendedSpecular"_tex, - "Reflection"_tex); - break; - case 0x15A3E6E5: /* RetroShader: Diffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x1BEB3E15: /* RetroShader: Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0x2261E0EB: /* RetroShader: Diffuse, Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0x239C7724: /* RetroDynamicShader: Diffuse*Dynamic, Emissive*Dynamic, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0x240C4C84: /* RetroShader: Lightmap, KColorDiffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Specular"_tex, "Reflection"_tex, - "Alpha"_kcola); - break; - case 0x2523A379: /* RetroDynamicShader: Emissive*Dynamic, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0x25E85017: /* RetroShader: Lightmap, KColorDiffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Alpha"_kcola); - break; - case 0x27FD5C6C: /* RetroShader: ObjLightmap, Diffuse, Specular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0x2AD9F535: /* RetroShader: Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex, WhiteColorLink("Specular"), "Reflection"_tex); - break; - case 0x2C9F5104: /* RetroShader: Diffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "Alpha"_kcola); - break; - case 0x2D059429: /* RetroShader: Diffuse, Emissive, ExtendedSpecular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, ExtendedSpecularLink(), "Reflection"_tex); - break; - case 0x30AC64BB: /* RetroShader: Diffuse, Specular, Reflection, Alpha=KAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "IndirectTex"_tex, - "Alpha"_kcola); - break; - case 0x39BC4809: /* RetroDynamicShader: ObjLightmap*Dynamic, Diffuse*Dynamic, Emissive*Dynamic, Specular, Reflection, - Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0x3BF97299: /* RetroShader: Lightmap, Diffuse, Specular, Reflection, Alpha=KAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - "IndirectTex"_tex, "Alpha"_kcola); - break; - case 0x4184FBCA: /* RetroShader: Lightmap, Diffuse, Emissive, DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 1, true)); - break; - case 0x47ECF3ED: /* RetroShader: Diffuse, Specular, Reflection, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "Emissive"_tex); - break; - case 0x4BBDFFA6: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0x4D4127A3: /* RetroShader: Lightmap, Diffuse, Specular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0x54A92F25: /* RetroShader: ObjLightmap, KColorDiffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_kcol, "Alpha"_kcola); - break; - case 0x58BAA415: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha=1.0 */ - // TODO: Last stage assigns into unused reg2, perhaps for runtime material mod? - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex); - break; - case 0x54C6204C: - _GenerateRootShader(out, "RetroShader"); - break; - case 0x5A62D5F0: /* RetroShader: Lightmap, Diffuse, UnusedExtendedSpecular?, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0x5CB59821: /* RetroShader: Diffuse, UnusedSpecular?, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x5D0F0069: /* RetroShader: Diffuse, Emissive, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 0, true)); - break; - case 0x5D80E53C: /* RetroShader: Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0x5F0AB0E9: /* RetroShader: Lightmap, Diffuse, UnusedSpecular?, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0x5F189425: /* RetroShader: Lightmap, Diffuse, UnusedSpecular?, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x6601D113: /* RetroShader: Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex); - break; - case 0x694287FA: /* RetroShader: Diffuse, Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, WhiteColorLink("Specular"), - "Reflection"_tex); - break; - case 0x6D98D689: /* RetroDynamicAlphaShader: Diffuse*Dynamic, Specular, Reflection, Alpha=KAlpha*Dynamic */ - _GenerateRootShader(out, "RetroDynamicAlphaShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "Alpha"_kcola); - break; - case 0x7252CB90: /* RetroShader: Lightmap, Diffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Alpha"_kcola); - break; - case 0x72BEDDAC: /* RetroShader: DiffuseMod, Diffuse, Emissive, Specular, Reflection Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "DiffuseMod"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0x76BEA57E: /* RetroShader: Lightmap, Diffuse, Emissive, Specular, Reflection, Alpha=1.0, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex, "IndirectTex"_tex); - break; - case 0x7D6A4487: /* RetroShader: Diffuse, Specular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, TexLink("Alpha", 0, true)); - break; - case 0x81106196: /* RetroDynamicShader: Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Emissive"_tex); - break; - case 0x84319328: /* RetroShader: Reflection, UnusedSpecular?, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", WhiteColorLink("Specular"), "Reflection"_tex); - break; - case 0x846215DA: /* RetroShader: Diffuse, Specular, Reflection, Alpha=DiffuseAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, "IndirectTex"_tex, - TexLink("Alpha", 0, true)); - break; - case 0x8C562AB1: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0x8E916C01: /* RetroShader: NULL, all inputs 0 */ - _GenerateRootShader(out, "RetroShader"); - break; - case 0x957709F8: /* RetroShader: Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex); - break; - case 0x96ABB2D3: /* RetroShader: Lightmap, Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0x985A0B67: /* RetroShader: Diffuse, UnusedSpecular?, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0x9B4453A2: /* RetroShader: Diffuse, Emissive, ExtendedSpecular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, ExtendedSpecularLink(), "Reflection"_tex); - break; - case 0xA187C630: /* RetroShader: Diffuse, Emissive, UnusedReflection?, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xB26E9E2E: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - // TODO: Last two stages assign into unused reg2, perhaps for runtime material mod? - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xC0E3FF1F: /* RetroShader: KColorDiffuse, Specular, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Specular"_tex, "Reflection"_tex, "Alpha"_kcola); - break; - case 0xC138DCFA: /* RetroShader: Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xC3C8B1C8: /* RetroShader: KColorDiffuse, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Alpha"_kcola); - break; - case 0xC689C8C6: /* RetroShader: Diffuse, ExtendedSpecular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, ExtendedSpecularLink(), "Reflection"_tex, - TexLink("Alpha", 0, true)); - break; - case 0xC6B18B28: /* RetroShader: Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0xCD92D4C5: /* RetroShader: Diffuse, Reflection, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, WhiteColorLink("Specular"), "Reflection"_tex, "Alpha"_kcola); - break; - case 0xCE06F3F2: /* RetroShader: Diffuse, Alpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0xD73E7728: /* RetroShader: ObjLightmap, Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0xDB8F01AD: /* RetroDynamicShader: Diffuse*Dynamic, Emissive*Dynamic, UnusedSpecular?, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Diffuse"_tex, "Emissive"_tex); - break; - case 0xE64D1085: /* RetroShader: Lightmap, Diffuse, Emissive, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Reflection"_tex, - TexLink("Alpha", 1, true)); - break; - case 0xE6784B10: /* RetroShader: Lightmap, Diffuse, Specular, Reflection, Alpha=DiffuseAlpha, IndirectTex */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "Reflection"_tex, - "IndirectTex"_tex, TexLink("Alpha", 1, true)); - break; - case 0xE68FF182: /* RetroShader: Diffuse, Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0xE92F1340: /* RetroShader: Diffuse, Alpha=DiffuseAlpha*AlphaMod */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_tex, TexLink("Alpha", 0, true), TexLink("AlphaMod", 1, true)); - break; - case 0xEB4645CF: /* RetroDynamicAlphaShader: Diffuse*Dynamic, Alpha=DiffuseAlpha*Dynamic */ - _GenerateRootShader(out, "RetroDynamicAlphaShader", "Diffuse"_tex, TexLink("Alpha", 0, true)); - break; - case 0xECEF8D1F: /* RetroDynamicShader: Diffuse*Dynamic, Emissive*Dynamic, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroDynamicShader", "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, "Reflection"_tex); - break; - case 0xF1C26570: /* RetroShader: Lightmap, Diffuse, Specular, ExtendedSpecular, Reflection, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Specular"_tex, "ExtendedSpecular"_tex, - "Reflection"_tex, TexLink("Alpha", 1, true)); - break; - case 0xF345C16E: /* RetroShader: Emissive, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Emissive"_tex, "Reflection"_tex); - break; - case 0xF4DA0A86: /* RetroShader: KColorDiffuse, Emissive, Alpha=KAlpha */ - _GenerateRootShader(out, "RetroShader", "Diffuse"_kcol, "Emissive"_tex, "Alpha"_kcola); - break; - break; - case 0xF559DB08: /* RetroShader: Lightmap, Diffuse, Emissive, Specular, Reflection, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, "Specular"_tex, - "Reflection"_tex); - break; - case 0xF9324367: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha=1.0 */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex); - break; - case 0xFC2761B8: /* RetroShader: Lightmap, Diffuse, Alpha=DiffuseAlpha*AlphaMod */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true), - TexLink("AlphaMod", 2, true)); - break; - case 0xFD95D7FD: /* RetroShader: ObjLightmap, Diffuse, Alpha=DiffuseAlpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, TexLink("Alpha", 1, true)); - break; - case 0xFFF3CEBB: /* RetroShader: Lightmap, Diffuse, Emissive, Alpha */ - _GenerateRootShader(out, "RetroShader", "Lightmap"_tex, "Diffuse"_tex, "Emissive"_tex, TexLink("Alpha", 3, true)); - break; - default: - _DescribeTEV(material); - Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve shader hash {:08X}\n"), hash); - break; - } - - /* Has Lightmap? */ - if (material.flags.lightmap()) { - if (material.tevStageTexInfo[0].texSlot != 0xff) - out << "new_material.hecl_lightmap = tex_maps[0].name\n" - "tex_maps[0].use_fake_user = True\n"; - } - - /* Texmtx Animation Section */ - i = 0; - for (const Material::UVAnimation& anim : material.uvAnims) - Material::AddTextureAnim(out, anim.mode, i++, anim.vals); -} - -void MaterialSet::ConstructMaterial(Stream& out, const MaterialSet::Material& material, unsigned groupIdx, - unsigned matIdx) { - _ConstructMaterial(out, material, groupIdx, matIdx); -} - -MaterialSet::Material::Material(const hecl::blender::Material& mat, std::vector& texPathsOut, - int colorCount, bool lightmapUVs, bool matrixSkinning) { - /* TODO: Rewrite for new shader rep */ - XXH32_state_t xxHash; - XXH32_reset(&xxHash, 0); - -#if 0 - if (gx.m_kcolorCount) { - flags.setKonstValuesEnabled(true); - konstCount.push_back(gx.m_kcolorCount); - } -#endif - - auto search = mat.iprops.find("retro_depth_sort"); - if (search != mat.iprops.end()) - flags.setDepthSorting(search->second != 0); - - search = mat.iprops.find("retro_alpha_test"); - if (search != mat.iprops.end()) - flags.setAlphaTest(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection"); - if (search != mat.iprops.end()) - flags.setSamusReflection(search->second != 0); - - search = mat.iprops.find("retro_depth_write"); - if (search != mat.iprops.end()) - flags.setDepthWrite(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_persp"); - if (search != mat.iprops.end()) - flags.setSamusReflectionSurfaceEye(search->second != 0); - - search = mat.iprops.find("retro_shadow_occluder"); - if (search != mat.iprops.end()) - flags.setShadowOccluderMesh(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_indirect"); - if (search != mat.iprops.end()) - flags.setSamusReflectionIndirectTexture(search->second != 0); - - search = mat.iprops.find("retro_lightmapped"); - if (search != mat.iprops.end()) - flags.setLightmap(search->second != 0); - - flags.setLightmapUVArray(lightmapUVs); - -#if 0 - atUint16 texFlags = 0; - atUint16 tcgFlags = 0; - tevStageTexInfo.reserve(gx.m_tevCount); - textureIdxs.reserve(gx.m_tevCount); - for (unsigned i = 0; i < gx.m_tevCount; ++i) { - const hecl::Backend::GX::TEVStage& stage = gx.m_tevs[i]; - tevStageTexInfo.emplace_back(); - TEVStageTexInfo& texInfo = tevStageTexInfo.back(); - if (stage.m_texGenIdx != -1) { - texInfo.tcgSlot = stage.m_texGenIdx; - const hecl::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[stage.m_texGenIdx]; - if (tcg.m_src >= hecl::Backend::GX::TG_TEX0 && tcg.m_src <= hecl::Backend::GX::TG_TEX6) - tcgFlags |= 1 << (tcg.m_src - hecl::Backend::GX::TG_TEX0); - } - if (stage.m_texMapIdx != -1) { - texInfo.texSlot = textureIdxs.size(); - const hecl::ProjectPath& texPath = texPathsIn.at(stage.m_texMapIdx); - texFlags |= 1 << i; - ++textureCount; - bool found = false; - for (size_t t = 0; t < texPathsOut.size(); ++t) { - if (texPath == texPathsOut[t]) { - found = true; - textureIdxs.push_back(t); - break; - } - } - if (!found) { - textureIdxs.push_back(texPathsOut.size()); - texPathsOut.push_back(texPath); - } - } - } - flags.setTextureSlots(texFlags); - - XXH32_update(&xxHash, &flags.flags, sizeof(flags.flags)); - - vaFlags.setPosition(GX::INDEX16); - vaFlags.setNormal(GX::INDEX16); - - if (0 < colorCount) - vaFlags.setColor0(GX::INDEX16); - if (1 < colorCount) - vaFlags.setColor1(GX::INDEX16); - - if (tcgFlags & (1 << 0)) - vaFlags.setTex0(GX::INDEX16); - if (tcgFlags & (1 << 1)) - vaFlags.setTex1(GX::INDEX16); - if (tcgFlags & (1 << 2)) - vaFlags.setTex2(GX::INDEX16); - if (tcgFlags & (1 << 3)) - vaFlags.setTex3(GX::INDEX16); - if (tcgFlags & (1 << 4)) - vaFlags.setTex4(GX::INDEX16); - if (tcgFlags & (1 << 5)) - vaFlags.setTex5(GX::INDEX16); - if (tcgFlags & (1 << 6)) - vaFlags.setTex6(GX::INDEX16); - - if (matrixSkinning) { - vaFlags.setPnMatIdx(GX::DIRECT); - if (tcgFlags & (1 << 0)) - vaFlags.setTex0MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 1)) - vaFlags.setTex1MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 2)) - vaFlags.setTex2MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 3)) - vaFlags.setTex3MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 4)) - vaFlags.setTex4MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 5)) - vaFlags.setTex5MatIdx(GX::DIRECT); - if (tcgFlags & (1 << 6)) - vaFlags.setTex6MatIdx(GX::DIRECT); - } - - XXH32_update(&xxHash, &vaFlags.vaFlags, sizeof(vaFlags.vaFlags)); - - XXH32_update(&xxHash, &gx.m_kcolorCount, sizeof(gx.m_kcolorCount)); - for (unsigned i = 0; i < gx.m_kcolorCount; ++i) { - konstColors.emplace_back(gx.m_kcolors[i]); - XXH32_update(&xxHash, &gx.m_kcolors[i].num, sizeof(gx.m_kcolors[i].num)); - } - - blendDstFac = BlendFactor(gx.m_blendDst); - XXH32_update(&xxHash, &gx.m_blendDst, sizeof(gx.m_blendDst)); - blendSrcFac = BlendFactor(gx.m_blendSrc); - XXH32_update(&xxHash, &gx.m_blendSrc, sizeof(gx.m_blendSrc)); - if (flags.samusReflectionIndirectTexture()) { - indTexSlot.push_back(textureIdxs.size()); - XXH32_update(&xxHash, &indTexSlot.back(), sizeof(indTexSlot.back())); - } - - colorChannelCount = 1; - XXH32_update(&xxHash, &colorChannelCount, sizeof(colorChannelCount)); - colorChannels.emplace_back(); - ColorChannel& ch = colorChannels.back(); - for (unsigned i = 0; i < gx.m_tevCount; ++i) { - const hecl::Backend::GX::TEVStage& stage = gx.m_tevs[i]; - for (int c = 0; c < 4; ++c) - if (stage.m_color[c] == hecl::Backend::GX::CC_RASC || stage.m_color[c] == hecl::Backend::GX::CC_RASA || - stage.m_alpha[c] == hecl::Backend::GX::CA_RASA) { - ch.setLighting(true); - uint8_t one = 1; - XXH32_update(&xxHash, &one, sizeof(one)); - break; - } - if (ch.lighting()) - break; - } - ch.setDiffuseFn(GX::DF_CLAMP); - ch.setAttenuationFn(GX::AF_SPOT); - - tevStageCount = gx.m_tevCount; - XXH32_update(&xxHash, &tevStageCount, sizeof(tevStageCount)); - tevStages.reserve(gx.m_tevCount); - for (unsigned i = 0; i < gx.m_tevCount; ++i) { - const hecl::Backend::GX::TEVStage& stage = gx.m_tevs[i]; - tevStages.emplace_back(); - TEVStage& target = tevStages.back(); - - target.setColorInA(stage.m_color[0]); - target.setColorInB(stage.m_color[1]); - target.setColorInC(stage.m_color[2]); - target.setColorInD(stage.m_color[3]); - target.setAlphaInA(stage.m_alpha[0]); - target.setAlphaInB(stage.m_alpha[1]); - target.setAlphaInC(stage.m_alpha[2]); - target.setAlphaInD(stage.m_alpha[3]); - target.setColorOp(stage.m_cop); - target.setColorOpBias(GX::TB_ZERO); - target.setColorOpScale(GX::CS_SCALE_1); - target.setColorOpClamp(true); - target.setColorOpOutReg(stage.m_cRegOut); - target.setAlphaOp(stage.m_aop); - target.setAlphaOpBias(GX::TB_ZERO); - target.setAlphaOpScale(GX::CS_SCALE_1); - target.setAlphaOpClamp(true); - target.setAlphaOpOutReg(stage.m_aRegOut); - target.setKColorIn(stage.m_kColor); - target.setKAlphaIn(stage.m_kAlpha); - - target.setRASIn(GX::GX_COLOR_NULL); - for (int c = 0; c < 4; ++c) - if (stage.m_color[c] == hecl::Backend::GX::CC_RASC || stage.m_color[c] == hecl::Backend::GX::CC_RASA || - stage.m_alpha[c] == hecl::Backend::GX::CA_RASA) { - target.setRASIn(GX::GX_COLOR0A0); - break; - } - - XXH32_update(&xxHash, &target.ciFlags, sizeof(target.ciFlags)); - XXH32_update(&xxHash, &target.aiFlags, sizeof(target.aiFlags)); - XXH32_update(&xxHash, &target.ccFlags, sizeof(target.ccFlags)); - XXH32_update(&xxHash, &target.acFlags, sizeof(target.acFlags)); - XXH32_update(&xxHash, &target.kaInput, sizeof(target.kaInput)); - XXH32_update(&xxHash, &target.kcInput, sizeof(target.kcInput)); - XXH32_update(&xxHash, &target.rascInput, sizeof(target.rascInput)); - } - - tcgCount = gx.m_tcgCount; - XXH32_update(&xxHash, &tcgCount, sizeof(tcgCount)); - for (unsigned i = 0; i < gx.m_tcgCount; ++i) { - const hecl::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[i]; - tcgs.emplace_back(); - TexCoordGen& target = tcgs.back(); - target.setType(GX::TG_MTX3x4); - target.setSource(tcg.m_src); - target.setMtx(tcg.m_mtx); - target.setNormalize(tcg.m_norm); - target.setPostMtx(tcg.m_pmtx); - - XXH32_update(&xxHash, &target.flags, sizeof(target.flags)); - } - - uvAnimsSize = 4; - uvAnimsCount = 0; - for (; uvAnimsCount < 8;) { - bool found = false; - for (unsigned t = 0; t < gx.m_tcgCount; ++t) { - const hecl::Backend::GX::TexCoordGen& tcg = gx.m_tcgs[t]; - if (tcg.m_mtx == GX::IDENTITY) - continue; - if ((tcg.m_mtx - GX::TEXMTX0) / 3 == uvAnimsCount) { - found = true; - ++uvAnimsCount; - uvAnims.emplace_back(tcg.m_gameFunction, tcg.m_gameArgs); - XXH32_update(&xxHash, tcg.m_gameFunction.data(), sizeof(tcg.m_gameFunction.size())); - for (const atVec4f& arg : tcg.m_gameArgs) - XXH32_update(&xxHash, &arg, sizeof(arg)); - size_t tmpUvAnimsSize = uvAnimsSize; - uvAnims.back().binarySize(tmpUvAnimsSize); - uvAnimsSize = tmpUvAnimsSize; - break; - } - } - if (!found) - break; - } - - XXH32_update(&xxHash, &uvAnimsSize, sizeof(uvAnimsSize)); - XXH32_update(&xxHash, &uvAnimsCount, sizeof(uvAnimsCount)); -#endif - - uniqueIdx = XXH32_digest(&xxHash); -} - -HMDLMaterialSet::Material::Material(const hecl::blender::Material& mat) { - auto search = mat.iprops.find("retro_depth_sort"); - if (search != mat.iprops.end()) - flags.setDepthSorting(search->second != 0); - - search = mat.iprops.find("retro_alpha_test"); - if (search != mat.iprops.end()) - flags.setAlphaTest(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection"); - if (search != mat.iprops.end()) - flags.setSamusReflection(search->second != 0); - - search = mat.iprops.find("retro_depth_write"); - if (search != mat.iprops.end()) - flags.setDepthWrite(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_persp"); - if (search != mat.iprops.end()) - flags.setSamusReflectionSurfaceEye(search->second != 0); - - search = mat.iprops.find("retro_shadow_occluder"); - if (search != mat.iprops.end()) - flags.setShadowOccluderMesh(search->second != 0); - - search = mat.iprops.find("retro_samus_reflection_indirect"); - if (search != mat.iprops.end()) - flags.setSamusReflectionIndirectTexture(search->second != 0); - - search = mat.iprops.find("retro_lightmapped"); - if (search != mat.iprops.end()) - flags.setLightmap(search->second != 0); - - XXH64_state_t xxh; - XXH64_reset(&xxh, 0); - shaderType = mat.shaderType; - XXH64_update(&xxh, &shaderType, sizeof(shaderType)); - chunkCount = 0; - chunks.reserve(mat.chunks.size()); - for (const auto& chunk : mat.chunks) { - chunk.visit([this, &xxh](const auto& var) { - using T = std::decay_t; - chunks.push_back(Chunk::Build(T::variant_type(), var)); - var.hash(&xxh); - ++chunkCount; - }); - } - blendMode = mat.blendMode; - XXH64_update(&xxh, &blendMode, sizeof(blendMode)); - int hashFlags = 0; - if (flags.samusReflection()) - hashFlags |= 1; - if (flags.samusReflectionIndirectTexture()) - hashFlags |= 2; - if (flags.depthWrite()) - hashFlags |= 4; - if (flags.alphaTest()) - hashFlags |= 8; - XXH64_update(&xxh, &hashFlags, sizeof(hashFlags)); - hash = XXH64_digest(&xxh); -} - -MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction, const std::vector& gameArgs) { - if (gameFunction == "RetroUVMode0NodeN") - mode = Mode::MvInvNoTranslation; - else if (gameFunction == "RetroUVMode1NodeN") - mode = Mode::MvInv; - else if (gameFunction == "RetroUVMode2Node") { - mode = Mode::Scroll; - if (gameArgs.size() < 2) - Log.report(logvisor::Fatal, FMT_STRING("Mode2 UV anim requires 2 vector arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[0].simd[1]; - vals[2] = gameArgs[1].simd[0]; - vals[3] = gameArgs[1].simd[1]; - } else if (gameFunction == "RetroUVMode3Node") { - mode = Mode::Rotation; - if (gameArgs.size() < 2) - Log.report(logvisor::Fatal, FMT_STRING("Mode3 UV anim requires 2 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - } else if (gameFunction == "RetroUVMode4Node") { - mode = Mode::HStrip; - if (gameArgs.size() < 4) - Log.report(logvisor::Fatal, FMT_STRING("Mode4 UV anim requires 4 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - vals[2] = gameArgs[2].simd[0]; - vals[3] = gameArgs[3].simd[0]; - } else if (gameFunction == "RetroUVMode5Node") { - mode = Mode::VStrip; - if (gameArgs.size() < 4) - Log.report(logvisor::Fatal, FMT_STRING("Mode5 UV anim requires 4 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - vals[2] = gameArgs[2].simd[0]; - vals[3] = gameArgs[3].simd[0]; - } else if (gameFunction == "RetroUVMode6NodeN") - mode = Mode::Model; - else if (gameFunction == "RetroUVMode7NodeN") { - mode = Mode::CylinderEnvironment; - if (gameArgs.size() < 2) - Log.report(logvisor::Fatal, FMT_STRING("Mode7 UV anim requires 2 arguments")); - vals[0] = gameArgs[0].simd[0]; - vals[1] = gameArgs[1].simd[0]; - } else - Log.report(logvisor::Fatal, FMT_STRING("unsupported UV anim '{}'"), gameFunction); -} - -template -void MaterialSet::Material::UVAnimation::Enumerate(typename Op::StreamT& s) { - Do({}, mode, s); - switch (mode) { - case Mode::MvInvNoTranslation: - case Mode::MvInv: - case Mode::Model: - break; - case Mode::Scroll: - case Mode::HStrip: - case Mode::VStrip: - for (int i = 0; i < 4; ++i) - Do({}, vals[i], s); - break; - case Mode::Rotation: - case Mode::CylinderEnvironment: - for (int i = 0; i < 2; ++i) - Do({}, vals[i], s); - break; - case Mode::Eight: - for (int i = 0; i < 9; ++i) - Do({}, vals[i], s); - break; - } -} - -AT_SPECIALIZE_DNA(MaterialSet::Material::UVAnimation) - -template -void HMDLMaterialSet::Material::PASS::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"type"}, type, s); - Do(athena::io::PropId{"texId"}, texId, s); - Do(athena::io::PropId{"source"}, source, s); - Do(athena::io::PropId{"uvAnimType"}, uvAnimType, s); - size_t uvParmCount = uvAnimParamsCount(); - for (size_t i = 0; i < uvParmCount; ++i) - Do({}, uvAnimParms[i], s); - Do(athena::io::PropId{"alpha"}, alpha, s); -} - -AT_SPECIALIZE_DNA(HMDLMaterialSet::Material::PASS) - -std::string_view HMDLMaterialSet::Material::PASS::DNAType() { - return "DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS"sv; -} - -} // namespace DataSpec::DNAMP1 - -namespace DataSpec::DNAMP2 { - -void MaterialSet::ConstructMaterial(Stream& out, const MaterialSet::Material& material, unsigned groupIdx, - unsigned matIdx) { - DataSpec::DNAMP1::_ConstructMaterial(out, material, groupIdx, matIdx); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP1/CMDLMaterials.hpp b/DataSpec/DNAMP1/CMDLMaterials.hpp deleted file mode 100644 index 355176df8..000000000 --- a/DataSpec/DNAMP1/CMDLMaterials.hpp +++ /dev/null @@ -1,640 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/GX.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "DNAMP1.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -struct MaterialSet : BigDNA { - static constexpr bool OneSection() { return false; } - - AT_DECL_DNA - struct MaterialSetHead : BigDNA { - AT_DECL_DNA - Value textureCount = 0; - Vector textureIDs; - Value materialCount = 0; - Vector materialEndOffs; - - void addTexture(const UniqueID32& id) { - textureIDs.push_back(id); - ++textureCount; - } - void addMaterialEndOff(atUint32 off) { - materialEndOffs.push_back(off); - ++materialCount; - } - - template - void ensureTexturesExtracted(PAKRouter& pakRouter) const { - for (const auto& id : textureIDs) { - const nod::Node* node; - const PAK::Entry* texEntry = pakRouter.lookupEntry(id, &node); - if (!texEntry) - continue; - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - } - } - } head; - - struct Material : BigDNA { - AT_DECL_DNA - struct Flags : BigDNA { - AT_DECL_DNA - Value flags = 0; - bool konstValuesEnabled() const { return (flags & 0x8) != 0; } - void setKonstValuesEnabled(bool enabled) { - flags &= ~0x8; - flags |= atUint32(enabled) << 3; - } - bool depthSorting() const { return (flags & 0x10) != 0; } - void setDepthSorting(bool enabled) { - flags &= ~0x10; - flags |= atUint32(enabled) << 4; - } - bool alphaTest() const { return (flags & 0x20) != 0; } - void setAlphaTest(bool enabled) { - flags &= ~0x20; - flags |= atUint32(enabled) << 5; - } - bool samusReflection() const { return (flags & 0x40) != 0; } - void setSamusReflection(bool enabled) { - flags &= ~0x40; - flags |= atUint32(enabled) << 6; - } - bool depthWrite() const { return (flags & 0x80) != 0; } - void setDepthWrite(bool enabled) { - flags &= ~0x80; - flags |= atUint32(enabled) << 7; - } - bool samusReflectionSurfaceEye() const { return (flags & 0x100) != 0; } - void setSamusReflectionSurfaceEye(bool enabled) { - flags &= ~0x100; - flags |= atUint32(enabled) << 8; - } - bool shadowOccluderMesh() const { return (flags & 0x200) != 0; } - void setShadowOccluderMesh(bool enabled) { - flags &= ~0x200; - flags |= atUint32(enabled) << 9; - } - bool samusReflectionIndirectTexture() const { return (flags & 0x400) != 0; } - void setSamusReflectionIndirectTexture(bool enabled) { - flags &= ~0x400; - flags |= atUint32(enabled) << 10; - } - bool lightmap() const { return (flags & 0x800) != 0; } - void setLightmap(bool enabled) { - flags &= ~0x800; - flags |= atUint32(enabled) << 11; - } - bool lightmapUVArray() const { return (flags & 0x2000) != 0; } - void setLightmapUVArray(bool enabled) { - flags &= ~0x2000; - flags |= atUint32(enabled) << 13; - } - atUint16 textureSlots() const { return (flags >> 16) != 0; } - void setTextureSlots(atUint16 texslots) { - flags &= ~0xffff0000; - flags |= atUint32(texslots) << 16; - } - } flags; - const Flags& getFlags() const { return flags; } - - Value textureCount = 0; - Vector textureIdxs; - struct VAFlags : BigDNA { - AT_DECL_DNA - Value vaFlags = 0; - GX::AttrType position() const { return GX::AttrType(vaFlags & 0x3); } - void setPosition(GX::AttrType val) { - vaFlags &= ~0x3; - vaFlags |= atUint32(val); - } - GX::AttrType normal() const { return GX::AttrType(vaFlags >> 2 & 0x3); } - void setNormal(GX::AttrType val) { - vaFlags &= ~0xC; - vaFlags |= atUint32(val) << 2; - } - GX::AttrType color0() const { return GX::AttrType(vaFlags >> 4 & 0x3); } - void setColor0(GX::AttrType val) { - vaFlags &= ~0x30; - vaFlags |= atUint32(val) << 4; - } - GX::AttrType color1() const { return GX::AttrType(vaFlags >> 6 & 0x3); } - void setColor1(GX::AttrType val) { - vaFlags &= ~0xC0; - vaFlags |= atUint32(val) << 6; - } - GX::AttrType tex0() const { return GX::AttrType(vaFlags >> 8 & 0x3); } - void setTex0(GX::AttrType val) { - vaFlags &= ~0x300; - vaFlags |= atUint32(val) << 8; - } - GX::AttrType tex1() const { return GX::AttrType(vaFlags >> 10 & 0x3); } - void setTex1(GX::AttrType val) { - vaFlags &= ~0xC00; - vaFlags |= atUint32(val) << 10; - } - GX::AttrType tex2() const { return GX::AttrType(vaFlags >> 12 & 0x3); } - void setTex2(GX::AttrType val) { - vaFlags &= ~0x3000; - vaFlags |= atUint32(val) << 12; - } - GX::AttrType tex3() const { return GX::AttrType(vaFlags >> 14 & 0x3); } - void setTex3(GX::AttrType val) { - vaFlags &= ~0xC000; - vaFlags |= atUint32(val) << 14; - } - GX::AttrType tex4() const { return GX::AttrType(vaFlags >> 16 & 0x3); } - void setTex4(GX::AttrType val) { - vaFlags &= ~0x30000; - vaFlags |= atUint32(val) << 16; - } - GX::AttrType tex5() const { return GX::AttrType(vaFlags >> 18 & 0x3); } - void setTex5(GX::AttrType val) { - vaFlags &= ~0xC0000; - vaFlags |= atUint32(val) << 18; - } - GX::AttrType tex6() const { return GX::AttrType(vaFlags >> 20 & 0x3); } - void setTex6(GX::AttrType val) { - vaFlags &= ~0x300000; - vaFlags |= atUint32(val) << 20; - } - GX::AttrType pnMatIdx() const { return GX::AttrType(vaFlags >> 24 & 0x1); } - void setPnMatIdx(GX::AttrType val) { - vaFlags &= ~0x1000000; - vaFlags |= atUint32(val & 0x1) << 24; - } - GX::AttrType tex0MatIdx() const { return GX::AttrType(vaFlags >> 25 & 0x1); } - void setTex0MatIdx(GX::AttrType val) { - vaFlags &= ~0x2000000; - vaFlags |= atUint32(val & 0x1) << 25; - } - GX::AttrType tex1MatIdx() const { return GX::AttrType(vaFlags >> 26 & 0x1); } - void setTex1MatIdx(GX::AttrType val) { - vaFlags &= ~0x4000000; - vaFlags |= atUint32(val & 0x1) << 26; - } - GX::AttrType tex2MatIdx() const { return GX::AttrType(vaFlags >> 27 & 0x1); } - void setTex2MatIdx(GX::AttrType val) { - vaFlags &= ~0x8000000; - vaFlags |= atUint32(val & 0x1) << 27; - } - GX::AttrType tex3MatIdx() const { return GX::AttrType(vaFlags >> 28 & 0x1); } - void setTex3MatIdx(GX::AttrType val) { - vaFlags &= ~0x10000000; - vaFlags |= atUint32(val & 0x1) << 28; - } - GX::AttrType tex4MatIdx() const { return GX::AttrType(vaFlags >> 29 & 0x1); } - void setTex4MatIdx(GX::AttrType val) { - vaFlags &= ~0x20000000; - vaFlags |= atUint32(val & 0x1) << 29; - } - GX::AttrType tex5MatIdx() const { return GX::AttrType(vaFlags >> 30 & 0x1); } - void setTex5MatIdx(GX::AttrType val) { - vaFlags &= ~0x40000000; - vaFlags |= atUint32(val & 0x1) << 30; - } - GX::AttrType tex6MatIdx() const { return GX::AttrType(vaFlags >> 31 & 0x1); } - void setTex6MatIdx(GX::AttrType val) { - vaFlags &= ~0x80000000; - vaFlags |= atUint32(val & 0x1) << 31; - } - - size_t vertDLSize() const { - static size_t ATTR_SZ[] = {0, 1, 1, 2}; - size_t ret = 0; - ret += ATTR_SZ[position()]; - ret += ATTR_SZ[normal()]; - ret += ATTR_SZ[color0()]; - ret += ATTR_SZ[color1()]; - ret += ATTR_SZ[tex0()]; - ret += ATTR_SZ[tex1()]; - ret += ATTR_SZ[tex2()]; - ret += ATTR_SZ[tex3()]; - ret += ATTR_SZ[tex4()]; - ret += ATTR_SZ[tex5()]; - ret += ATTR_SZ[tex6()]; - ret += ATTR_SZ[pnMatIdx()]; - ret += ATTR_SZ[tex0MatIdx()]; - ret += ATTR_SZ[tex1MatIdx()]; - ret += ATTR_SZ[tex2MatIdx()]; - ret += ATTR_SZ[tex3MatIdx()]; - ret += ATTR_SZ[tex4MatIdx()]; - ret += ATTR_SZ[tex5MatIdx()]; - ret += ATTR_SZ[tex6MatIdx()]; - return ret; - } - } vaFlags; - const VAFlags& getVAFlags() const { return vaFlags; } - Value uniqueIdx; - - Vector konstCount; - Vector konstColors; - - using BlendFactor = GX::BlendFactor; - Value blendDstFac; - Value blendSrcFac; - Vector indTexSlot; - - Value colorChannelCount = 0; - struct ColorChannel : BigDNA { - AT_DECL_DNA - Value flags = 0; - bool lighting() const { return (flags & 0x1) != 0; } - void setLighting(bool enabled) { - flags &= ~0x1; - flags |= atUint32(enabled); - } - bool useAmbient() const { return (flags & 0x2) != 0; } - void setUseAmbient(bool enabled) { - flags &= ~0x2; - flags |= atUint32(enabled) << 1; - } - bool useMaterial() const { return (flags & 0x4) != 0; } - void setUseMaterial(bool enabled) { - flags &= ~0x4; - flags |= atUint32(enabled) << 2; - } - atUint8 lightmask() const { return atUint8(flags >> 3 & 0xff); } - void setLightmask(atUint8 mask) { - flags &= ~0x7f8; - flags |= atUint32(mask) << 3; - } - GX::DiffuseFn diffuseFn() const { return GX::DiffuseFn(flags >> 11 & 0x3); } - void setDiffuseFn(GX::DiffuseFn fn) { - flags &= ~0x1800; - flags |= atUint32(fn) << 11; - } - GX::AttnFn attenuationFn() const { return GX::AttnFn(flags >> 13 & 0x3); } - void setAttenuationFn(GX::AttnFn fn) { - flags &= ~0x6000; - flags |= atUint32(fn) << 13; - } - }; - Vector colorChannels; - - Value tevStageCount = 0; - struct TEVStage : BigDNA { - AT_DECL_DNA - Value ciFlags = 0; - Value aiFlags = 0; - Value ccFlags = 0; - Value acFlags = 0; - Value pad = 0; - Value kaInput = 0; - Value kcInput = 0; - Value rascInput = 0; - - GX::TevColorArg colorInA() const { return GX::TevColorArg(ciFlags & 0xf); } - void setColorInA(GX::TevColorArg val) { - ciFlags &= ~0x1f; - ciFlags |= atUint32(val); - } - GX::TevColorArg colorInB() const { return GX::TevColorArg(ciFlags >> 5 & 0xf); } - void setColorInB(GX::TevColorArg val) { - ciFlags &= ~0x3e0; - ciFlags |= atUint32(val) << 5; - } - GX::TevColorArg colorInC() const { return GX::TevColorArg(ciFlags >> 10 & 0xf); } - void setColorInC(GX::TevColorArg val) { - ciFlags &= ~0x7c00; - ciFlags |= atUint32(val) << 10; - } - GX::TevColorArg colorInD() const { return GX::TevColorArg(ciFlags >> 15 & 0xf); } - void setColorInD(GX::TevColorArg val) { - ciFlags &= ~0xf8000; - ciFlags |= atUint32(val) << 15; - } - - GX::TevAlphaArg alphaInA() const { return GX::TevAlphaArg(aiFlags & 0x7); } - void setAlphaInA(GX::TevAlphaArg val) { - aiFlags &= ~0x1f; - aiFlags |= atUint32(val); - } - GX::TevAlphaArg alphaInB() const { return GX::TevAlphaArg(aiFlags >> 5 & 0x7); } - void setAlphaInB(GX::TevAlphaArg val) { - aiFlags &= ~0x3e0; - aiFlags |= atUint32(val) << 5; - } - GX::TevAlphaArg alphaInC() const { return GX::TevAlphaArg(aiFlags >> 10 & 0x7); } - void setAlphaInC(GX::TevAlphaArg val) { - aiFlags &= ~0x7c00; - aiFlags |= atUint32(val) << 10; - } - GX::TevAlphaArg alphaInD() const { return GX::TevAlphaArg(aiFlags >> 15 & 0x7); } - void setAlphaInD(GX::TevAlphaArg val) { - aiFlags &= ~0xf8000; - aiFlags |= atUint32(val) << 15; - } - - GX::TevOp colorOp() const { return GX::TevOp(ccFlags & 0xf); } - void setColorOp(GX::TevOp val) { - ccFlags &= ~0x1; - ccFlags |= atUint32(val); - } - GX::TevBias colorOpBias() const { return GX::TevBias(ccFlags >> 4 & 0x3); } - void setColorOpBias(GX::TevBias val) { - ccFlags &= ~0x30; - ccFlags |= atUint32(val) << 4; - } - GX::TevScale colorOpScale() const { return GX::TevScale(ccFlags >> 6 & 0x3); } - void setColorOpScale(GX::TevScale val) { - ccFlags &= ~0xc0; - ccFlags |= atUint32(val) << 6; - } - bool colorOpClamp() const { return ccFlags >> 8 & 0x1; } - void setColorOpClamp(bool val) { - ccFlags &= ~0x100; - ccFlags |= atUint32(val) << 8; - } - GX::TevRegID colorOpOutReg() const { return GX::TevRegID(ccFlags >> 9 & 0x3); } - void setColorOpOutReg(GX::TevRegID val) { - ccFlags &= ~0x600; - ccFlags |= atUint32(val) << 9; - } - - GX::TevOp alphaOp() const { return GX::TevOp(acFlags & 0xf); } - void setAlphaOp(GX::TevOp val) { - acFlags &= ~0x1; - acFlags |= atUint32(val); - } - GX::TevBias alphaOpBias() const { return GX::TevBias(acFlags >> 4 & 0x3); } - void setAlphaOpBias(GX::TevBias val) { - acFlags &= ~0x30; - acFlags |= atUint32(val) << 4; - } - GX::TevScale alphaOpScale() const { return GX::TevScale(acFlags >> 6 & 0x3); } - void setAlphaOpScale(GX::TevScale val) { - acFlags &= ~0xc0; - acFlags |= atUint32(val) << 6; - } - bool alphaOpClamp() const { return acFlags >> 8 & 0x1; } - void setAlphaOpClamp(bool val) { - acFlags &= ~0x100; - acFlags |= atUint32(val) << 8; - } - GX::TevRegID alphaOpOutReg() const { return GX::TevRegID(acFlags >> 9 & 0x3); } - void setAlphaOpOutReg(GX::TevRegID val) { - acFlags &= ~0x600; - acFlags |= atUint32(val) << 9; - } - - GX::TevKColorSel kColorIn() const { return GX::TevKColorSel(kcInput); } - void setKColorIn(GX::TevKColorSel val) { kcInput = val; } - GX::TevKAlphaSel kAlphaIn() const { return GX::TevKAlphaSel(kaInput); } - void setKAlphaIn(GX::TevKAlphaSel val) { kaInput = val; } - - GX::ChannelID rasIn() const { return GX::ChannelID(rascInput); } - void setRASIn(GX::ChannelID id) { rascInput = id; } - }; - Vector tevStages; - struct TEVStageTexInfo : BigDNA { - AT_DECL_DNA - Value pad = 0; - Value texSlot = 0xff; - Value tcgSlot = 0xff; - }; - Vector tevStageTexInfo; - - Value tcgCount = 0; - struct TexCoordGen : BigDNA { - AT_DECL_DNA - Value flags = 0; - - GX::TexGenType type() const { return GX::TexGenType(flags & 0xf); } - void setType(GX::TexGenType val) { - flags &= ~0xf; - flags |= atUint32(val); - } - GX::TexGenSrc source() const { return GX::TexGenSrc(flags >> 4 & 0x1f); } - void setSource(GX::TexGenSrc val) { - flags &= ~0x1f0; - flags |= atUint32(val) << 4; - } - GX::TexMtx mtx() const { return GX::TexMtx((flags >> 9 & 0x1f) + 30); } - void setMtx(GX::TexMtx val) { - flags &= ~0x3e00; - flags |= (atUint32(val) - 30) << 9; - } - bool normalize() const { return flags >> 14 & 0x1; } - void setNormalize(bool val) { - flags &= ~0x4000; - flags |= atUint32(val) << 14; - } - GX::PTTexMtx postMtx() const { return GX::PTTexMtx((flags >> 15 & 0x3f) + 64); } - void setPostMtx(GX::PTTexMtx val) { - flags &= ~0x1f8000; - flags |= (atUint32(val) - 64) << 15; - } - }; - Vector tcgs; - - Value uvAnimsSize = 4; - Value uvAnimsCount = 0; - struct UVAnimation : BigDNA { - AT_DECL_EXPLICIT_DNA - enum class Mode { - MvInvNoTranslation, - MvInv, - Scroll, - Rotation, - HStrip, - VStrip, - Model, - CylinderEnvironment, - Eight - } mode; - float vals[9]; - - UVAnimation() = default; - UVAnimation(const std::string& gameFunction, const std::vector& gameArgs); - }; - Vector uvAnims; - - static void AddTexture(hecl::blender::PyOutStream& out, GX::TexGenSrc type, int mtxIdx, uint32_t texIdx, - bool diffuse); - static void AddTextureAnim(hecl::blender::PyOutStream& out, MaterialSet::Material::UVAnimation::Mode type, - unsigned idx, const float* vals); - static void AddKcolor(hecl::blender::PyOutStream& out, const GX::Color& col, unsigned idx); - static void AddDynamicColor(hecl::blender::PyOutStream& out, unsigned idx); - static void AddDynamicAlpha(hecl::blender::PyOutStream& out, unsigned idx); - - Material() = default; - Material(const hecl::blender::Material& material, std::vector& texPathsOut, int colorCount, - bool lightmapUVs, bool matrixSkinning); - }; - Vector materials; - - static void RegisterMaterialProps(hecl::blender::PyOutStream& out); - static void ConstructMaterial(hecl::blender::PyOutStream& out, const MaterialSet::Material& material, - unsigned groupIdx, unsigned matIdx); - - void readToBlender(hecl::blender::PyOutStream& os, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx) { - DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx); - } - - template - void nameTextures(PAKRouter& pakRouter, const char* prefix, int setIdx) const { - int matIdx = 0; - for (const Material& mat : materials) { - int stageIdx = 0; - for (const Material::TEVStage& stage : mat.tevStages) { - (void)stage; - const Material::TEVStageTexInfo& texInfo = mat.tevStageTexInfo[stageIdx]; - if (texInfo.texSlot == 0xff) { - ++stageIdx; - continue; - } - const nod::Node* node; - typename PAKRouter::EntryType* texEntry = (typename PAKRouter::EntryType*)pakRouter.lookupEntry( - head.textureIDs[mat.textureIdxs[texInfo.texSlot]], &node); - if (texEntry->name.size()) { - if (texEntry->name.size() < 5 || texEntry->name.compare(0, 5, "mult_")) - texEntry->name = "mult_" + texEntry->name; - ++stageIdx; - continue; - } - if (setIdx < 0) - texEntry->name = fmt::format(FMT_STRING("{}_{}_{}"), prefix, matIdx, stageIdx); - else - texEntry->name = fmt::format(FMT_STRING("{}_{}_{}_{}"), prefix, setIdx, matIdx, stageIdx); - - if (mat.flags.lightmap() && stageIdx == 0) { - texEntry->name += "light"; - ++stageIdx; - continue; - } - - ++stageIdx; - } - ++matIdx; - } - } - - void ensureTexturesExtracted(PAKRouter& pakRouter) const { head.ensureTexturesExtracted(pakRouter); } -}; - -struct HMDLMaterialSet : BigDNA { - static constexpr bool OneSection() { return false; } - - AT_DECL_DNA - Value materialCount = 0; - Vector materialEndOffs; - - struct Material : BigDNA { - AT_DECL_DNA - MaterialSet::Material::Flags flags; - - using BlendMaterial = hecl::blender::Material; - - struct PASS : hecl::TypedRecordBigDNA { - AT_DECL_EXPLICIT_DNA - Value type; - UniqueID32 texId; - Value source; - Value uvAnimType; - Value uvAnimParms[9] = {}; - Value alpha; - PASS() = default; - explicit PASS(const BlendMaterial::PASS& pass) - : type(pass.type), texId(pass.tex), source(pass.source), uvAnimType(pass.uvAnimType), alpha(pass.alpha) { - std::copy(pass.uvAnimParms.begin(), pass.uvAnimParms.end(), std::begin(uvAnimParms)); - } - bool shouldNormalizeUv() const { - switch (uvAnimType) { - case BlendMaterial::UVAnimType::MvInvNoTranslation: - case BlendMaterial::UVAnimType::MvInv: - case BlendMaterial::UVAnimType::Model: - case BlendMaterial::UVAnimType::CylinderEnvironment: - return true; - default: - return false; - } - } - size_t uvAnimParamsCount() const { - switch (uvAnimType) { - default: - return 0; - case BlendMaterial::UVAnimType::Scroll: - case BlendMaterial::UVAnimType::HStrip: - case BlendMaterial::UVAnimType::VStrip: - return 4; - case BlendMaterial::UVAnimType::Rotation: - case BlendMaterial::UVAnimType::CylinderEnvironment: - return 2; - case BlendMaterial::UVAnimType::Eight: - return 9; - } - } - }; - struct CLR : hecl::TypedRecordBigDNA { - AT_DECL_DNA - Value type; - Value color; - CLR() = default; - explicit CLR(const BlendMaterial::CLR& clr) : type(clr.type), color(clr.color.val) {} - }; - using Chunk = hecl::TypedVariantBigDNA; - - static unsigned TexMapIdx(BlendMaterial::PassType type) { - switch (type) { - case BlendMaterial::PassType::Lightmap: - return 0; - case BlendMaterial::PassType::Diffuse: - return 1; - case BlendMaterial::PassType::Emissive: - return 2; - case BlendMaterial::PassType::Specular: - return 3; - case BlendMaterial::PassType::ExtendedSpecular: - return 4; - case BlendMaterial::PassType::Reflection: - return 5; - case BlendMaterial::PassType::Alpha: - return 6; - case BlendMaterial::PassType::IndirectTex: - return 7; - default: - assert(false && "Unknown pass type"); - return 0; - } - } - - Value hash; - Value shaderType; - Value chunkCount; - Vector chunks; - Value blendMode = BlendMaterial::BlendMode::Opaque; - - std::pair blendFactors() const { - switch (blendMode) { - case BlendMaterial::BlendMode::Opaque: - default: - return {hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero}; - case BlendMaterial::BlendMode::Alpha: - return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha}; - case BlendMaterial::BlendMode::Additive: - return {hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One}; - } - } - - Material() = default; - Material(const hecl::blender::Material& mat); - }; - Vector materials; -}; - -} // namespace DataSpec::DNAMP1 - -AT_SPECIALIZE_TYPED_VARIANT_BIGDNA(DataSpec::DNAMP1::HMDLMaterialSet::Material::PASS, - DataSpec::DNAMP1::HMDLMaterialSet::Material::CLR) diff --git a/DataSpec/DNAMP1/CMakeLists.txt b/DataSpec/DNAMP1/CMakeLists.txt deleted file mode 100644 index 4b16eaaca..000000000 --- a/DataSpec/DNAMP1/CMakeLists.txt +++ /dev/null @@ -1,69 +0,0 @@ -include(DNAMP1/ScriptObjects/CMakeLists.txt) -include(DNAMP1/SFX/CMakeLists.txt) - -make_dnalist(PAK - MLVL - AGSC - CSNG - AFSM - ANCS - ANIM - CINF - CSKR - EVNT - CMDLMaterials - MREA - DeafBabe - SCAN - FRME - SAVW - HINT - MazeSeeds - SnowForces - DCLN - Tweaks/CTweakGame - Tweaks/CTweakParticle - Tweaks/CTweakPlayer - Tweaks/CTweakPlayerControl - Tweaks/CTweakPlayerGun - Tweaks/CTweakGunRes - Tweaks/CTweakPlayerRes - Tweaks/CTweakGui - Tweaks/CTweakSlideShow - Tweaks/CTweakCameraBob - Tweaks/CTweakTargeting - Tweaks/CTweakAutoMapper - Tweaks/CTweakBall - Tweaks/CTweakGuiColors) - -set(DNAMP1_SOURCES - DNAMP1.hpp DNAMP1.cpp - AFSM.cpp - PAK.cpp - MLVL.cpp - STRG.hpp STRG.cpp - AGSC.cpp - CSNG.cpp - CSKR.cpp - ANCS.cpp - ANIM.cpp - CINF.cpp - EVNT.cpp - PATH.hpp - CMDL.hpp CMDL.cpp - CMDLMaterials.cpp - DCLN.cpp - MAPA.hpp - MAPU.hpp - MREA.cpp - SCLY.hpp SCLY.cpp - FRME.cpp - SCAN.cpp - DeafBabe.cpp - Tweaks/CTweakAutoMapper.cpp - Tweaks/CTweakPlayer.cpp - Tweaks/CTweakTargeting.cpp - Tweaks/CTweakBall.cpp - Tweaks/CTweakGame.cpp) - -dataspec_add_list(DNAMP1 DNAMP1_SOURCES) diff --git a/DataSpec/DNAMP1/CSKR.cpp b/DataSpec/DNAMP1/CSKR.cpp deleted file mode 100644 index 7c4083a11..000000000 --- a/DataSpec/DNAMP1/CSKR.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "CSKR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const { - atUint32 accum = 0; - for (const SkinningRule& rule : skinningRules) { - if (idx >= accum && idx < accum + rule.vertCount) - for (const SkinningRule::Weight& weight : rule.weights) - os.format(FMT_STRING("vert[dvert_lay][{}] = {}\n"), cinf.getBoneIdxFromId(weight.boneId), weight.weight); - accum += rule.vertCount; - } -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CSKR.hpp b/DataSpec/DNAMP1/CSKR.hpp deleted file mode 100644 index c31c9234a..000000000 --- a/DataSpec/DNAMP1/CSKR.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CINF.hpp" - -namespace DataSpec::DNAMP1 { - -struct CSKR : BigDNA { - AT_DECL_DNA - Value skinningRuleCount; - struct SkinningRule : BigDNA { - AT_DECL_DNA - Value weightCount; - struct Weight : BigDNA { - AT_DECL_DNA - Value boneId; - Value weight; - }; - Vector weights; - Value vertCount; - }; - Vector skinningRules; - - const atInt16* getMatrixBank(size_t) const { return nullptr; } - - void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CSNG.cpp b/DataSpec/DNAMP1/CSNG.cpp deleted file mode 100644 index 949003df0..000000000 --- a/DataSpec/DNAMP1/CSNG.cpp +++ /dev/null @@ -1,98 +0,0 @@ -#include "CSNG.hpp" -#include "amuse/SongConverter.hpp" - -namespace DataSpec::DNAMP1 { - -bool CSNG::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - hecl::ProjectPath midPath = outPath.getWithExtension(".mid", true); - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - - Header head; - head.read(rs); - - { - athena::io::YAMLDocWriter dw("CSNG"); - dw.writeUint32("midiSetupId", head.midiSetupId); - dw.writeUint32("songGroupId", head.songGroupId); - if (auto rec = dw.enterSubRecord("agscId")) - head.agscId.write(dw); - - athena::io::FileWriter w(yamlPath.getAbsolutePath()); - if (w.hasError()) - return false; - dw.finish(&w); - } - - { - auto sng = rs.readUBytes(head.sngLength); - int version; - bool isBig; - auto midi = amuse::SongConverter::SongToMIDI(sng.get(), version, isBig); - - athena::io::FileWriter w(midPath.getAbsolutePath()); - if (w.hasError()) - return false; - w.writeUBytes(midi.data(), midi.size()); - } - - /* Update !songs.yaml for Amuse editor */ - hecl::ProjectPath audGrp(outPath.getParentPath().getParentPath(), "AudioGrp"); - audGrp.makeDirChain(true); - hecl::ProjectPath songsPath(audGrp, "!songs.yaml"); - std::optional r; - if (songsPath.isFile()) - r.emplace(songsPath.getAbsolutePath()); - athena::io::YAMLDocWriter ydw("amuse::Songs", r ? &*r : nullptr); - r = std::nullopt; - ydw.writeString(fmt::format(FMT_STRING("{:04X}"), head.midiSetupId), - fmt::format(FMT_STRING("../MidiData/{}"), midPath.getLastComponent())); - athena::io::FileWriter w(songsPath.getAbsolutePath()); - ydw.finish(&w); - - return true; -} - -bool CSNG::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::ProjectPath midPath = inPath.getWithExtension(".mid", true); - hecl::ProjectPath yamlPath = inPath.getWithExtension(".yaml", true); - - std::vector sngData; - { - athena::io::FileReader midR(midPath.getAbsolutePath()); - if (midR.hasError()) - return false; - - uint32_t midLen = midR.length(); - std::vector midData; - midData.resize(midLen); - midR.readUBytesToBuf(midData.data(), midLen); - sngData = amuse::SongConverter::MIDIToSong(midData, 1, true); - } - - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - - { - athena::io::FileReader yamlR(yamlPath.getAbsolutePath()); - if (yamlR.hasError()) - return false; - athena::io::YAMLDocReader dr; - if (!dr.parse(&yamlR)) - return false; - - Header head; - head.midiSetupId = dr.readUint32("midiSetupId"); - head.songGroupId = dr.readUint32("songGroupId"); - if (auto rec = dr.enterSubRecord("agscId")) - head.agscId.read(dr); - head.sngLength = sngData.size(); - head.write(w); - } - - w.writeUBytes(sngData.data(), sngData.size()); - - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/CSNG.hpp b/DataSpec/DNAMP1/CSNG.hpp deleted file mode 100644 index da45efe47..000000000 --- a/DataSpec/DNAMP1/CSNG.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -class CSNG { - struct Header : BigDNA { - AT_DECL_DNA - Value magic = 0x2; - Value midiSetupId; - Value songGroupId; - UniqueID32 agscId; - Value sngLength; - }; - -public: - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DCLN.cpp b/DataSpec/DNAMP1/DCLN.cpp deleted file mode 100644 index 330ec144d..000000000 --- a/DataSpec/DNAMP1/DCLN.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "DCLN.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -#if DCLN_DUMP_OBB -void DCLN::Collision::Node::sendToBlender(hecl::blender::PyOutStream& os) const { - os.format( - "obj = bpy.data.objects.new('%s', None)\n" - "obj.empty_display_type = 'CUBE'\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "obj.rotation_mode = 'QUATERNION'\n" - "obj.location = mtxd[0]\n" - "obj.rotation_quaternion = mtxd[1]\n" - "obj.scale = (%f,%f,%f)\n", - isLeaf ? "leaf" : "branch", xf[0].simd[0], xf[0].simd[1], xf[0].simd[2], xf[0].simd[3], xf[1].simd[0], - xf[1].simd[1], xf[1].simd[2], xf[1].simd[3], xf[2].simd[0], xf[2].simd[1], xf[2].simd[2], xf[2].simd[3], - halfExtent.simd[0], halfExtent.simd[1], halfExtent.simd[2]); - if (isLeaf) - os << "obj.show_name = True\n"; - if (!isLeaf) { - left->sendToBlender(os); - right->sendToBlender(os); - } -} -#endif - -void DCLN::sendToBlender(hecl::blender::Connection& conn, std::string_view entryName) { - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "from mathutils import Vector, Matrix\n" - "\n" - "bpy.context.scene.name = '{}'\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n"), - entryName); - - DeafBabe::BlenderInit(os); - atInt32 idx = 0; - for (const Collision& col : collision) { - DeafBabeSendToBlender(os, col, true, idx++); -#if DCLN_DUMP_OBB - col.root.sendToBlender(os); -#endif - } - os.centerView(); - os.close(); -} - -bool DCLN::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - DCLN dcln; - dcln.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::ColMesh)) - return false; - - dcln.sendToBlender(conn, pakRouter.getBestEntryName(entry, false)); - return conn.saveBlend(); -} - -bool DCLN::Cook(const hecl::ProjectPath& outPath, const std::vector& meshes) { - DCLN dcln; - dcln.colCount = atUint32(meshes.size()); - for (const Mesh& mesh : meshes) { - dcln.collision.emplace_back(); - Collision& colOut = dcln.collision.back(); - DeafBabeBuildFromBlender(colOut, mesh); - colOut.root = std::move(*OBBTreeBuilder::buildCol(mesh)); - colOut.memSize = atUint32(colOut.root.getMemoryUsage()); - } - -#if DCLN_DUMP_OBB - hecl::blender::Connection& conn = hecl::blender::SharedBlenderToken.getBlenderConnection(); - conn.createBlend(outPath.getWithExtension(".blend"), hecl::blender::BlendType::ColMesh); - dcln.sendToBlender(conn, "BLAH"); - conn.saveBlend(); -#endif - - athena::io::FileWriter w(outPath.getAbsolutePath()); - dcln.write(w); - int64_t rem = w.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - w.writeUByte(0xff); - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DCLN.hpp b/DataSpec/DNAMP1/DCLN.hpp deleted file mode 100644 index 380de3e44..000000000 --- a/DataSpec/DNAMP1/DCLN.hpp +++ /dev/null @@ -1,120 +0,0 @@ -#pragma once - -#include "athena/Types.hpp" -#include "DataSpec/DNACommon/DeafBabe.hpp" -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/OBBTreeBuilder.hpp" -#include "DNAMP1.hpp" -#include "DeafBabe.hpp" - -#define DCLN_DUMP_OBB 0 - -namespace DataSpec::DNAMP1 { - -struct DCLN : BigDNA { - using Mesh = hecl::blender::ColMesh; - - AT_DECL_DNA - Value colCount; - struct Collision : BigDNA { - using Material = DeafBabe::Material; - using Edge = DeafBabe::Edge; - using Triangle = DeafBabe::Triangle; - - AT_DECL_DNA - Value magic; - Value version; - Value memSize; - Value materialCount; - Vector materials; - Value vertMatsCount; - Vector vertMats; - Value edgeMatsCount; - Vector edgeMats; - Value triMatsCount; - Vector triMats; - Value edgeVertsCount; - Vector edgeVertConnections; - Value triangleEdgesCount; - Vector triangleEdgeConnections; - Value vertCount; - Vector verts; - - struct Node : BigDNA { - AT_DECL_EXPLICIT_DNA - - struct LeafData : BigDNA { - AT_DECL_DNA - Value triangleIndexCount; - Vector triangleIndices; - size_t getMemoryUsage() const { return (((triangleIndices.size() * 2) + 16) + 3) & ~3; } - }; - - Value xf[3]; - Value halfExtent; - Value isLeaf; - std::unique_ptr leafData; - std::unique_ptr left; - std::unique_ptr right; - - size_t getMemoryUsage() const { - size_t ret = 80; - if (isLeaf) - ret += leafData->getMemoryUsage(); - else { - ret += left->getMemoryUsage(); - ret += right->getMemoryUsage(); - } - - return (ret + 3) & ~3; - } - -#if DCLN_DUMP_OBB - void sendToBlender(hecl::blender::PyOutStream& os) const; -#endif - }; - Node root; - size_t getMemoryUsage() const { return root.getMemoryUsage(); } - - /* Dummy MP2 member */ - void insertNoClimb(hecl::blender::PyOutStream&) const {} - }; - - Vector collision; - - void sendToBlender(hecl::blender::Connection& conn, std::string_view entryName); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const std::vector& meshes); -}; - -template -void DCLN::Collision::Node::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"xf[0]"}, xf[0], s); - Do(athena::io::PropId{"xf[1]"}, xf[1], s); - Do(athena::io::PropId{"xf[2]"}, xf[2], s); - Do(athena::io::PropId{"halfExtent"}, halfExtent, s); - Do(athena::io::PropId{"isLeaf"}, isLeaf, s); - if (isLeaf) { - if (!leafData) { - leafData = std::make_unique(); - } - Do(athena::io::PropId{"leafData"}, *leafData, s); - } else { - if (!left) { - left = std::make_unique(); - } - Do(athena::io::PropId{"left"}, *left, s); - if (!right) { - right = std::make_unique(); - } - Do(athena::io::PropId{"right"}, *right, s); - } -} - -AT_SPECIALIZE_DNA(DCLN::Collision::Node) - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DNAMP1.cpp b/DataSpec/DNAMP1/DNAMP1.cpp deleted file mode 100644 index aeda873f6..000000000 --- a/DataSpec/DNAMP1/DNAMP1.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include - -#define NOD_ATHENA 1 -#include "DNAMP1.hpp" -#include "STRG.hpp" -#include "SCAN.hpp" -#include "MLVL.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/PART.hpp" -#include "DataSpec/DNACommon/ELSC.hpp" -#include "DataSpec/DNACommon/SWHC.hpp" -#include "DataSpec/DNACommon/CRSC.hpp" -#include "DataSpec/DNACommon/WPSC.hpp" -#include "DataSpec/DNACommon/DPSC.hpp" -#include "DataSpec/DNACommon/FONT.hpp" -#include "DataSpec/DNACommon/DGRP.hpp" -#include "DataSpec/DNACommon/ATBL.hpp" -#include "HINT.hpp" -#include "CMDL.hpp" -#include "AFSM.hpp" -#include "SAVW.hpp" -#include "ANCS.hpp" -#include "MREA.hpp" -#include "MAPA.hpp" -#include "MAPU.hpp" -#include "FRME.hpp" -#include "AGSC.hpp" -#include "CSNG.hpp" -#include "DCLN.hpp" -#include "PATH.hpp" - -#include "DataSpec/DNACommon/Tweaks/TweakWriter.hpp" -#include "DataSpec/DNACommon/MetaforceVersionInfo.hpp" -#include "Tweaks/CTweakPlayerRes.hpp" -#include "Tweaks/CTweakGunRes.hpp" -#include "Tweaks/CTweakPlayer.hpp" -#include "Tweaks/CTweakCameraBob.hpp" -#include "Tweaks/CTweakSlideShow.hpp" -#include "Tweaks/CTweakGame.hpp" -#include "Tweaks/CTweakTargeting.hpp" -#include "Tweaks/CTweakAutoMapper.hpp" -#include "Tweaks/CTweakGui.hpp" -#include "Tweaks/CTweakPlayerControl.hpp" -#include "Tweaks/CTweakBall.hpp" -#include "Tweaks/CTweakParticle.hpp" -#include "Tweaks/CTweakGuiColors.hpp" -#include "Tweaks/CTweakPlayerGun.hpp" -#include "MazeSeeds.hpp" -#include "SnowForces.hpp" - -namespace DataSpec::DNAMP1 { -logvisor::Module Log("DataSpec::DNAMP1"); - -static bool GetNoShare(std::string_view name) { - std::string lowerName(name); - std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); - if (!lowerName.compare(0, 7, "metroid")) - return false; - return true; -} - -PAKBridge::PAKBridge(const nod::Node& node, bool doExtract) -: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) { - nod::AthenaPartReadStream rs(node.beginReadStream()); - m_pak.read(rs); - - /* Append Level String */ - for (auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MLVL')) { - m_levelId = entry.id; - PAKEntryReadStream rs = entry.beginReadStream(m_node); - MLVL mlvl; - mlvl.read(rs); - PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId); - if (nameEnt) { - nameEnt->name = entry.name + "_name"; - PAKEntryReadStream rs = nameEnt->beginReadStream(m_node); - STRG mlvlName; - mlvlName.read(rs); - if (m_levelString.size()) - m_levelString += ", "; - m_levelString += mlvlName.getUTF8(FOURCC('ENGL'), 0); - } - } - } -} - -static std::string LayerName(std::string_view name) { - std::string ret(name); - for (auto& ch : ret) - if (ch == '/' || ch == '\\') - ch = '-'; - return ret; -} - -void PAKBridge::build() { - /* First pass: build per-area/per-layer dependency map */ - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MLVL')) { - Level& level = m_levelDeps[entry.id]; - - MLVL mlvl; - { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - mlvl.read(rs); - } - std::string catalogueName; - std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName); - level.name = bestName; - level.areas.reserve(mlvl.areaCount); - unsigned layerIdx = 0; - - /* Make MAPW available to lookup MAPAs */ - PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap); - std::vector mapw; - if (worldMapEnt) { - worldMapEnt->name = entry.name + "_mapw"; - PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node); - rs.seek(8, athena::SeekOrigin::Current); - atUint32 areaCount = rs.readUint32Big(); - mapw.reserve(areaCount); - for (atUint32 i = 0; i < areaCount; ++i) - mapw.emplace_back(rs); - level.resources.insert(mlvl.worldMap); - } - - PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId); - if (savwEnt) { - savwEnt->name = entry.name + "_savw"; - level.resources.insert(mlvl.saveWorldId); - } - - PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId); - if (skyEnt) { - skyEnt->name = entry.name + "_skybox"; - level.resources.insert(mlvl.worldSkyboxId); - } - - /* Index areas */ - unsigned ai = 0; - for (const MLVL::Area& area : mlvl.areas) { - Level::Area& areaDeps = level.areas[area.areaMREAId]; - MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai]; - PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId); - if (areaNameEnt) { - STRG areaName; - { - PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node); - areaName.read(rs); - } - areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0); - areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); - } - if (areaDeps.name.empty()) { - std::string idStr = area.areaMREAId.toString(); - areaDeps.name = std::string("MREA_") + idStr; - } - std::string num = fmt::format(FMT_STRING("{:02d} "), ai); - areaDeps.name = num + areaDeps.name; - - std::string lowerName(areaDeps.name); - for (char& ch : lowerName) { - ch = tolower(ch); - if (ch == ' ') - ch = '_'; - } - if (areaNameEnt) - areaNameEnt->name = lowerName + "_name"; - PAK::Entry* areaEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaMREAId); - if (areaEnt) - areaEnt->name = lowerName; - - areaDeps.layers.reserve(area.depLayerCount - 1); - unsigned r = 0; - for (unsigned l = 1; l < area.depLayerCount; ++l) { - areaDeps.layers.emplace_back(); - Level::Area::Layer& layer = areaDeps.layers.back(); - layer.name = LayerName(mlvl.layerNames[layerIdx++]); - layer.active = layerFlags.flags >> (l - 1) & 0x1; - layer.name = hecl::StringUtils::TrimWhitespace(layer.name); - - num = fmt::format(FMT_STRING("{:02d} "), l - 1); - layer.name = num + layer.name; - - layer.resources.reserve(area.depLayers[l] - r); - for (; r < area.depLayers[l]; ++r) - layer.resources.emplace(area.deps[r].id); - } - areaDeps.resources.reserve(area.depCount - r + 2); - for (; r < area.depCount; ++r) - areaDeps.resources.emplace(area.deps[r].id); - areaDeps.resources.emplace(area.areaMREAId); - if (mapw.size() > ai) - areaDeps.resources.emplace(mapw[ai]); - ++ai; - } - } - } - - /* Second pass: cross-compare uniqueness */ - for (auto& [id, entry] : m_pak.m_entries) - entry.unique.checkEntry(*this, entry); -} - -void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('ANCS')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - ANCS ancs; - ancs.read(rs); - for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) { - charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskr] = - std::make_pair(entry.id, fmt::format(FMT_STRING("{}_{}.CSKR"), ci.name, ci.cskr)); - PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl); - PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr); - PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf); - if (cmdlEnt != nullptr && cskrEnt != nullptr && cinfEnt != nullptr) { - cmdlEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_model"), id, ci.name); - cskrEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_skin"), id, ci.name); - cinfEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_skel"), id, ci.name); - if (ci.cmdlIce.isValid() && ci.cskrIce.isValid()) { - charAssoc.m_cmdlRigs[ci.cmdlIce] = {ci.cskrIce, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskrIce] = - std::make_pair(entry.id, fmt::format(FMT_STRING("{}.ICE_{}.CSKR"), ci.name, ci.cskrIce)); - PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce); - PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce); - cmdlEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_icemodel"), id, ci.name); - cskrEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_iceskin"), id, ci.name); - } - } - } - std::map> animInfo; - ancs.getAnimationResInfo(&pakRouter, animInfo); - for (auto& [animIdx, animResInfo] : animInfo) { - PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(animResInfo.animId); - animEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}"), id, animResInfo.name); - charAssoc.m_cskrToCharacter[animResInfo.animId] = - std::make_pair(entry.id, fmt::format(FMT_STRING("{}_{}.ANIM"), animResInfo.name, animResInfo.animId)); - if (animResInfo.evntId.isValid()) { - PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(animResInfo.evntId); - evntEnt->name = fmt::format(FMT_STRING("ANCS_{}_{}_evnt"), id, animResInfo.name); - charAssoc.m_cskrToCharacter[animResInfo.evntId] = std::make_pair( - entry.id, fmt::format(FMT_STRING("{}_{}.evnt.yaml"), animResInfo.name, animResInfo.evntId)); - } - } - } else if (entry.type == FOURCC('MREA')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc); - } - } -} - -void PAKBridge::addPATHToMREA(PAKRouter& pakRouter, - std::unordered_map& pathToMrea) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MREA')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - UniqueID32 pathID = MREA::GetPATHId(rs); - if (pathID.isValid()) - pathToMrea[pathID] = id; - } - } -} - -static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; - -void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, - std::unordered_map& addTo, - std::unordered_map& pathOverrides) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MLVL')) { - MLVL mlvl; - { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - mlvl.read(rs); - } - hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry).getParentPath(); - - if (mlvl.worldNameId.isValid()) - pathOverrides[mlvl.worldNameId] = - hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId)); - - for (const MLVL::Area& area : mlvl.areas) { - { - /* Get PATH transform */ - const nod::Node* areaNode; - const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode); - PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode); - UniqueID32 pathId = MREA::GetPATHId(rs); - if (pathId.isValid()) - addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow) - .transposed(); - } - - hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); - if (area.areaNameId.isValid()) - pathOverrides[area.areaNameId] = - hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId)); - } - - if (mlvl.worldMap.isValid()) { - const nod::Node* mapNode; - const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); - if (mapEntry) { - PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); - u32 magic = rs.readUint32Big(); - if (magic == 0xDEADF00D) { - rs.readUint32Big(); - u32 count = rs.readUint32Big(); - for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) { - MLVL::Area& areaData = mlvl.areas[i]; - UniqueID32 mapaId; - mapaId.read(rs); - addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1], - areaData.transformMtx[2], BottomRow) - .transposed(); - } - } - } - } - } - } -} - -ResExtractor PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) { - switch (entry.type.toUint32()) { - case SBIG('STRG'): - return {STRG::Extract, {".yaml"}}; - case SBIG('SCAN'): - return {SCAN::Extract, {".yaml"}, 0, SCAN::Name}; - case SBIG('HINT'): - return {HINT::Extract, {".yaml"}}; - case SBIG('TXTR'): - return {TXTR::Extract, {".png"}}; - case SBIG('AFSM'): - return {AFSM::Extract, {".yaml"}}; - case SBIG('FRME'): - return {FRME::Extract, {".blend"}, 2}; - case SBIG('CINF'): - return {CINF::Extract, {".blend"}, 1}; - case SBIG('CMDL'): - return {CMDL::Extract, {".blend"}, 1, CMDL::Name}; - case SBIG('DCLN'): - return {DCLN::Extract, {".blend"}}; - case SBIG('ANCS'): - return {ANCS::Extract, {".yaml", ".blend"}, 2}; - case SBIG('MLVL'): - return {MLVL::Extract, {".yaml", ".blend"}, 3}; - case SBIG('SAVW'): - return {MLVL::ExtractSAVW, {".yaml"}, 3}; - case SBIG('MREA'): - return {MREA::Extract, {".blend"}, 4, MREA::Name}; - case SBIG('MAPA'): - return {MAPA::Extract, {".blend"}, 4}; - case SBIG('MAPW'): - return {MLVL::ExtractMAPW, {".yaml"}, 4}; - case SBIG('MAPU'): - return {MAPU::Extract, {".blend"}, 5}; - case SBIG('PATH'): - return {PATH::Extract, {".blend"}, 5}; - case SBIG('PART'): - return {DNAParticle::ExtractGPSM, {".gpsm.yaml"}}; - case SBIG('ELSC'): - return {DNAParticle::ExtractELSM, {".elsm.yaml"}}; - case SBIG('SWHC'): - return {DNAParticle::ExtractSWSH, {".swsh.yaml"}}; - case SBIG('CRSC'): - return {DNAParticle::ExtractCRSM, {".crsm.yaml"}}; - case SBIG('WPSC'): - return {DNAParticle::ExtractWPSM, {".wpsm.yaml"}}; - case SBIG('DPSC'): - return {DNAParticle::ExtractDPSM, {".dpsm.yaml"}}; - case SBIG('FONT'): - return {DNAFont::ExtractFONT, {".yaml"}}; - case SBIG('DGRP'): - return {DNADGRP::ExtractDGRP, {".yaml"}}; - case SBIG('AGSC'): - return {AGSC::Extract, {}}; - case SBIG('CSNG'): - return {CSNG::Extract, {".mid", ".yaml"}}; - case SBIG('ATBL'): - return {DNAAudio::ATBL::Extract, {".yaml"}}; - case SBIG('CTWK'): - case SBIG('DUMB'): { - std::string catalogueName; - std::string name = pak.bestEntryName(pakNode, entry, catalogueName); - if (!catalogueName.empty()) { - if (catalogueName == "PlayerRes"sv) { - if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) { - /* We need to use the new rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - /* We need to use the old rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - if (catalogueName == "GunRes"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Player"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "CameraBob"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "SlideShow"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Game"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Targeting"sv) { - if (isCurrentSpecWii() || getCurrentRegion() == ERegion::PAL || getCurrentRegion() == ERegion::NTSC_J) { - /* We need to use the new rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - /* We need to use the old rep for these tweaks */ - return {ExtractTweak>, {".yaml"}}; - } - if (catalogueName == "Gui"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "AutoMapper"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "PlayerControls"sv || catalogueName == "PlayerControls2"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Ball"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "Particle"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "GuiColors"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "PlayerGun"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "DUMB_MazeSeeds"sv) - return {ExtractTweak, {".yaml"}}; - if (catalogueName == "DUMB_SnowForces"sv) - return {ExtractTweak, {".yaml"}}; - } - break; - } - } - return {}; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DNAMP1.hpp b/DataSpec/DNAMP1/DNAMP1.hpp deleted file mode 100644 index ebc9db828..000000000 --- a/DataSpec/DNAMP1/DNAMP1.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" -#include "zeus/CMatrix4f.hpp" - -namespace DataSpec::DNAMP1 { - -extern logvisor::Module Log; - -/* MP1-specific, one-shot PAK traversal/extraction class */ -class PAKBridge { - const nod::Node& m_node; - PAK m_pak; - -public: - bool m_doExtract; - using Level = DataSpec::Level; - std::unordered_map m_levelDeps; - UniqueID32 m_levelId; - std::string m_levelString; - - PAKBridge(const nod::Node& node, bool doExtract = true); - void build(); - static ResExtractor LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry); - std::string_view getName() const { return m_node.getName(); } - UniqueID32 getLevelId() const { return m_levelId; } - std::string_view getLevelString() const { return m_levelString; } - using PAKType = PAK; - const PAKType& getPAK() const { return m_pak; } - const nod::Node& getNode() const { return m_node; } - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - - void addPATHToMREA(PAKRouter& pakRouter, std::unordered_map& pathToMrea) const; - - void addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, - std::unordered_map& pathOverrides) const; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DeafBabe.cpp b/DataSpec/DNAMP1/DeafBabe.cpp deleted file mode 100644 index b074ba4b9..000000000 --- a/DataSpec/DNAMP1/DeafBabe.cpp +++ /dev/null @@ -1,233 +0,0 @@ -#include "DeafBabe.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) { - os << "TYPE_COLORS = {'NoSFX':(0.0, 0.0, 0.0),\n" - " 'Stone':(1.0, 0.43, 0.15),\n" - " 'Metal':(0.5, 0.5, 0.5),\n" - " 'Grass':(0.0, 0.42, 0.01)," - " 'Ice':(0.0, 0.1, 0.1),\n" - " 'Metal Grating':(0.09, 0.09, 0.09),\n" - " 'Phazon':(0.24, 0.0, 0.21),\n" - " 'Dirt':(0.1, 0.07, 0.05),\n" - " 'Stone':(0.12, 0.12, 0.12),\n" - " 'Lava':(0.8, 0.15, 0.0),\n" - " 'Stone/Rock':(0.06, 0.05, 0.03),\n" - " 'Snow':(0.9, 1.0, 1.0),\n" - " 'Mud (Slow)':(0.12, 0.06, 0.02),\n" - " 'Mud':(0.12, 0.06, 0.02),\n" - " 'Glass':(0.27, 0.38, 0.9),\n" - " 'Shield':(1.0, 0.6, 0.0),\n" - " 'Sand':(0.53, 0.44, 0.21),\n" - " 'Wood':(0.30, 0.15, 0.03),\n" - " 'Organic':(0.19, 0.45, 0.2)}\n" - "\n" - "# Diffuse Color Maker\n" - "from mathutils import Color\n" - "def make_color(index, mat_type, name):\n" - " new_mat = bpy.data.materials.new(name)\n" - " if mat_type in TYPE_COLORS:\n" - " new_mat.diffuse_color = TYPE_COLORS[mat_type] + (1.0,)\n" - " else:\n" - " col = Color()\n" - " col.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n" - " new_mat.diffuse_color = tuple(col) + (1.0,)\n" - " return new_mat\n" - "\n" - "bpy.types.Material.retro_unknown = bpy.props.BoolProperty(name='Retro: Unknown (U)')\n" - "bpy.types.Material.retro_surface_stone = bpy.props.BoolProperty(name='Retro Surface: Stone')\n" - "bpy.types.Material.retro_surface_metal = bpy.props.BoolProperty(name='Retro Surface: Metal')\n" - "bpy.types.Material.retro_surface_grass = bpy.props.BoolProperty(name='Retro Surface: Grass')\n" - "bpy.types.Material.retro_surface_ice = bpy.props.BoolProperty(name='Retro Surface: Ice')\n" - "bpy.types.Material.retro_pillar = bpy.props.BoolProperty(name='Retro Pillar (I)')\n" - "bpy.types.Material.retro_surface_metal_grating = bpy.props.BoolProperty(name='Retro Surface: Metal Grating')\n" - "bpy.types.Material.retro_surface_phazon = bpy.props.BoolProperty(name='Retro Surface: Phazon')\n" - "bpy.types.Material.retro_surface_dirt = bpy.props.BoolProperty(name='Retro Surface: Rock')\n" - "bpy.types.Material.retro_surface_lava = bpy.props.BoolProperty(name='Retro Surface: Lava')\n" - "bpy.types.Material.retro_surface_lava_stone = bpy.props.BoolProperty(name='Retro Surface: Lava Stone')\n" - "bpy.types.Material.retro_surface_snow = bpy.props.BoolProperty(name='Retro Surface: Snow')\n" - "bpy.types.Material.retro_surface_mud_slow = bpy.props.BoolProperty(name='Retro Surface: Mud (Slow)')\n" - "bpy.types.Material.retro_half_pipe = bpy.props.BoolProperty(name='Retro: Half Pipe (H)')\n" - "bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(name='Retro Surface: Mud')\n" - "bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(name='Retro Surface: Glass')\n" - "bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(name='Retro Surface: Shield')\n" - "bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(name='Retro Surface: Sand')\n" - "bpy.types.Material.retro_projectile_passthrough = bpy.props.BoolProperty(name='Retro: Projectile Passthrough " - "(P)')\n" - "bpy.types.Material.retro_solid = bpy.props.BoolProperty(name='Retro: Solid (K)')\n" - "bpy.types.Material.retro_no_platform_collision = bpy.props.BoolProperty(name='Retro: No Platform Collision')\n" - "bpy.types.Material.retro_camera_passthrough = bpy.props.BoolProperty(name='Retro: Camera Passthrough (O)')\n" - "bpy.types.Material.retro_surface_wood = bpy.props.BoolProperty(name='Retro Surface: Wood')\n" - "bpy.types.Material.retro_surface_organic = bpy.props.BoolProperty(name='Retro Surface: Organic')\n" - "bpy.types.Material.retro_no_edge_collision = bpy.props.BoolProperty(name='Retro: No Edge Collision')\n" - "bpy.types.Material.retro_see_through = bpy.props.BoolProperty(name='Retro: See Through')\n" - "bpy.types.Material.retro_scan_passthrough = bpy.props.BoolProperty(name='Retro: Scan Passthrough (S)')\n" - "bpy.types.Material.retro_ai_passthrough = bpy.props.BoolProperty(name='Retro: AI Passthrough (A)')\n" - "bpy.types.Material.retro_ceiling = bpy.props.BoolProperty(name='Retro: Ceiling (C)')\n" - "bpy.types.Material.retro_wall = bpy.props.BoolProperty(name='Retro: Wall (W)')\n" - "bpy.types.Material.retro_floor = bpy.props.BoolProperty(name='Retro: Floor (F)')\n" - "\n" - "material_dict = {}\n" - "material_index = []\n" - "def get_type_id(data):\n" - "\n" - " ret = 0\n" - " for i in range(1, 24):\n" - " if i == 5 or i == 13 or i in range(18, 22):\n" - " continue\n" - " if ((data >> i) & 1):\n" - " ret = i\n" - " return ret\n" - "\n" - "def select_material(data):\n" - "\n" - " type_id = get_type_id(data)\n" - " mat_type = str(type_id)\n" - " if type_id == 0:\n" - " mat_type = 'NoSFX'\n" - " if type_id == 1:\n" - " mat_type = 'Stone'\n" - " elif type_id == 2:\n" - " mat_type = 'Metal'\n" - " elif type_id == 3:\n" - " mat_type = 'Grass'\n" - " elif type_id == 4:\n" - " mat_type = 'Ice'\n" - " elif type_id == 6:\n" - " mat_type = 'Metal Grating'\n" - " elif type_id == 7:\n" - " mat_type = 'Phazon'\n" - " elif type_id == 8:\n" - " mat_type = 'Dirt'\n" - " elif type_id == 9:\n" - " mat_type = 'Lava'\n" - " elif type_id == 10:\n" - " mat_type = 'Stone/Rock'\n" - " elif type_id == 11:\n" - " mat_type = 'Snow'\n" - " elif type_id == 12:\n" - " mat_type = 'Mud (Slow)'\n" - " elif type_id == 14:\n" - " mat_type = 'Mud'\n" - " elif type_id == 15:\n" - " mat_type = 'Glass'\n" - " elif type_id == 16:\n" - " mat_type = 'Shield'\n" - " elif type_id == 17:\n" - " mat_type = 'Sand'\n" - " elif type_id == 22:\n" - " mat_type = 'Wood'\n" - " elif type_id == 23:\n" - " mat_type = 'Organic'\n" - "\n" - " mat_flags = ''\n" - " if ((data >> 0) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 5) & 1):\n" - " mat_flags += 'I'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 13) & 1):\n" - " mat_flags += 'H'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 18) & 1):\n" - " mat_flags += 'P'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 19) & 1):\n" - " mat_flags += 'K'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 20) & 1):\n" - " mat_flags += 'u'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 21) & 1):\n" - " mat_flags += 'O'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 24) & 1):\n" - " mat_flags += 'u'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 26) & 1):\n" - " mat_flags += 'T'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 27) & 1):\n" - " mat_flags += 'S'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 28) & 1):\n" - " mat_flags += 'A'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 29) & 1):\n" - " mat_flags += 'C'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 30) & 1):\n" - " mat_flags += 'W'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 31) & 1):\n" - " mat_flags += 'F'\n" - " else:\n" - " mat_flags += 'x'\n" - "\n" - " if len(mat_flags) > 0:\n" - " mat_flags = ' ' + mat_flags\n" - "\n" - " mat_name = mat_type + mat_flags\n" - "\n" - " if mat_name in material_index:\n" - " return material_index.index(mat_name)\n" - " elif mat_name in material_dict:\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - " else:\n" - " mat = make_color(len(material_dict), mat_type, mat_name)\n" - " mat.retro_unknown = ((data >> 0) & 1)\n" - " mat.retro_surface_stone = ((data >> 1) & 1)\n" - " mat.retro_surface_metal = ((data >> 2) & 1)\n" - " mat.retro_surface_grass = ((data >> 3) & 1) \n" - " mat.retro_surface_ice = ((data >> 4) & 1)\n" - " mat.retro_pillar = ((data >> 5) & 1)\n" - " mat.retro_surface_metal_grating = ((data >> 6) & 1)\n" - " mat.retro_surface_phazon = ((data >> 7) & 1)\n" - " mat.retro_surface_dirt = ((data >> 8) & 1)\n" - " mat.retro_surface_lava = ((data >> 9) & 1)\n" - " mat.retro_surface_lava_stone = ((data >> 10) & 1)\n" - " mat.retro_surface_snow = ((data >> 11) & 1)\n" - " mat.retro_surface_mud_slow = ((data >> 12) & 1)\n" - " mat.retro_half_pipe = ((data >> 13) & 1)\n" - " mat.retro_surface_mud = ((data >> 14) & 1)\n" - " mat.retro_surface_glass = ((data >> 15) & 1)\n" - " mat.retro_surface_shield = ((data >> 16) & 1)\n" - " mat.retro_surface_sand = ((data >> 17) & 1)\n" - " mat.retro_projectile_passthrough = ((data >> 18) & 1)\n" - " mat.retro_solid = ((data >> 19) & 1)\n" - " mat.retro_no_platform_collision = ((data >> 20) & 1)\n" - " mat.retro_camera_passthrough = ((data >> 21) & 1)\n" - " mat.retro_surface_wood = ((data >> 22) & 1)\n" - " mat.retro_surface_organic = ((data >> 23) & 1)\n" - " mat.retro_no_edge_collision = ((data >> 24) & 1)\n" - " mat.retro_see_through = ((data >> 26) & 1)\n" - " mat.retro_scan_passthrough = ((data >> 27) & 1)\n" - " mat.retro_ai_passthrough = ((data >> 28) & 1)\n" - " mat.retro_ceiling = ((data >> 29) & 1)\n" - " mat.retro_wall= ((data >> 30) & 1)\n" - " mat.retro_floor = ((data >> 31) & 1)\n" - " material_dict[mat_name] = mat\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - "\n" - "\n"; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/DeafBabe.hpp b/DataSpec/DNAMP1/DeafBabe.hpp deleted file mode 100644 index f573d4625..000000000 --- a/DataSpec/DNAMP1/DeafBabe.hpp +++ /dev/null @@ -1,241 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DeafBabe.hpp" -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec::DNAMP1 { - -struct DeafBabe : BigDNA { - AT_DECL_DNA - using BspNodeType = DataSpec::BspNodeType; - - struct Material : BigDNA { - AT_DECL_DNA - Value material = 0; - bool unknown() const { return material & 1; } - void setUnknown(bool v) { - material &= ~1; - material |= int(v); - } - bool surfaceStone() const { return (material >> 1) & 1; } - void setSurfaceStone(bool v) { - material &= ~(1ull << 1); - material |= (v << 1); - } - bool surfaceMetal() const { return (material >> 2) & 1; } - void setSurfaceMetal(bool v) { - material &= ~(1ull << 2); - material |= (v << 2); - } - bool surfaceGrass() const { return (material >> 3) & 1; } - void setSurfaceGrass(bool v) { - material &= ~(1ull << 3); - material |= (v << 3); - } - bool surfaceIce() const { return (material >> 4) & 1; } - void setSurfaceIce(bool v) { - material &= ~(1ull << 4); - material |= (v << 4); - } - bool pillar() const { return (material >> 5) & 1; } - void setPillar(bool v) { - material &= ~(1ull << 5); - material |= (v << 5); - } - bool surfaceMetalGrating() const { return (material >> 6) & 1; } - void setSurfaceMetalGrating(bool v) { - material &= ~(1ull << 6); - material |= (v << 6); - } - bool surfacePhazon() const { return (material >> 7) & 1; } - void setSurfacePhazon(bool v) { - material &= ~(1ull << 7); - material |= (v << 7); - } - bool surfaceDirt() const { return (material >> 8) & 1; } - void setSurfaceDirt(bool v) { - material &= ~(1ull << 8); - material |= (v << 8); - } - bool surfaceLava() const { return (material >> 9) & 1; } - void setSurfaceLava(bool v) { - material &= ~(1ull << 9); - material |= (v << 9); - } - bool surfaceStoneRock() const { return (material >> 10) & 1; } - void setSurfaceLavaStone(bool v) { - material &= ~(1ull << 10); - material |= (v << 10); - } - bool surfaceSnow() const { return (material >> 11) & 1; } - void setSurfaceSnow(bool v) { - material &= ~(1ull << 11); - material |= (v << 11); - } - bool surfaceMudSlow() const { return (material >> 12) & 1; } - void setSurfaceMudSlow(bool v) { - material &= ~(1ull << 12); - material |= (v << 12); - } - bool halfPipe() const { return (material >> 13) & 1; } - void setHalfPipe(bool v) { - material &= ~(1ull << 13); - material |= (v << 13); - } - bool surfaceMud() const { return (material >> 14) & 1; } - void setSurfaceMud(bool v) { - material &= ~(1ull << 14); - material |= (v << 14); - } - bool surfaceGlass() const { return (material >> 15) & 1; } - void setSurfaceGlass(bool v) { - material &= ~(1ull << 15); - material |= (v << 15); - } - bool surfaceShield() const { return (material >> 16) & 1; } - void setSurfaceShield(bool v) { - material &= ~(1ull << 16); - material |= (v << 16); - } - bool surfaceSand() const { return (material >> 17) & 1; } - void setSurfaceSand(bool v) { - material &= ~(1ull << 17); - material |= (v << 17); - } - bool projectilePassthrough() const { return (material >> 18) & 1; } - void setProjectilePassthrough(bool v) { - material &= ~(1ull << 18); - material |= (v << 18); - } - bool solid() const { return (material >> 19) & 1; } - void setSolid(bool v) { - material &= ~(1ull << 19); - material |= (v << 19); - } - bool noPlatformCollision() const { return (material >> 20) & 1; } - void setNoPlatformCollision(bool v) { - material &= ~(1ull << 20); - material |= (v << 20); - } - bool cameraPassthrough() const { return (material >> 21) & 1; } - void setCameraPassthrough(bool v) { - material &= ~(1ull << 21); - material |= (v << 21); - } - bool surfaceWood() const { return (material >> 22) & 1; } - void setSurfaceWood(bool v) { - material &= ~(1ull << 22); - material |= (v << 22); - } - bool surfaceOrganic() const { return (material >> 23) & 1; } - void setSurfaceOrganic(bool v) { - material &= ~(1ull << 23); - material |= (v << 23); - } - bool noEdgeCollision() const { return (material >> 24) & 1; } - void setNoEdgeCollision(bool v) { - material &= ~(1ull << 24); - material |= (v << 24); - } - bool flipFace() const { return (material >> 25) & 1; } - void setFlipFace(bool v) { - material &= ~(1ull << 25); - material |= (v << 25); - } - bool seeThrough() const { return (material >> 26) & 1; } - void setSeeThrough(bool v) { - material &= ~(1ull << 26); - material |= (v << 26); - } - bool scanPassthrough() const { return (material >> 27) & 1; } - void setScanPassthrough(bool v) { - material &= ~(1ull << 27); - material |= (v << 27); - } - bool aiPassthrough() const { return (material >> 28) & 1; } - void setAiPassthrough(bool v) { - material &= ~(1ull << 28); - material |= (v << 28); - } - bool ceiling() const { return (material >> 29) & 1; } - void setCeiling(bool v) { - material &= ~(1ull << 29); - material |= (v << 29); - } - bool wall() const { return (material >> 30) & 1; } - void setWall(bool v) { - material &= ~(1ull << 30); - material |= (v << 30); - } - bool floor() const { return (material >> 31) & 1; } - void setFloor(bool v) { - material &= ~(1ull << 31); - material |= (v << 31); - } - - /* Dummies for later games */ - bool surfaceSPMetal() const { return false; } - void setSurfaceSPMetal(bool v) {} - bool surfaceFabric() const { return false; } - void setSurfaceFabric(bool v) {} - bool surfaceRubber() const { return false; } - void setSurfaceRubber(bool v) {} - bool surfaceMothOrSeedOrganics() const { return false; } - void setSurfaceMothOrSeedOrganics(bool v) {} - bool surfaceWeb() const { return false; } - void setSurfaceWeb(bool v) {} - bool unused3() const { return false; } - void setUnused3(bool v) {} - bool unused4() const { return false; } - void setUnused4(bool v) {} - bool aiBlock() const { return false; } - void setAiBlock(bool v) {} - bool jumpNotAllowed() const { return false; } - void setJumpNotAllowed(bool v) {} - bool spiderBall() const { return false; } - void setSpiderBall(bool v) {} - bool screwAttackWallJump() const { return false; } - void setScrewAttackWallJump(bool v) {} - }; - - struct Edge : BigDNA { - AT_DECL_DNA - Value verts[2]; - }; - - struct Triangle : BigDNA { - AT_DECL_DNA - Value edges[3]; - }; - - Value unk1; - Value length; - Value magic; - Value version; - Value aabb[2]; - Value rootNodeType; - Value bspSize; - Buffer bspTree; - Value materialCount; - Vector materials; - Value vertMatsCount; - Vector vertMats; - Value edgeMatsCount; - Vector edgeMats; - Value triMatsCount; - Vector triMats; - Value edgeVertsCount; - Vector edgeVertConnections; - Value triangleEdgesCount; - Vector triangleEdgeConnections; - Value vertCount; - Vector verts; - - /* Dummy MP2 member */ - void insertNoClimb(hecl::blender::PyOutStream&) const {} - - static void BlenderInit(hecl::blender::PyOutStream& os); - void sendToBlender(hecl::blender::PyOutStream& os) const { DeafBabeSendToBlender(os, *this); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/EVNT.cpp b/DataSpec/DNAMP1/EVNT.cpp deleted file mode 100644 index 95d5c401c..000000000 --- a/DataSpec/DNAMP1/EVNT.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "EVNT.hpp" - -namespace DataSpec::DNAMP1 { - -template -void EVNT::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"version"}, version, s); - - DoSize(athena::io::PropId{"boolPOICount"}, boolPOICount, s); - Do(athena::io::PropId{"boolPOINodes"}, boolPOINodes, boolPOICount, s); - - DoSize(athena::io::PropId{"int32POICount"}, int32POICount, s); - Do(athena::io::PropId{"int32POINodes"}, int32POINodes, int32POICount, s); - - DoSize(athena::io::PropId{"particlePOICount"}, particlePOICount, s); - Do(athena::io::PropId{"particlePOINodes"}, particlePOINodes, particlePOICount, s); - - if (version == 2) { - DoSize(athena::io::PropId{"soundPOICount"}, soundPOICount, s); - Do(athena::io::PropId{"soundPOINodes"}, soundPOINodes, soundPOICount, s); - } -} - -AT_SPECIALIZE_DNA_YAML(EVNT) - -std::string_view EVNT::DNAType() { return "DNAMP1::EVNT"sv; } - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/EVNT.hpp b/DataSpec/DNAMP1/EVNT.hpp deleted file mode 100644 index 8d39a78ed..000000000 --- a/DataSpec/DNAMP1/EVNT.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct EVNT : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - Value version; - - struct POINode : BigDNA { - AT_DECL_DNA_YAML - Value unk0; - String<-1> name; - Value type; - struct CharAnimTime : BigDNA { - enum class Type : atUint32 { NonZero, ZeroIncreasing, ZeroSteady, ZeroDecreasing, Infinity }; - - AT_DECL_DNA_YAML - Value time; - Value type; - }; - - CharAnimTime animTime; - Value idx; - Value unk2; - Value weight; - Value charIdx; - Value flags; - }; - - struct BoolPOINode : POINode { - AT_DECL_DNA_YAML - Value value; - }; - Value boolPOICount; - Vector boolPOINodes; - - struct Int32POINode : POINode { - AT_DECL_DNA_YAML - Value value; - String<-1> locator; - }; - Value int32POICount; - Vector int32POINodes; - - struct ParticlePOINode : POINode { - AT_DECL_DNA_YAML - Value duration; - DNAFourCC ptype; - UniqueID32 id; - String<-1> locator; - Value scale; - Value parentMode; - }; - Value particlePOICount; - Vector particlePOINodes; - - struct SoundPOINode : POINode { - AT_DECL_DNA_YAML - Value soundId; - Value falloff; - Value maxDist; - }; - Value soundPOICount; - Vector soundPOINodes; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - EVNT evnt; - evnt.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(evnt, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - EVNT evnt; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(evnt, reader); - athena::io::FileWriter ws(outPath.getAbsolutePath()); - evnt.write(ws); - return true; - } - - void gatherDependencies(std::vector& pathsOut) const { - for (const ParticlePOINode& node : particlePOINodes) - g_curSpec->flattenDependencies(node.id, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/FRME.cpp b/DataSpec/DNAMP1/FRME.cpp deleted file mode 100644 index 27e89411a..000000000 --- a/DataSpec/DNAMP1/FRME.cpp +++ /dev/null @@ -1,613 +0,0 @@ -#include "FRME.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void FRME::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* version */ - version = __dna_reader.readUint32Big(); - /* unk1 */ - unk1 = __dna_reader.readUint32Big(); - /* modelCount */ - modelCount = __dna_reader.readUint32Big(); - /* unk3 */ - unk3 = __dna_reader.readUint32Big(); - /* widgetCount */ - widgetCount = __dna_reader.readUint32Big(); - /* widgets */ - __dna_reader.enumerate(widgets, widgetCount, [this](athena::io::IStreamReader& reader, Widget& w) { - w.owner = this; - w.read(reader); - }); -} - -template <> -void FRME::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* version */ - __dna_writer.writeUint32Big(version); - /* unk1 */ - __dna_writer.writeUint32Big(unk1); - /* modelCount */ - __dna_writer.writeUint32Big(modelCount); - /* unk3 */ - __dna_writer.writeUint32Big(unk3); - /* widgetCount */ - __dna_writer.writeUint32Big(widgetCount); - /* widgets */ - __dna_writer.enumerate(widgets); -} - -template <> -void FRME::Enumerate(size_t& __isz) { - for (const Widget& w : widgets) - w.binarySize(__isz); - __isz += 20; -} - -template <> -void FRME::Widget::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* type */ - type.read(__dna_reader); - /* header */ - header.read(__dna_reader); - switch (type.toUint32()) { - case SBIG('BWIG'): - widgetInfo = std::make_unique(); - break; - case SBIG('HWIG'): - widgetInfo = std::make_unique(); - break; - case SBIG('CAMR'): - widgetInfo = std::make_unique(); - break; - case SBIG('LITE'): - widgetInfo = std::make_unique(); - break; - case SBIG('ENRG'): - widgetInfo = std::make_unique(); - break; - case SBIG('MODL'): - widgetInfo = std::make_unique(); - break; - case SBIG('METR'): - widgetInfo = std::make_unique(); - break; - case SBIG('GRUP'): - widgetInfo = std::make_unique(); - break; - case SBIG('PANE'): - widgetInfo = std::make_unique(); - break; - case SBIG('TXPN'): - widgetInfo = std::make_unique(owner->version); - break; - case SBIG('IMGP'): - widgetInfo = std::make_unique(); - break; - case SBIG('TBGP'): - widgetInfo = std::make_unique(); - break; - case SBIG('SLGP'): - widgetInfo = std::make_unique(); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unsupported FRME widget type {}"), type); - } - - /* widgetInfo */ - widgetInfo->read(__dna_reader); - - /* isWorker */ - isWorker = __dna_reader.readBool(); - if (isWorker) { - /* workerId */ - workerId = __dna_reader.readUint16Big(); - } - /* origin */ - origin = __dna_reader.readVec3fBig(); - /* basis[0] */ - basis[0] = __dna_reader.readVec3fBig(); - /* basis[1] */ - basis[1] = __dna_reader.readVec3fBig(); - /* basis[2] */ - basis[2] = __dna_reader.readVec3fBig(); - /* rotationCenter */ - rotationCenter = __dna_reader.readVec3fBig(); - /* unk1 */ - unk1 = __dna_reader.readInt32Big(); - /* unk2 */ - unk2 = __dna_reader.readInt16Big(); -} - -template <> -void FRME::Widget::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* type */ - DNAFourCC _type = widgetInfo ? widgetInfo->fourcc() : FOURCC('BWIG'); - _type.write(__dna_writer); - /* header */ - header.write(__dna_writer); - - /* widgetInfo */ - if (widgetInfo) - widgetInfo->write(__dna_writer); - - /* isWorker */ - __dna_writer.writeBool(isWorker); - if (isWorker) { - /* workerId */ - __dna_writer.writeUint16Big(workerId); - } - /* origin */ - __dna_writer.writeVec3fBig(origin); - /* basis[0] */ - __dna_writer.writeVec3fBig(basis[0]); - /* basis[1] */ - __dna_writer.writeVec3fBig(basis[1]); - /* basis[2] */ - __dna_writer.writeVec3fBig(basis[2]); - /* rotationCenter */ - __dna_writer.writeVec3fBig(rotationCenter); - /* unk1 */ - __dna_writer.writeInt32Big(unk1); - /* unk2 */ - __dna_writer.writeInt16Big(unk2); -} - -template <> -void FRME::Widget::Enumerate(size_t& __isz) { - type.binarySize(__isz); - header.binarySize(__isz); - if (widgetInfo) - widgetInfo->binarySize(__isz); - if (isWorker) - __isz += 4; - __isz += 67; -} - -template <> -void FRME::Widget::CAMRInfo::Enumerate(athena::io::IStreamReader& __dna_reader) { - projectionType = ProjectionType(__dna_reader.readUint32Big()); - if (projectionType == ProjectionType::Perspective) { - projection = std::make_unique(); - } else if (projectionType == ProjectionType::Orthographic) { - projection = std::make_unique(); - } else { - Log.report(logvisor::Fatal, FMT_STRING("Invalid CAMR projection mode! {}"), int(projectionType)); - } - - projection->read(__dna_reader); -} - -template <> -void FRME::Widget::CAMRInfo::Enumerate(athena::io::IStreamWriter& __dna_writer) { - if (!projection) - Log.report(logvisor::Fatal, FMT_STRING("Invalid CAMR projection object!")); - if (projection->type != projectionType) - Log.report(logvisor::Fatal, FMT_STRING("CAMR projection type does not match actual projection type!")); - - __dna_writer.writeUint32Big(atUint32(projectionType)); - projection->write(__dna_writer); -} - -template <> -void FRME::Widget::CAMRInfo::Enumerate(size_t& __isz) { - projection->binarySize(__isz); - __isz += 4; -} - -template <> -void FRME::Widget::LITEInfo::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* type */ - type = ELightType(__dna_reader.readUint32Big()); - /* distC */ - distC = __dna_reader.readFloatBig(); - /* distL */ - distL = __dna_reader.readFloatBig(); - /* distQ */ - distQ = __dna_reader.readFloatBig(); - /* angC */ - angC = __dna_reader.readFloatBig(); - /* angL */ - angL = __dna_reader.readFloatBig(); - /* angQ */ - angQ = __dna_reader.readFloatBig(); - /* loadedIdx */ - loadedIdx = __dna_reader.readUint32Big(); - - /* cutoff */ - if (type == ELightType::Spot) - cutoff = __dna_reader.readFloatBig(); -} - -template <> -void FRME::Widget::LITEInfo::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* type */ - __dna_writer.writeUint32Big(atUint32(type)); - /* distC */ - __dna_writer.writeFloatBig(distC); - /* distL */ - __dna_writer.writeFloatBig(distL); - /* distQ */ - __dna_writer.writeFloatBig(distQ); - /* angC */ - __dna_writer.writeFloatBig(angC); - /* angL */ - __dna_writer.writeFloatBig(angL); - /* angQ */ - __dna_writer.writeFloatBig(angQ); - /* loadedIdx */ - __dna_writer.writeUint32Big(loadedIdx); - - /* cutoff */ - if (type == ELightType::Spot) - __dna_writer.writeFloatBig(cutoff); -} - -template <> -void FRME::Widget::LITEInfo::Enumerate(size_t& __isz) { - __isz += ((type == ELightType::Spot) ? 36 : 32); -} - -template -void FRME::Widget::TXPNInfo::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"xDim"}, xDim, s); - Do(athena::io::PropId{"zDim"}, zDim, s); - Do(athena::io::PropId{"scaleCenter"}, scaleCenter, s); - Do(athena::io::PropId{"font"}, font, s); - Do(athena::io::PropId{"wordWrap"}, wordWrap, s); - Do(athena::io::PropId{"horizontal"}, horizontal, s); - Do(athena::io::PropId{"justification"}, justification, s); - Do(athena::io::PropId{"verticalJustification"}, verticalJustification, s); - Do(athena::io::PropId{"fillColor"}, fillColor, s); - Do(athena::io::PropId{"outlineColor"}, outlineColor, s); - Do(athena::io::PropId{"blockExtent"}, blockExtent, s); - if (version == 1) { - Do(athena::io::PropId{"jpnFont"}, jpnFont, s); - Do(athena::io::PropId{"jpnPointScale[0]"}, jpnPointScale[0], s); - Do(athena::io::PropId{"jpnPointScale[1]"}, jpnPointScale[1], s); - } -} - -AT_SPECIALIZE_DNA(FRME::Widget::TXPNInfo) - -bool FRME::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - if (!force && outPath.isFile()) - return true; - - FRME frme; - frme.read(rs); - - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Frame)) - return false; - - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - - os << "import bpy, math, bmesh\n" - "from mathutils import Matrix, Quaternion\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "def duplicateObject(copy_obj):\n" - " # Create new mesh\n" - " mesh = bpy.data.meshes.new(copy_obj.name)\n" - " # Create new object associated with the mesh\n" - " ob_new = bpy.data.objects.new(copy_obj.name, mesh)\n" - " # Copy data block from the old object into the new object\n" - " ob_new.data = copy_obj.data\n" - " ob_new.scale = copy_obj.scale\n" - " ob_new.location = copy_obj.location\n" - " # Link new object to the given scene and select it\n" - " bpy.context.scene.collection.objects.link(ob_new)\n" - " return ob_new\n"; - - os.format(FMT_STRING("bpy.context.scene.name = '{}'\n" - "bpy.context.scene.render.resolution_x = 640\n" - "bpy.context.scene.render.resolution_y = 480\n" - "bpy.context.scene.world.use_nodes = True\n" - "bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n" - "bg_node.inputs[1].default_value = 0.0\n"), - pakRouter.getBestEntryName(entry)); - - int pIdx = 0; - for (const FRME::Widget& w : frme.widgets) { - os << "binding = None\n" - "angle = Quaternion((1.0, 0.0, 0.0), 0)\n"; - if (w.type == SBIG('CAMR')) { - using CAMRInfo = Widget::CAMRInfo; - os.format(FMT_STRING("cam = bpy.data.cameras.new(name='{}')\n" - "binding = cam\n"), - w.header.name); - if (CAMRInfo* info = static_cast(w.widgetInfo.get())) { - if (info->projectionType == CAMRInfo::ProjectionType::Orthographic) { - CAMRInfo::OrthographicProjection* proj = - static_cast(info->projection.get()); - os.format(FMT_STRING("cam.type = 'ORTHO'\n" - "cam.ortho_scale = {}\n" - "cam.clip_start = {}\n" - "cam.clip_end = {}\n"), - std::fabs(proj->right - proj->left), proj->znear, proj->zfar); - } else if (info->projectionType == CAMRInfo::ProjectionType::Perspective) { - CAMRInfo::PerspectiveProjection* proj = static_cast(info->projection.get()); - os.format(FMT_STRING("cam.type = 'PERSP'\n" - "cam.lens_unit = 'FOV'\n" - "cam.clip_start = {}\n" - "cam.clip_end = {}\n" - "bpy.context.scene.render.resolution_x = int(480 * {})\n"), - proj->znear, proj->zfar, proj->aspect); - if (proj->aspect > 1.f) - os.format(FMT_STRING("cam.angle = math.atan2({}, 1.0 / math.tan(math.radians({} / 2.0))) * 2.0\n"), - proj->aspect, proj->fov); - else - os.format(FMT_STRING("cam.angle = math.radians({})\n"), proj->fov); - } - } - os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n"; - } else if (w.type == SBIG('LITE')) { - using LITEInfo = Widget::LITEInfo; - if (LITEInfo* info = static_cast(w.widgetInfo.get())) { - switch (info->type) { - case LITEInfo::ELightType::LocalAmbient: { - zeus::simd_floats colorF(w.header.color.simd); - os.format(FMT_STRING("bg_node.inputs[0].default_value = ({},{},{},1.0)\n" - "bg_node.inputs[1].default_value = {}\n"), - colorF[0], colorF[1], colorF[2], info->distQ / 8.0); - break; - } - case LITEInfo::ELightType::Spot: - case LITEInfo::ELightType::Directional: - os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n"; - [[fallthrough]]; - default: { - zeus::simd_floats colorF(w.header.color.simd); - os.format(FMT_STRING("lamp = bpy.data.lights.new(name='{}', type='POINT')\n" - "lamp.color = ({}, {}, {})\n" - "lamp.hecl_falloff_constant = {}\n" - "lamp.hecl_falloff_linear = {}\n" - "lamp.hecl_falloff_quadratic = {}\n" - "lamp.retro_light_angle_constant = {}\n" - "lamp.retro_light_angle_linear = {}\n" - "lamp.retro_light_angle_quadratic = {}\n" - "lamp.retro_light_index = {}\n" - "binding = lamp\n"), - w.header.name, colorF[0], colorF[1], colorF[2], info->distC, info->distL, info->distQ, info->angC, - info->angL, info->angQ, info->loadedIdx); - if (info->type == LITEInfo::ELightType::Spot) - os.format(FMT_STRING("lamp.type = 'SPOT'\n" - "lamp.spot_size = {}\n"), - info->cutoff); - else if (info->type == LITEInfo::ELightType::Directional) - os << "lamp.type = 'SUN'\n"; - } - } - } - } else if (w.type == SBIG('IMGP')) { - using IMGPInfo = Widget::IMGPInfo; - if (IMGPInfo* info = static_cast(w.widgetInfo.get())) { - std::string texName; - std::string resPath; - if (info->texture.isValid()) { - texName = pakRouter.getBestEntryName(info->texture); - const nod::Node* node; - const PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(info->texture, &node); - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - resPath = pakRouter.getResourceRelativePath(entry, info->texture); - } - - if (resPath.size()) { - os.format(FMT_STRING("if '{}' in bpy.data.images:\n" - " image = bpy.data.images['{}']\n" - "else:\n" - " image = bpy.data.images.load('''//{}''')\n" - " image.name = '{}'\n"), - texName, texName, resPath, texName); - } else { - os << "image = None\n"; - } - - os.format(FMT_STRING("material = bpy.data.materials.new('{}')\n" - "material.use_nodes = True\n" - "new_nodetree = material.node_tree\n" - "for n in new_nodetree.nodes:\n" - " new_nodetree.nodes.remove(n)\n" - "tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n" - "tex_node.image = image\n" - "bm = bmesh.new()\n" - "verts = []\n"), - w.header.name); - - for (uint32_t i = 0; i < info->quadCoordCount; ++i) { - int ti; - if (i == 2) - ti = 3; - else if (i == 3) - ti = 2; - else - ti = i; - zeus::simd_floats f(info->quadCoords[ti].simd); - os.format(FMT_STRING("verts.append(bm.verts.new(({},{},{})))\n"), f[0], f[1], f[2]); - } - os << "bm.faces.new(verts)\n" - "bm.loops.layers.uv.new('UV')\n" - "bm.verts.ensure_lookup_table()\n"; - for (uint32_t i = 0; i < info->uvCoordCount; ++i) { - int ti; - if (i == 2) - ti = 3; - else if (i == 3) - ti = 2; - else - ti = i; - zeus::simd_floats f(info->uvCoords[ti].simd); - os.format(FMT_STRING("bm.verts[{}].link_loops[0][bm.loops.layers.uv[0]].uv = ({},{})\n"), i, f[0], f[1]); - } - os.format(FMT_STRING("binding = bpy.data.meshes.new('{}')\n" - "bm.to_mesh(binding)\n" - "bm.free()\n" - "binding.materials.append(material)\n"), - w.header.name); - } - } - - zeus::simd_floats colorF(w.header.color.simd); - os.format(FMT_STRING( - "frme_obj = bpy.data.objects.new(name='{}', object_data=binding)\n" - "frme_obj.pass_index = {}\n" - "parentName = '{}'\n" - "frme_obj.retro_widget_type = 'RETRO_{}'\n" - "frme_obj.retro_widget_use_anim_controller = {}\n" - "frme_obj.retro_widget_default_visible = {}\n" - "frme_obj.retro_widget_default_active = {}\n" - "frme_obj.retro_widget_cull_faces = {}\n" - "frme_obj.retro_widget_color = ({},{},{},{})\n" - "widget_model_draw_flags = {}\n" - "if bpy.app.version >= (2, 93, 0):\n" - " frme_obj.retro_widget_model_draw_flags = bpy.types.Object.retro_widget_model_draw_flags.keywords['items'][widget_model_draw_flags][0]\n" - "else:\n" - " frme_obj.retro_widget_model_draw_flags = bpy.types.Object.retro_widget_model_draw_flags[1]['items'][widget_model_draw_flags][0]\n" - "frme_obj.retro_widget_is_worker = {}\n" - "frme_obj.retro_widget_worker_id = {}\n" - "if parentName not in bpy.data.objects:\n" - " frme_obj.retro_widget_parent = parentName\n" - "else:\n" - " frme_obj.parent = bpy.data.objects[parentName]\n"), - w.header.name, pIdx++, w.header.parent, w.type, - w.header.useAnimController ? "True" : "False", w.header.defaultVisible ? "True" : "False", - w.header.defaultActive ? "True" : "False", w.header.cullFaces ? "True" : "False", colorF[0], colorF[1], - colorF[2], colorF[3], w.header.modelDrawFlags, w.isWorker ? "True" : "False", w.workerId); - - if (w.type == SBIG('MODL')) { - using MODLInfo = FRME::Widget::MODLInfo; - MODLInfo* info = static_cast(w.widgetInfo.get()); - hecl::ProjectPath modelPath = pakRouter.getWorking(info->model); - const PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info->model, nullptr, true, true); - - os.linkMesh(modelPath.getAbsolutePath(), pakRouter.getBestEntryName(*cmdlE)); - - os.format(FMT_STRING("frme_obj.retro_model_light_mask = {}\n"), info->lightMask); - os << "print(obj.name)\n" - "copy_obj = duplicateObject(obj)\n" - "copy_obj.parent = frme_obj\n" - "copy_obj.hide_set(False)\n"; - } else if (w.type == SBIG('CAMR')) { - os << "bpy.context.scene.camera = frme_obj\n" - "if 'Camera' in bpy.data.objects:\n" - " cam = bpy.data.objects['Camera']\n" - " #bpy.context.scene.objects.unlink(cam)\n" - " bpy.data.objects.remove(cam)\n"; - } else if (w.type == SBIG('PANE')) { - using PANEInfo = Widget::PANEInfo; - if (PANEInfo* info = static_cast(w.widgetInfo.get())) { - zeus::simd_floats f(info->scaleCenter.simd); - os.format(FMT_STRING("frme_obj.retro_pane_dimensions = ({},{})\n" - "frme_obj.retro_pane_scale_center = ({},{},{})\n"), - info->xDim, info->zDim, f[0], f[1], f[2]); - } - } else if (w.type == SBIG('TXPN')) { - using TXPNInfo = Widget::TXPNInfo; - if (TXPNInfo* info = static_cast(w.widgetInfo.get())) { - hecl::ProjectPath fontPath = pakRouter.getWorking(info->font, true); - hecl::ProjectPath jpFontPath; - if (frme.version >= 1) - jpFontPath = pakRouter.getWorking(info->jpnFont, true); - - zeus::simd_floats scaleF(info->scaleCenter.simd); - zeus::simd_floats fillF(info->fillColor.simd); - zeus::simd_floats outlineF(info->outlineColor.simd); - zeus::simd_floats extentF(info->blockExtent.simd); - os.format(FMT_STRING( - "frme_obj.retro_pane_dimensions = ({},{})\n" - "frme_obj.retro_pane_scale_center = ({},{},{})\n" - "frme_obj.retro_textpane_font_path = '{}'\n" - "frme_obj.retro_textpane_word_wrap = {}\n" - "frme_obj.retro_textpane_horizontal = {}\n" - "frme_obj.retro_textpane_fill_color = ({},{},{},{})\n" - "frme_obj.retro_textpane_outline_color = ({},{},{},{})\n" - "frme_obj.retro_textpane_block_extent = ({},{})\n" - "frme_obj.retro_textpane_jp_font_path = '{}'\n" - "frme_obj.retro_textpane_jp_font_scale = ({},{})\n" - "textpane_hjustification = {}\n" - "textpane_vjustification = {}\n" - "if bpy.app.version >= (2, 93, 0):\n" - " frme_obj.retro_textpane_hjustification = bpy.types.Object.retro_textpane_hjustification.keywords['items'][textpane_hjustification][0]\n" - " frme_obj.retro_textpane_vjustification = bpy.types.Object.retro_textpane_vjustification.keywords['items'][textpane_vjustification][0]\n" - "else:\n" - " frme_obj.retro_textpane_hjustification = bpy.types.Object.retro_textpane_hjustification[1]['items'][textpane_hjustification][0]\n" - " frme_obj.retro_textpane_vjustification = bpy.types.Object.retro_textpane_vjustification[1]['items'][textpane_vjustification][0]\n"), - info->xDim, info->zDim, scaleF[0], scaleF[1], scaleF[2], fontPath.getRelativePath(), - info->wordWrap ? "True" : "False", info->horizontal ? "True" : "False", fillF[0], fillF[1], fillF[2], - fillF[3], outlineF[0], outlineF[1], outlineF[2], outlineF[3], extentF[0], extentF[1], - jpFontPath.getRelativePath(), info->jpnPointScale[0], info->jpnPointScale[1], - int(info->justification), int(info->verticalJustification)); - } - } else if (w.type == SBIG('TBGP')) { - using TBGPInfo = Widget::TBGPInfo; - if (TBGPInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_tablegroup_elem_count = {}\n" - "frme_obj.retro_tablegroup_elem_default = {}\n" - "frme_obj.retro_tablegroup_wraparound = {}\n"), - info->elementCount, info->defaultSelection, info->selectWraparound ? "True" : "False"); - } - } else if (w.type == SBIG('GRUP')) { - using GRUPInfo = Widget::GRUPInfo; - if (GRUPInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_group_default_worker = {}\n"), info->defaultWorker); - } - } else if (w.type == SBIG('SLGP')) { - using SLGPInfo = Widget::SLGPInfo; - if (SLGPInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_slider_min = {}\n" - "frme_obj.retro_slider_max = {}\n" - "frme_obj.retro_slider_default = {}\n" - "frme_obj.retro_slider_increment = {}\n"), - info->min, info->max, info->cur, info->increment); - } - } else if (w.type == SBIG('ENRG')) { - using ENRGInfo = Widget::ENRGInfo; - if (ENRGInfo* info = static_cast(w.widgetInfo.get())) { - hecl::ProjectPath txtrPath = pakRouter.getWorking(info->texture); - if (txtrPath) - os.format(FMT_STRING("frme_obj.retro_energybar_texture_path = '{}'\n"), txtrPath.getRelativePath()); - } - } else if (w.type == SBIG('METR')) { - using METRInfo = Widget::METRInfo; - if (METRInfo* info = static_cast(w.widgetInfo.get())) { - os.format(FMT_STRING("frme_obj.retro_meter_no_round_up = {}\n" - "frme_obj.retro_meter_max_capacity = {}\n" - "frme_obj.retro_meter_worker_count = {}\n"), - info->noRoundUp ? "True" : "False", info->maxCapacity, info->workerCount); - } - } - - zeus::simd_floats xfMtxF[3]; - for (int i = 0; i < 3; ++i) - w.basis[i].simd.copy_to(xfMtxF[i]); - zeus::simd_floats originF(w.origin.simd); - os.format(FMT_STRING("mtx = Matrix((({},{},{},{}),({},{},{},{}),({},{},{},{}),(0.0,0.0,0.0,1.0)))\n" - "mtxd = mtx.decompose()\n" - "frme_obj.rotation_mode = 'QUATERNION'\n" - "frme_obj.location = mtxd[0]\n" - "frme_obj.rotation_quaternion = mtxd[1] @ angle\n" - "frme_obj.scale = mtxd[2]\n" - "bpy.context.scene.collection.objects.link(frme_obj)\n"), - xfMtxF[0][0], xfMtxF[0][1], xfMtxF[0][2], originF[0], xfMtxF[1][0], xfMtxF[1][1], xfMtxF[1][2], - originF[1], xfMtxF[2][0], xfMtxF[2][1], xfMtxF[2][2], originF[2]); - } - - os.centerView(); - os.close(); - conn.saveBlend(); - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/FRME.hpp b/DataSpec/DNAMP1/FRME.hpp deleted file mode 100644 index 5e24d7c9c..000000000 --- a/DataSpec/DNAMP1/FRME.hpp +++ /dev/null @@ -1,274 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" -#include -#include "athena/DNAOp.hpp" - -namespace DataSpec::DNAMP1 { -struct FRME : BigDNA { - AT_DECL_EXPLICIT_DNA - Value version; - Value unk1; - Value modelCount; // Matches MODL widgets - Value unk3; - Value widgetCount; - - struct Widget : BigDNA { - AT_DECL_EXPLICIT_DNA - FRME* owner; - DNAFourCC type; - struct WidgetHeader : BigDNA { - AT_DECL_DNA - String<-1> name; - String<-1> parent; - Value useAnimController; - Value defaultVisible; - Value defaultActive; - Value cullFaces; - Value color; - Value modelDrawFlags; - } header; - - struct IWidgetInfo : BigDNAV { - Delete _dBase; - virtual FourCC fourcc() const = 0; - }; - - std::unique_ptr widgetInfo; - Value isWorker; - Value workerId = 0; - Value origin; - Value basis[3]; - Value rotationCenter; - Value unk1; - Value unk2; - - struct BWIGInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::BWIG"sv; } - FourCC fourcc() const override { return FOURCC('BWIG'); } - }; - - struct HWIGInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::HWIG"sv; } - FourCC fourcc() const override { return FOURCC('HWIG'); } - }; - - struct CAMRInfo : IWidgetInfo { - AT_DECL_EXPLICIT_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::CAMR"sv; } - enum class ProjectionType { Perspective, Orthographic }; - - Value projectionType; - struct IProjection : BigDNAV { - Delete _d; - const ProjectionType type; - IProjection(ProjectionType t) : type(t) {} - }; - - struct PerspectiveProjection : IProjection { - AT_DECL_DNAV - PerspectiveProjection() : IProjection(ProjectionType::Perspective) {} - Value fov; - Value aspect; - Value znear; - Value zfar; - }; - - struct OrthographicProjection : IProjection { - AT_DECL_DNAV - OrthographicProjection() : IProjection(ProjectionType::Orthographic) {} - Value left; - Value right; - Value top; - Value bottom; - Value znear; - Value zfar; - }; - std::unique_ptr projection; - - FourCC fourcc() const override { return FOURCC('CAMR'); } - }; - - struct MODLInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::MODL"sv; } - UniqueID32 model; - enum class BlendMode { Unknown0, Unknown1, Unknown2, Additive }; - - Value blendMode; - Value lightMask; - - FourCC fourcc() const override { return FOURCC('MODL'); } - }; - - struct LITEInfo : IWidgetInfo { - AT_DECL_EXPLICIT_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::LITE"sv; } - enum class ELightType : atUint32 { - Spot = 0, - Point = 1, - Directional = 2, - LocalAmbient = 3, - Custom = 4, - }; - - Value type; - Value distC; - Value distL; - Value distQ; - Value angC; - Value angL; - Value angQ; - Value loadedIdx; - Value cutoff; /* Spot only */ - - FourCC fourcc() const override { return FOURCC('LITE'); } - }; - - struct ENRGInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::ENRG"sv; } - UniqueID32 texture; - - FourCC fourcc() const override { return FOURCC('ENRG'); } - }; - - struct METRInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::METR"sv; } - Value unk1; - Value noRoundUp; - Value maxCapacity; - Value workerCount; - - FourCC fourcc() const override { return FOURCC('METR'); } - }; - - struct GRUPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::GRUP"sv; } - Value defaultWorker; - Value unk3; - - FourCC fourcc() const override { return FOURCC('GRUP'); } - }; - - struct TBGPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::TBGP"sv; } - Value elementCount; - Value unk2; - Value unkEnum; - Value defaultSelection; - Value un4; - Value selectWraparound; - Value unk6; - Value unkFloat1; - Value unkFloat2; - Value unk7; - Value unkFloat3; - Value unk8; - Value unk9; - Value unk10; - Value unk11; - - FourCC fourcc() const override { return FOURCC('TBGP'); } - }; - - struct SLGPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::SLGP"sv; } - Value min; - Value max; - Value cur; - Value increment; - - FourCC fourcc() const override { return FOURCC('SLGP'); } - }; - - struct PANEInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::PANE"sv; } - Value xDim; - Value zDim; - Value scaleCenter; - - FourCC fourcc() const override { return FOURCC('PANE'); } - }; - - struct TXPNInfo : IWidgetInfo { - std::string_view DNATypeV() const override { return "FRME::TXPN"sv; } - enum class Justification : atUint32 { - Left = 0, - Center, - Right, - Full, - NLeft, - NCenter, - NRight, - LeftMono, - CenterMono, - RightMono - }; - - enum class VerticalJustification : atUint32 { - Top = 0, - Center, - Bottom, - Full, - NTop, - NCenter, - NBottom, - LeftMono, - CenterMono, - RightMono - }; - - AT_DECL_EXPLICIT_DNAV_NO_TYPE - - atUint32 version = 0; - TXPNInfo() {} - TXPNInfo(atUint32 version) : version(version) {} - Value xDim; - Value zDim; - Value scaleCenter; - UniqueID32 font; - Value wordWrap; - Value horizontal; - Value justification; - Value verticalJustification; - Value fillColor; - Value outlineColor; - Value blockExtent; /* In points; converted to int by loader */ - /* The following is only found in V1 */ - UniqueID32 jpnFont; - Value jpnPointScale[2] = {}; - - FourCC fourcc() const override { return FOURCC('TXPN'); } - }; - - struct IMGPInfo : IWidgetInfo { - AT_DECL_DNAV_NO_TYPE - std::string_view DNATypeV() const override { return "FRME::IMGP"sv; } - UniqueID32 texture; - Value unk1; - Value unk2; - Value quadCoordCount; - Vector quadCoords; - Value uvCoordCount; - Vector uvCoords; - - FourCC fourcc() const override { return FOURCC('IMGP'); } - }; - }; - - Vector widgets; - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/HINT.hpp b/DataSpec/DNAMP1/HINT.hpp deleted file mode 100644 index f035bd68c..000000000 --- a/DataSpec/DNAMP1/HINT.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAMP1 { -struct HINT : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - - struct Hint : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value immediateTime; - Value normalTime; - UniqueID32 stringID; - Value textPageCount; - struct Location : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 worldAssetID; - UniqueID32 areaAssetID; - Value areaID; - UniqueID32 stringID; - }; - - Value locationCount; - Vector locations; - }; - Value hintCount; - Vector hints; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - HINT hint; - hint.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(hint, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - HINT hint; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(hint, reader); - athena::io::FileWriter ws(outPath.getAbsolutePath()); - hint.write(ws); - return true; - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MAPA.hpp b/DataSpec/DNAMP1/MAPA.hpp deleted file mode 100644 index 49a0daaf7..000000000 --- a/DataSpec/DNAMP1/MAPA.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPA.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct MAPA : DNAMAPA::MAPA { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MAPA mapa; - mapa.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); - } - - static bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out) { - return DNAMAPA::Cook(mapa, out); - } - - static uint32_t Version() { return 2; } - using Header = DNAMAPA::MAPA::HeaderMP1; - using MappableObject = DNAMAPA::MAPA::MappableObjectMP1_2; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MAPU.hpp b/DataSpec/DNAMP1/MAPU.hpp deleted file mode 100644 index a29254dc0..000000000 --- a/DataSpec/DNAMP1/MAPU.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPU.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct MAPU : DNAMAPU::MAPU { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MAPU mapu; - mapu.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPU::ReadMAPUToBlender(conn, mapu, outPath, pakRouter, entry, force); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MLVL.cpp b/DataSpec/DNAMP1/MLVL.cpp deleted file mode 100644 index 149a718f2..000000000 --- a/DataSpec/DNAMP1/MLVL.cpp +++ /dev/null @@ -1,537 +0,0 @@ -#include "MLVL.hpp" -#include "SCLY.hpp" -#include "SAVW.hpp" -#include "SCAN.hpp" -#include "ScriptObjects/MemoryRelay.hpp" -#include "ScriptObjects/SpecialFunction.hpp" -#include "ScriptObjects/DoorArea.hpp" -#include "Runtime/RetroTypes.hpp" -#include "Runtime/World/ScriptObjectSupport.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP1; - -namespace DNAMP1 { - -bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MLVL mlvl; - mlvl.read(rs); - const nod::Node* node; - const typename PAKRouter::EntryType* savwEntry = pakRouter.lookupEntry(mlvl.saveWorldId, &node); - SAVW savw; - { - PAKEntryReadStream rs = savwEntry->beginReadStream(*node); - savw.read(rs); - } - - atUint32 areaIdx = 0; - for (const MLVL::Area& area : mlvl.areas) { - hecl::ProjectPath areaDir = pakRouter.getWorking(area.areaMREAId).getParentPath(); - { - athena::io::FileWriter fw(hecl::ProjectPath(areaDir, "!memoryid.yaml").getAbsolutePath()); - athena::io::YAMLDocWriter w; - w.writeUint32("memoryid", area.areaId); - w.finish(&fw); - } - { - athena::io::FileWriter fw(hecl::ProjectPath(areaDir, "!memoryrelays.yaml").getAbsolutePath()); - athena::io::YAMLDocWriter w; - - std::vector relayIds; - for (const atUint32& relay : savw.relays) { - atUint16 aIdx = ((relay >> 16) & 0x3ff); - if (aIdx == areaIdx && std::find(relayIds.begin(), relayIds.end(), relay) == relayIds.end()) - relayIds.push_back(relay); - } - - w.enumerate("memrelays", relayIds); - w.finish(&fw); - } - if (pakRouter.mreaHasDupeResources(area.areaMREAId)) - athena::io::FileWriter(hecl::ProjectPath(areaDir, "!duperes").getAbsolutePath()); - - areaIdx++; - } - - athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::ToYAMLStream(mlvl, writer, &MLVL::writeMeta); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); -} - -bool MLVL::ExtractMAPW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - /* Empty placeholder file for dependency management */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::YAMLDocWriter dw("DataSpec::DNAMP1::MAPW"); - return dw.finish(&writer); -} - -bool MLVL::ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - /* Empty placeholder file for dependency management */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::YAMLDocWriter dw("DataSpec::DNAMP1::SAVW"); - return dw.finish(&writer); -} - -struct LayerResources { - std::unordered_set addedPaths; - std::vector>> layerPaths; - std::unordered_set addedSharedPaths; - std::vector> sharedPaths; - void beginLayer() { - layerPaths.resize(layerPaths.size() + 1); - addedPaths.clear(); - } - void addSharedPath(const hecl::ProjectPath& path, bool lazy) { - auto search = addedSharedPaths.find(path.hash()); - if (search == addedSharedPaths.cend()) { - sharedPaths.emplace_back(path, lazy); - addedSharedPaths.insert(path.hash()); - } - } - void addPath(const hecl::ProjectPath& path, bool lazy) { - auto search = addedPaths.find(path.hash()); - if (search == addedPaths.cend()) { - layerPaths.back().emplace_back(path, lazy); - addedPaths.insert(path.hash()); - } - } -}; - -bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld, - hecl::blender::Token& btok) { - MLVL mlvl = {}; - athena::io::FileReader reader(inPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::FromYAMLStream(mlvl, reader, &MLVL::readMeta); - - const hecl::ProjectPath parentPath = inPath.getParentPath(); - const hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath()); - - mlvl.magic = 0xDEAFBABE; - mlvl.version = 0x11; - hecl::ProjectPath namePath = GetPathBeginsWith(dEnum, parentPath, "!name"); - if (namePath.isFile()) - mlvl.worldNameId = namePath; - hecl::ProjectPath savwPath = GetPathBeginsWith(dEnum, parentPath, "!savw"); - if (savwPath.isFile()) { - CookSAVW(savwPath.getCookedPath(SpecEntMP1), wld); - mlvl.saveWorldId = savwPath; - } - hecl::ProjectPath mapwPath = GetPathBeginsWith(dEnum, parentPath, "!mapw"); - if (mapwPath.isFile()) { - CookMAPW(mapwPath.getCookedPath(SpecEntMP1), wld); - mlvl.worldMap = mapwPath; - } - - size_t areaIdx = 0; - size_t nameStartIdx = 0; - for (const World::Area& area : wld.areas) { - if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) - continue; - - const hecl::DirectoryEnumerator areaDEnum(area.path.getAbsolutePath()); - const hecl::ProjectPath areaPath = GetPathBeginsWith(areaDEnum, area.path, "!area"); - if (!areaPath.isFile()) - continue; - - Log.report(logvisor::Info, FMT_STRING("Visiting {}"), area.path.getRelativePath()); - - hecl::ProjectPath memRelayPath(area.path, "!memoryrelays.yaml"); - - std::vector memRelays; - - if (memRelayPath.isFile()) { - athena::io::FileReader fr(memRelayPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&fr)) - r.enumerate("memrelays", memRelays); - } - - std::vector memRelayLinks; - /* Bare minimum we'll need exactly the same number of links as relays */ - memRelayLinks.reserve(memRelays.size()); - - bool areaInit = false; - size_t layerIdx = 0; - LayerResources layerResources; - const hecl::DirectoryEnumerator enumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted); - for (const hecl::DirectoryEnumerator::Entry& e : enumerator) { - std::string layerName; - char* endCh = nullptr; - hecl::StrToUl(e.m_name.c_str(), &endCh, 10); - if (!endCh) - layerName = hecl::StringUtils::TrimWhitespace(e.m_name); - else - layerName = hecl::StringUtils::TrimWhitespace(std::string(endCh)); - - hecl::ProjectPath objectsPath(area.path, e.m_name + "/!objects.yaml"); - if (objectsPath.isNone()) - continue; - - SCLY::ScriptLayer layer; - { - athena::io::FileReader freader(objectsPath.getAbsolutePath()); - if (!freader.isOpen()) - continue; - if (!athena::io::ValidateFromYAMLStream(freader)) - continue; - - athena::io::YAMLDocReader reader; - if (!reader.parse(&freader)) - continue; - - layer.read(reader); - } - - layerResources.beginLayer(); - - /* Set active flag state */ - hecl::ProjectPath defActivePath(area.path, e.m_name + "/!defaultactive"); - bool active = defActivePath.isNone() ? false : true; - - if (!areaInit) { - /* Finish last area */ - mlvl.finishLastArea(); - - /* Populate area record */ - mlvl.areas.emplace_back(); - MLVL::Area& areaOut = mlvl.areas.back(); - - namePath = GetPathBeginsWith(areaDEnum, area.path, "!name"); - if (namePath.isFile()) - areaOut.areaNameId = namePath; - - areaOut.transformMtx[0] = area.transform[0]; - areaOut.transformMtx[1] = area.transform[1]; - areaOut.transformMtx[2] = area.transform[2]; - areaOut.aabb[0] = area.aabb[0]; - areaOut.aabb[1] = area.aabb[1]; - areaOut.areaMREAId = areaPath; - areaOut.areaId = 0xffffffff; - - hecl::ProjectPath memIdPath(area.path, "!memoryid.yaml"); - if (memIdPath.isFile()) { - athena::io::FileReader fr(memIdPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&fr)) - areaOut.areaId = r.readUint32("memoryid"); - } - - /* Attached Areas and Docks */ - { - std::unordered_set addedAreas; - areaOut.dockCount = area.docks.size(); - for (const World::Area::Dock& dock : area.docks) { - areaOut.docks.emplace_back(); - MLVL::Area::Dock& dockOut = areaOut.docks.back(); - - if (dock.targetArea != UINT32_MAX && dock.targetDock != UINT32_MAX) { - dockOut.endpointCount = 1; - dockOut.endpoints.emplace_back(); - MLVL::Area::Dock::Endpoint& ep = dockOut.endpoints.back(); - ep.areaIdx = dock.targetArea; - ep.dockIdx = dock.targetDock; - - if (addedAreas.find(dock.targetArea) == addedAreas.cend()) { - addedAreas.insert(dock.targetArea); - areaOut.attachedAreas.push_back(dock.targetArea); - } - } else { - dockOut.endpointCount = 0; - } - - dockOut.planeVertCount = 4; - dockOut.planeVerts.push_back(dock.verts[0]); - dockOut.planeVerts.push_back(dock.verts[1]); - dockOut.planeVerts.push_back(dock.verts[2]); - dockOut.planeVerts.push_back(dock.verts[3]); - } - areaOut.attachedAreaCount = areaOut.attachedAreas.size(); - } - - /* Layer flags */ - mlvl.layerFlags.emplace_back(); - mlvl.layerFlags.back().layerCount = 0; - mlvl.layerFlags.back().flags = ~0; - - /* Layer name offset */ - mlvl.layerNameOffsets.push_back(nameStartIdx); - - areaInit = true; - } - - /* Gather memory relays, scans, and dependencies */ - { - g_ThreadBlenderToken.reset(&btok); - std::vector depPaths; - std::vector lazyPaths; - for (std::unique_ptr& obj : layer.objects) { - if (obj->type == int(metaforce::EScriptObjectType::MemoryRelay)) { - MemoryRelay& memRelay = static_cast(*obj); - for (IScriptObject::Connection& conn : memRelay.connections) { - MemRelayLink linkOut; - linkOut.memRelayId = memRelay.id; - linkOut.targetId = conn.target; - linkOut.msg = conn.msg; - linkOut.active = memRelay.active; - auto iter = std::find(memRelays.begin(), memRelays.end(), linkOut.memRelayId); - if (iter == memRelays.end()) { - /* We must have a new relay, let's track it */ - memRelayLinks.push_back(linkOut); - memRelays.push_back(memRelay.id); - } else { - memRelayLinks.push_back(linkOut); - } - } - } - - obj->gatherDependencies(depPaths, lazyPaths); - } - - /* Cull duplicate paths and add typed hash to list */ - for (const hecl::ProjectPath& path : depPaths) - layerResources.addPath(path, false); - for (const hecl::ProjectPath& path : lazyPaths) - layerResources.addPath(path, true); - } - - mlvl.layerNames.emplace_back(layerName); - ++nameStartIdx; - - MLVL::LayerFlags& thisLayFlags = mlvl.layerFlags.back(); - ++thisLayFlags.layerCount; - if (!active) - thisLayFlags.flags &= ~(1 << layerIdx); - - ++layerIdx; - } - - if (!areaInit) - Log.report(logvisor::Info, FMT_STRING("No layer directories for area {}"), area.path.getRelativePath()); - - /* Build deplist */ - MLVL::Area& areaOut = mlvl.areas.back(); - for (const std::vector>& layer : layerResources.layerPaths) { - areaOut.depLayers.push_back(areaOut.deps.size()); - for (const std::pair& path : layer) { - if (path.first) { - metaforce::SObjectTag tag = g_curSpec->buildTagFromPath(path.first); - if (tag.id.IsValid()) { - if (path.second) - areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type); - else - areaOut.lazyDeps.emplace_back(0, FOURCC('NONE')); - areaOut.deps.emplace_back(tag.id.Value(), tag.type); - } - } - } - } - - /* Append Memory Relays */ - if (!memRelayLinks.empty()) - mlvl.memRelayLinks.insert(mlvl.memRelayLinks.end(), memRelayLinks.begin(), memRelayLinks.end()); - - /* Cull duplicate area paths and add typed hash to list */ - auto& conn = btok.getBlenderConnection(); - if (conn.openBlend(areaPath)) { - areaOut.depLayers.push_back(areaOut.deps.size()); - - auto ds = conn.beginData(); - std::vector texs = ds.getTextures(); - ds.close(); - - for (const hecl::ProjectPath& path : texs) - layerResources.addSharedPath(path, false); - - for (const std::pair& path : layerResources.sharedPaths) { - metaforce::SObjectTag tag = g_curSpec->buildTagFromPath(path.first); - if (tag.id.IsValid()) { - if (path.second) - areaOut.lazyDeps.emplace_back(tag.id.Value(), tag.type); - else - areaOut.lazyDeps.emplace_back(0, FOURCC('NONE')); - areaOut.deps.emplace_back(tag.id.Value(), tag.type); - } - } - - hecl::ProjectPath pathPath = GetPathBeginsWith(areaDEnum, area.path, "!path"); - metaforce::SObjectTag pathTag = g_curSpec->buildTagFromPath(pathPath); - if (pathTag.id.IsValid()) { - areaOut.deps.emplace_back(pathTag.id.Value(), pathTag.type); - areaOut.lazyDeps.emplace_back(0, FOURCC('NONE')); - } - } - - ++areaIdx; - } - - /* Finish last area */ - mlvl.finishLastArea(); - - mlvl.memRelayLinkCount = mlvl.memRelayLinks.size(); - mlvl.areaCount = mlvl.areas.size(); - mlvl.layerFlagCount = mlvl.layerFlags.size(); - mlvl.layerNameCount = mlvl.layerNames.size(); - mlvl.layerNameOffsetCount = mlvl.layerNameOffsets.size(); - - /* Write out */ - { - athena::io::FileWriter fo(outPath.getAbsolutePath()); - mlvl.write(fo); - int64_t rem = fo.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - fo.writeBytes((atInt8*)"\xff", 1); - } - - return true; -} - -bool MLVL::CookMAPW(const hecl::ProjectPath& outPath, const World& wld) { - std::vector mapaTags; - mapaTags.reserve(wld.areas.size()); - - for (const World::Area& area : wld.areas) { - if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) - continue; - - /* Area map */ - hecl::ProjectPath mapPath = GetPathBeginsWith(area.path, "!map"); - if (mapPath.isFile()) - mapaTags.push_back(g_curSpec->buildTagFromPath(mapPath)); - } - - /* Write out MAPW */ - { - athena::io::FileWriter fo(outPath.getAbsolutePath()); - fo.writeUint32Big(0xDEADF00D); - fo.writeUint32Big(1); - fo.writeUint32Big(mapaTags.size()); - for (const metaforce::SObjectTag& mapa : mapaTags) - fo.writeUint32Big(u32(mapa.id.Value())); - int64_t rem = fo.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - fo.writeBytes((atInt8*)"\xff", 1); - } - - return true; -} - -bool MLVL::CookSAVW(const hecl::ProjectPath& outPath, const World& wld) { - SAVW savw = {}; - savw.header.magic = 0xC001D00D; - savw.header.version = 0x3; - std::unordered_set addedScans; - - for (const World::Area& area : wld.areas) { - if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) - continue; - - hecl::ProjectPath areaPath = GetPathBeginsWith(area.path, "!area"); - if (!areaPath.isFile()) - continue; - - hecl::ProjectPath memRelayPath(area.path, "/!memoryrelays.yaml"); - std::vector memRelays; - if (memRelayPath.isFile()) { - athena::io::FileReader fr(memRelayPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&fr)) - r.enumerate("memrelays", memRelays); - } - savw.relays.insert(savw.relays.end(), memRelays.begin(), memRelays.end()); - - for (const hecl::DirectoryEnumerator::Entry& e : - hecl::DirectoryEnumerator(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted)) { - hecl::ProjectPath objectsPath(area.path, e.m_name + "/!objects.yaml"); - if (objectsPath.isNone()) - continue; - - SCLY::ScriptLayer layer; - { - athena::io::FileReader freader(objectsPath.getAbsolutePath()); - if (!freader.isOpen()) - continue; - if (!athena::io::ValidateFromYAMLStream(freader)) - continue; - - athena::io::YAMLDocReader reader; - if (!reader.parse(&freader)) - continue; - - layer.read(reader); - } - - /* Gather memory relays, scans, and dependencies */ - { - std::vector scans; - for (std::unique_ptr& obj : layer.objects) { - if (obj->type == int(metaforce::EScriptObjectType::MemoryRelay)) { - MemoryRelay& memRelay = static_cast(*obj); - auto iter = std::find(memRelays.begin(), memRelays.end(), memRelay.id); - if (iter == memRelays.end()) { - /* We must have a new relay, let's track it */ - savw.relays.push_back(memRelay.id); - memRelays.push_back(memRelay.id); - } - } else if (obj->type == int(metaforce::EScriptObjectType::SpecialFunction)) { - SpecialFunction& specialFunc = static_cast(*obj); - if (specialFunc.function == ESpecialFunctionType::CinematicSkip) - savw.skippableCutscenes.push_back(specialFunc.id); - else if (specialFunc.function == ESpecialFunctionType::ScriptLayerController) { - savw.layers.emplace_back(); - SAVWCommon::Layer& layer = savw.layers.back(); - layer.areaId = specialFunc.layerSwitch.area; - layer.layer = specialFunc.layerSwitch.layerIdx; - } - } else if (obj->type == int(metaforce::EScriptObjectType::Door)) { - DoorArea& doorArea = static_cast(*obj); - savw.doors.push_back(doorArea.id); - } - - obj->gatherScans(scans); - } - - /* Cull duplicate scans and add to list */ - for (const Scan& scan : scans) { - if (!scan.scanId.isValid()) - continue; - if (addedScans.find(scan.scanId) == addedScans.cend()) { - addedScans.insert(scan.scanId); - hecl::ProjectPath scanPath = UniqueIDBridge::TranslatePakIdToPath(scan.scanId); - savw.scans.emplace_back(); - Scan& scanOut = savw.scans.back(); - scanOut.scanId = scan.scanId; - scanOut.category = SAVWCommon::EScanCategory(SCAN::GetCategory(scanPath)); - } - } - } - } - } - - /* Write out SAVW */ - { - savw.header.areaCount = wld.areas.size(); - savw.skippableCutsceneCount = savw.skippableCutscenes.size(); - savw.relayCount = savw.relays.size(); - savw.layerCount = savw.layers.size(); - savw.doorCount = savw.doors.size(); - savw.scanCount = savw.scans.size(); - - athena::io::FileWriter fo(outPath.getAbsolutePath()); - savw.write(fo); - int64_t rem = fo.position() % 32; - if (rem) - for (int64_t i = 0; i < 32 - rem; ++i) - fo.writeBytes((atInt8*)"\xff", 1); - } - - return true; -} - -} // namespace DNAMP1 -} // namespace DataSpec diff --git a/DataSpec/DNAMP1/MLVL.hpp b/DataSpec/DNAMP1/MLVL.hpp deleted file mode 100644 index 98dc25587..000000000 --- a/DataSpec/DNAMP1/MLVL.hpp +++ /dev/null @@ -1,148 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MLVL.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct MLVL : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - UniqueID32 worldNameId; - UniqueID32 saveWorldId; - UniqueID32 worldSkyboxId; - - Value memRelayLinkCount; - struct MemRelayLink : BigDNA { - AT_DECL_DNA_YAML - Value memRelayId; - Value targetId; - Value msg; - Value active; - }; - Vector memRelayLinks; - - Value areaCount; - Value unknown1; - struct Area : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 areaNameId; - Value transformMtx[3]; - Value aabb[2]; - UniqueID32 areaMREAId; - Value areaId; - - Value attachedAreaCount; - Vector attachedAreas; - - struct Dependency : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 id; - DNAFourCC type; - - Dependency() = default; - Dependency(const UniqueID32& idin, const hecl::FourCC& fcc) : id(idin), type(fcc) {} - }; - - Value lazyDepCount; - Vector lazyDeps; - - Value depCount; - Vector deps; - - Value depLayerCount; - Vector depLayers; - - Value dockCount; - struct Dock : BigDNA { - AT_DECL_DNA_YAML - Value endpointCount; - struct Endpoint : BigDNA { - AT_DECL_DNA_YAML - Value areaIdx; - Value dockIdx; - }; - Vector endpoints; - - Value planeVertCount; - Vector planeVerts; - }; - Vector docks; - }; - Vector areas; - - void finishLastArea() { - if (areas.size()) { - MLVL::Area& areaLast = areas.back(); - areaLast.attachedAreaCount = areaLast.attachedAreas.size(); - areaLast.lazyDepCount = areaLast.lazyDeps.size(); - areaLast.depCount = areaLast.deps.size(); - areaLast.depLayerCount = areaLast.depLayers.size(); - areaLast.dockCount = areaLast.docks.size(); - } - } - - UniqueID32 worldMap; - Value unknown2; - Value unknown3; - - Value audioGroupCount; - struct AudioGroup : BigDNA { - AT_DECL_DNA_YAML - Value groupId; - UniqueID32 agscId; - }; - Vector audioGroups; - String<-1> unkString; - - Value layerFlagCount; - struct LayerFlags : BigDNA { - AT_DECL_DNA_YAML - Value layerCount; - Value flags; - }; - Vector layerFlags; - - Value layerNameCount; - Vector, AT_DNA_COUNT(layerNameCount)> layerNames; - - Value layerNameOffsetCount; - Vector layerNameOffsets; - - void readMeta(athena::io::YAMLDocReader& __dna_docin) { - /* worldSkyboxId */ - __dna_docin.enumerate("worldSkyboxId", worldSkyboxId); - /* audioGroupCount squelched */ - /* audioGroups */ - audioGroupCount = __dna_docin.enumerate("audioGroups", audioGroups); - } - - void writeMeta(athena::io::YAMLDocWriter& __dna_docout) const { - /* worldSkyboxId */ - __dna_docout.enumerate("worldSkyboxId", worldSkyboxId); - /* audioGroupCount squelched */ - /* audioGroups */ - __dna_docout.enumerate("audioGroups", audioGroups); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged); - - static bool ExtractMAPW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - - static bool ExtractSAVW(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - - using World = hecl::blender::World; - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld, - hecl::blender::Token& btok); - - static bool CookMAPW(const hecl::ProjectPath& outPath, const World& wld); - - static bool CookSAVW(const hecl::ProjectPath& outPath, const World& wld); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MREA.cpp b/DataSpec/DNAMP1/MREA.cpp deleted file mode 100644 index d3ab74930..000000000 --- a/DataSpec/DNAMP1/MREA.cpp +++ /dev/null @@ -1,771 +0,0 @@ -#include "hecl/ClientProcess.hpp" -#include "athena/MemoryReader.hpp" -#include "MREA.hpp" -#include "SCLY.hpp" -#include "PATH.hpp" -#include "DeafBabe.hpp" -#include "DataSpec/DNACommon/BabeDead.hpp" -#include "zeus/Math.hpp" -#include "zeus/CAABox.hpp" -#include "DataSpec/DNACommon/AROTBuilder.hpp" -#include "ScriptObjects/ScriptTypes.hpp" -#include "hecl/Blender/Connection.hpp" - -#define DUMP_OCTREE 0 - -extern std::string ExeDir; - -namespace DataSpec::DNAMP1 { - -void MREA::ReadBabeDeadToBlender_1_2(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs) { - atUint32 bdMagic = rs.readUint32Big(); - if (bdMagic != 0xBABEDEAD) - Log.report(logvisor::Fatal, FMT_STRING("invalid BABEDEAD magic")); - os << "bpy.context.scene.world.use_nodes = True\n" - "bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n" - "bg_node.inputs[1].default_value = 0.0\n"; - for (atUint32 s = 0; s < 2; ++s) { - atUint32 lightCount = rs.readUint32Big(); - for (atUint32 l = 0; l < lightCount; ++l) { - BabeDeadLight light; - light.read(rs); - ReadBabeDeadLightToBlender(os, light, s, l); - } - } -} - -void MREA::AddCMDLRigPairs(PAKEntryReadStream& rs, PAKRouter& pakRouter, - CharacterAssociations& charAssoc) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* Skip to SCLY */ - atUint32 curSec = 0; - atUint64 secStart = rs.position(); - while (curSec != head.sclySecIdx) - secStart += head.secSizes[curSec++]; - rs.seek(secStart, athena::SeekOrigin::Begin); - SCLY scly; - scly.read(rs); - scly.addCMDLRigPairs(pakRouter, charAssoc); -} - -UniqueID32 MREA::GetPATHId(PAKEntryReadStream& rs) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* Skip to PATH */ - atUint32 curSec = 0; - atUint64 secStart = rs.position(); - while (curSec != head.pathSecIdx) - secStart += head.secSizes[curSec++]; - if (!head.secSizes[curSec]) - return {}; - rs.seek(secStart, athena::SeekOrigin::Begin); - return {rs}; -} - -#if DUMP_OCTREE -/* Collision octree dumper */ -static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::MemoryReader& r, BspNodeType type, - const zeus::CAABox& aabb) { - if (type == BspNodeType::Branch) { - u16 flags = r.readUint16Big(); - r.readUint16Big(); - u32 offsets[8]; - for (int i = 0; i < 8; ++i) - offsets[i] = r.readUint32Big(); - u32 dataStart = r.position(); - for (int i = 0; i < 8; ++i) { - r.seek(dataStart + offsets[i], athena::SeekOrigin::Begin); - int chFlags = (flags >> (i * 2)) & 0x3; - - zeus::CAABox pos, neg, res; - aabb.splitZ(neg, pos); - if (i & 4) { - zeus::CAABox(pos).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } - } else { - zeus::CAABox(neg).splitY(neg, pos); - if (i & 2) { - zeus::CAABox(pos).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } else { - zeus::CAABox(neg).splitX(neg, pos); - if (i & 1) - res = pos; - else - res = neg; - } - } - - OutputOctreeNode(os, r, BspNodeType(chFlags), res); - } - } else if (type == BspNodeType::Leaf) { - zeus::CVector3f pos = aabb.center(); - zeus::CVector3f extent = aabb.extents(); - os.format( - "obj = bpy.data.objects.new('Leaf', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.location = (%f,%f,%f)\n" - "obj.scale = (%f,%f,%f)\n" - "obj.empty_display_type = 'CUBE'\n" - "obj.layers[1] = True\n" - "obj.layers[0] = False\n", - pos.x, pos.y, pos.z, extent.x, extent.y, extent.z); - } -} - -static const uint32_t AROTChildCounts[] = {0, 2, 2, 4, 2, 4, 4, 8}; - -/* AROT octree dumper */ -static void OutputOctreeNode(hecl::blender::PyOutStream& os, athena::io::IStreamReader& r, const zeus::CAABox& aabb) { - r.readUint16Big(); - u16 flags = r.readUint16Big(); - if (flags) { - u32 childCount = AROTChildCounts[flags]; - r.seek(2 * childCount); - - zeus::CAABox Z[2] = {aabb}; - if ((flags & 0x4) != 0) - aabb.splitZ(Z[0], Z[1]); - for (int k = 0; k < 1 + ((flags & 0x4) != 0); ++k) { - zeus::CAABox Y[2] = {Z[k]}; - if ((flags & 0x2) != 0) - Z[k].splitY(Y[0], Y[1]); - for (int j = 0; j < 1 + ((flags & 0x2) != 0); ++j) { - zeus::CAABox X[2] = {Y[j]}; - if ((flags & 0x1) != 0) - Y[j].splitX(X[0], X[1]); - for (int i = 0; i < 1 + ((flags & 0x1) != 0); ++i) { - OutputOctreeNode(os, r, X[i]); - } - } - } - } else { - zeus::CVector3f pos = aabb.center(); - zeus::CVector3f extent = aabb.extents(); - os.format( - "obj = bpy.data.objects.new('Leaf', None)\n" - "bpy.context.scene.collection.objects.link(obj)\n" - "obj.location = (%f,%f,%f)\n" - "obj.scale = (%f,%f,%f)\n" - "obj.empty_display_type = 'CUBE'\n" - "obj.layers[1] = True\n" - "obj.layers[0] = False\n", - pos.x, pos.y, pos.z, extent.x, extent.y, extent.z); - } -} -#endif - -bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function) { - using RigPair = std::pair, std::pair>; - RigPair dummy = {}; - - if (!force && outPath.isFile()) - return true; - - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os << "import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "bpy.context.scene.render.fps = 60\n" - "\n"; - os.format(FMT_STRING("bpy.context.scene.name = '{}'\n"), pakRouter.getBestEntryName(entry, false)); - DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n" - "bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n" - "bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan " - "Visor')\n" - "bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal " - "Visor')\n" - "bpy.types.Object.retro_disable_xray_visor = bpy.props.BoolProperty(name='Retro: Disable in X-Ray Visor')\n" - "bpy.types.Object.retro_thermal_level = bpy.props.EnumProperty(items=[('COOL', 'Cool', 'Cool Temperature')," - "('HOT', 'Hot', 'Hot Temperature')," - "('WARM', 'Warm', 'Warm Temperature')]," - "name='Retro: Thermal Visor Level')\n" - "\n"; - - /* One shared material set for all meshes */ - os << "# Materials\n" - "materials = []\n" - "\n"; - MaterialSet matSet; - atUint64 secStart = rs.position(); - matSet.read(rs); - matSet.readToBlender(os, pakRouter, entry, 0); - rs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - std::vector vertAttribs; - DNACMDL::GetVertexAttributes(matSet, vertAttribs); - - /* Read meshes */ - atUint32 curSec = 1; - for (atUint32 m = 0; m < head.meshCount; ++m) { - MeshHeader mHeader; - secStart = rs.position(); - mHeader.read(rs); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - curSec += DNACMDL::ReadGeomSectionsToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_1>( - os, rs, pakRouter, entry, dummy, true, true, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec]); - os.format(FMT_STRING("obj.retro_disable_enviro_visor = {}\n" - "obj.retro_disable_thermal_visor = {}\n" - "obj.retro_disable_xray_visor = {}\n" - "obj.retro_thermal_level = '{}'\n"), - mHeader.visorFlags.disableEnviro() ? "True" : "False", - mHeader.visorFlags.disableThermal() ? "True" : "False", - mHeader.visorFlags.disableXray() ? "True" : "False", mHeader.visorFlags.thermalLevelStr()); - } - - /* Skip AROT */ - secStart = rs.position(); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Read SCLY layers */ - secStart = rs.position(); - SCLY scly; - scly.read(rs); - scly.exportToLayerDirectories(entry, pakRouter, force); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Read collision meshes */ - DeafBabe collision; - secStart = rs.position(); - collision.read(rs); - DeafBabe::BlenderInit(os); - collision.sendToBlender(os); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Skip unknown section */ - rs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Read BABEDEAD Lights as Cycles emissives */ - secStart = rs.position(); - ReadBabeDeadToBlender_1_2(os, rs); - rs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Dump VISI entities */ - secStart = rs.position(); - if (head.secSizes[curSec] && rs.readUint32Big() == 'VISI') { - { - rs.seek(secStart, athena::SeekOrigin::Begin); - auto visiData = rs.readUBytes(head.secSizes[curSec]); - athena::io::FileWriter visiOut(outPath.getWithExtension(".visi", true).getAbsolutePath()); - visiOut.writeUBytes(visiData.get(), head.secSizes[curSec]); - rs.seek(secStart + 4, athena::SeekOrigin::Begin); - } - - athena::io::YAMLDocWriter visiWriter("VISI"); - if (auto __vec = visiWriter.enterSubVector("entities")) { - rs.seek(18, athena::SeekOrigin::Current); - uint32_t entityCount = rs.readUint32Big(); - rs.seek(8, athena::SeekOrigin::Current); - for (uint32_t i = 0; i < entityCount; ++i) { - uint32_t entityId = rs.readUint32Big(); - visiWriter.writeUint32(entityId); - } - } - hecl::ProjectPath visiMetadataPath(outPath.getParentPath(), "!visi.yaml"); - athena::io::FileWriter visiMetadata(visiMetadataPath.getAbsolutePath()); - visiWriter.finish(&visiMetadata); - } - - /* Origins to center of mass */ - os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n" - "bpy.ops.object.select_by_type(type='MESH')\n" - "bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n" - "bpy.ops.object.select_all(action='DESELECT')\n" - "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n"; - - /* Link MLVL scene as background */ - os.linkBackground(fmt::format(FMT_STRING("//../!world_{}.blend"), pakRouter.getCurrentBridge().getLevelId()), - "World"sv); - - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -void MREA::Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, PAK::Entry& entry) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* One shared material set for all meshes */ - atUint64 secStart = rs.position(); - MaterialSet matSet; - matSet.read(rs); - matSet.nameTextures(pakRouter, fmt::format(FMT_STRING("MREA_{}"), entry.id).c_str(), -1); - rs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - - /* Skip to SCLY */ - atUint32 curSec = 1; - secStart = rs.position(); - while (curSec != head.sclySecIdx) - secStart += head.secSizes[curSec++]; - rs.seek(secStart, athena::SeekOrigin::Begin); - SCLY scly; - scly.read(rs); - scly.nameIDs(pakRouter); - - /* Skip to PATH */ - while (curSec != head.pathSecIdx) - secStart += head.secSizes[curSec++]; - rs.seek(secStart, athena::SeekOrigin::Begin); - - UniqueID32 pathID(rs); - const nod::Node* node; - PAK::Entry* pathEnt = (PAK::Entry*)pakRouter.lookupEntry(pathID, &node); - pathEnt->name = entry.name + "_path"; -} - -void MREA::MeshHeader::VisorFlags::setFromBlenderProps(const std::unordered_map& props) { - auto search = props.find("retro_disable_enviro_visor"); - if (search != props.cend() && search->second == "1") - setDisableEnviro(true); - search = props.find("retro_disable_thermal_visor"); - if (search != props.cend() && search->second == "1") - setDisableThermal(true); - search = props.find("retro_disable_xray_visor"); - if (search != props.cend() && search->second == "1") - setDisableXray(true); - search = props.find("retro_thermal_level"); - if (search != props.cend()) { - if (search->second == "0") - setThermalLevel(ThermalLevel::Cool); - else if (search->second == "1") - setThermalLevel(ThermalLevel::Hot); - else if (search->second == "2") - setThermalLevel(ThermalLevel::Warm); - } -} - -bool MREA::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const std::vector& meshes, const ColMesh& cMesh, const std::vector& lights, - hecl::blender::Token& btok, const hecl::blender::Matrix4f* xf, bool pc) { - /* Discover area layers */ - hecl::ProjectPath areaDirPath = inPath.getParentPath(); - std::vector layerScriptPaths; - { - hecl::DirectoryEnumerator dEnum(inPath.getParentPath().getAbsolutePath(), - hecl::DirectoryEnumerator::Mode::DirsSorted, false, false, true); - for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) { - hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + "/!objects.yaml"); - if (layerScriptPath.isFile()) - layerScriptPaths.push_back(std::move(layerScriptPath)); - } - } - - size_t secCount = 1 + meshes.size() * (pc ? 5 : 7); /* (materials, 5/7 fixed model secs) */ - - /* tally up surfaces */ - for (const DNACMDL::Mesh& mesh : meshes) - secCount += mesh.surfaces.size(); - - /* Header */ - Header head = {}; - head.magic = 0xDEADBEEF; - head.version = pc ? 0x1000F : 0xF; - if (xf) { - head.localToWorldMtx[0] = xf->val[0]; - head.localToWorldMtx[1] = xf->val[1]; - head.localToWorldMtx[2] = xf->val[2]; - } else { - head.localToWorldMtx[0].simd[0] = 1.f; - head.localToWorldMtx[1].simd[1] = 1.f; - head.localToWorldMtx[2].simd[2] = 1.f; - } - head.meshCount = meshes.size(); - head.geomSecIdx = 0; - head.arotSecIdx = secCount++; - head.sclySecIdx = secCount++; - head.collisionSecIdx = secCount++; - head.unkSecIdx = secCount++; - head.lightSecIdx = secCount++; - head.visiSecIdx = secCount++; - head.pathSecIdx = secCount++; - head.secCount = secCount; - - std::vector> secs; - secs.reserve(secCount + 2); - - /* Header section */ - { - size_t secSz = 0; - head.binarySize(secSz); - secs.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - head.write(w); - int i = w.position(); - int end = ROUND_UP_32(i); - for (; i < end; ++i) - w.writeByte(0); - } - - /* Sizes section */ - secs.emplace_back(); - - /* Pre-emptively build full AABB and mesh AABBs in world coords */ - zeus::CAABox fullAabb; - std::vector meshAabbs; - meshAabbs.reserve(meshes.size()); - - /* Models */ - if (pc) { - if (!DNACMDL::WriteHMDLMREASecs(secs, inPath, meshes, - fullAabb, meshAabbs)) - return false; - } else { - if (!DNACMDL::WriteMREASecs(secs, inPath, meshes, fullAabb, - meshAabbs)) - return false; - } - - /* AROT */ - { - AROTBuilder arotBuilder; - arotBuilder.build(secs, fullAabb, meshAabbs, meshes); - -#if DUMP_OCTREE - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(inPath.getWithExtension(".octree.blend", true), hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format( - "import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '%s'\n", - inPath.getLastComponent().data()); - - athena::io::MemoryReader reader(secs.back().data(), secs.back().size()); - reader.readUint32Big(); - reader.readUint32Big(); - u32 numMeshBitmaps = reader.readUint32Big(); - u32 meshBitCount = reader.readUint32Big(); - u32 numNodes = reader.readUint32Big(); - auto aabbMin = reader.readVec3fBig(); - auto aabbMax = reader.readVec3fBig(); - reader.seekAlign32(); - reader.seek(ROUND_UP_32(meshBitCount) / 8 * numMeshBitmaps + numNodes * 4); - zeus::CAABox arotAABB(aabbMin, aabbMax); - OutputOctreeNode(os, reader, arotAABB); - - os.centerView(); - os.close(); - conn.saveBlend(); -#endif - } - - /* SCLY */ - DNAMP1::SCLY sclyData = {}; - { - sclyData.fourCC = FOURCC('SCLY'); - sclyData.version = 1; - for (const hecl::ProjectPath& layer : layerScriptPaths) { - athena::io::FileReader freader(layer.getAbsolutePath()); - if (!freader.isOpen()) - continue; - if (!athena::io::ValidateFromYAMLStream(freader)) - continue; - - athena::io::YAMLDocReader reader; - if (!reader.parse(&freader)) - continue; - - sclyData.layers.emplace_back(); - sclyData.layers.back().read(reader); - size_t layerSize = 0; - sclyData.layers.back().binarySize(layerSize); - sclyData.layerSizes.push_back(layerSize); - } - sclyData.layerCount = sclyData.layers.size(); - - size_t secSz = 0; - sclyData.binarySize(secSz); - secs.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - sclyData.write(w); - } - - /* Collision */ - { - DeafBabe collision = {}; - DeafBabeBuildFromBlender(collision, cMesh); - -#if DUMP_OCTREE - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(inPath.getWithExtension(".coctree.blend", true), hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format( - "import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '%s'\n", - inPath.getLastComponent().data()); - - athena::io::MemoryReader reader(collision.bspTree.get(), collision.bspSize); - zeus::CAABox colAABB(collision.aabb[0], collision.aabb[1]); - OutputOctreeNode(os, reader, collision.rootNodeType, colAABB); - - os.centerView(); - os.close(); - conn.saveBlend(); -#endif - - size_t secSz = 0; - collision.binarySize(secSz); - secs.emplace_back(secSz, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - collision.write(w); - } - - /* Unk */ - { - secs.emplace_back(8, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - w.writeUint32Big(1); - } - - /* Lights */ - std::vector lightsVisi[2]; - { - int actualCounts[2] = {}; - for (const Light& l : lights) - if (l.layer == 0 || l.layer == 1) - ++actualCounts[l.layer]; - lightsVisi[0].reserve(actualCounts[0]); - lightsVisi[1].reserve(actualCounts[1]); - - secs.emplace_back(12 + 65 * (actualCounts[0] + actualCounts[1]), 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - w.writeUint32Big(0xBABEDEAD); - - for (uint32_t lay = 0; lay < 2; ++lay) { - int lightCount = 0; - for (const Light& l : lights) { - if (l.layer == lay) - ++lightCount; - } - w.writeUint32Big(lightCount); - for (const Light& l : lights) { - if (l.layer == lay) { - BabeDeadLight light = {}; - WriteBabeDeadLightFromBlender(light, l); - light.write(w); - lightsVisi[l.layer].push_back(light.position); - } - } - } - } - - /* VISI */ - hecl::ProjectPath visiMetadataPath(areaDirPath, "!visi.yaml"); - bool visiGood = false; - if (visiMetadataPath.isFile()) { - athena::io::FileReader visiReader(visiMetadataPath.getAbsolutePath()); - athena::io::YAMLDocReader r; - if (r.parse(&visiReader)) { - size_t entityCount; - std::vector> entities; - if (auto __vec = r.enterSubVector("entities", entityCount)) { - entities.reserve(entityCount); - for (size_t i = 0; i < entityCount; ++i) { - uint32_t entityId = r.readUint32(); - for (const SCLY::ScriptLayer& layer : sclyData.layers) { - for (const std::unique_ptr& obj : layer.objects) { - if ((obj->id & ~0x03FF0000) == entityId) { - zeus::CAABox entAABB = obj->getVISIAABB(btok); - if (!entAABB.invalid()) - entities.emplace_back(entityId, entAABB); - } - } - } - } - } - - // Check if pre-generated visi exists, recycle if able - hecl::ProjectPath preVisiPath = inPath.getWithExtension(".visi", true); - if (preVisiPath.getPathType() == hecl::ProjectPath::Type::File) { - athena::io::FileReader preVisiReader(preVisiPath.getAbsolutePath()); - atUint64 preVisiLen = preVisiReader.length(); - if (preVisiLen > 26) { - auto preVisiData = preVisiReader.readUBytes(preVisiLen); - athena::io::MemoryReader preVisiDataReader(preVisiData.get(), preVisiLen); - - atUint32 preVisiFourCC = preVisiDataReader.readUint32Big(); - atUint32 preVisiVersion = preVisiDataReader.readUint32Big(); - preVisiDataReader.readBool(); - preVisiDataReader.readBool(); - atUint32 preFeatureCount = preVisiDataReader.readUint32Big(); - atUint32 preLightsCount = preVisiDataReader.readUint32Big(); - atUint32 preLayer2LightCount = preVisiDataReader.readUint32Big(); - atUint32 preEntityCount = preVisiDataReader.readUint32Big(); - - if (preVisiFourCC == 'VISI' && preVisiVersion == 2 && preFeatureCount == meshes.size() + entities.size() && - preLightsCount == lightsVisi[0].size() + lightsVisi[1].size() && - preLayer2LightCount == lightsVisi[1].size() && preEntityCount == entities.size()) { - secs.emplace_back(preVisiLen, 0); - memcpy(secs.back().data(), preVisiData.get(), preVisiLen); - visiGood = true; - } else { - // TODO: Fix visigen and remove this hack - secs.emplace_back(preVisiLen, 0); - memcpy(secs.back().data(), preVisiData.get(), preVisiLen); - visiGood = true; - } - } - } -// TODO: fix visigen so this can be re-enabled -#if 0 -#if !WINDOWS_STORE - if (!visiGood) { - hecl::ProjectPath visiIntOut = outPath.getWithExtension(".visiint"); - athena::io::FileWriter w(visiIntOut.getAbsolutePath()); - w.writeUint32Big(meshes.size()); - for (const DNACMDL::Mesh& mesh : meshes) { - w.writeUint32Big(uint32_t(mesh.topology)); - - w.writeUint32Big(mesh.pos.size()); - for (const auto& v : mesh.pos) { - atVec3f xfPos = hecl::blender::MtxVecMul4RM(mesh.sceneXf, v); - w.writeVec3fBig(xfPos); - } - - w.writeUint32Big(mesh.surfaces.size()); - for (const DNACMDL::Mesh::Surface& surf : mesh.surfaces) { - w.writeUint32Big(surf.verts.size()); - for (const DNACMDL::Mesh::Surface::Vert& vert : surf.verts) - w.writeUint32Big(vert.iPos); - const DNACMDL::Material& mat = mesh.materialSets[0][surf.materialIdx]; - w.writeBool(mat.blendMode != DNACMDL::Material::BlendMode::Opaque); - } - } - - w.writeUint32Big(entities.size()); - for (const auto& ent : entities) { - w.writeUint32Big(ent.first); - w.writeVec3fBig(ent.second.min); - w.writeVec3fBig(ent.second.max); - } - - w.writeUint32Big(lightsVisi[0].size() + lightsVisi[1].size()); - w.writeUint32Big(lightsVisi[1].size()); - for (const auto& light : lightsVisi[1]) - w.writeVec3fBig(light); - for (const auto& light : lightsVisi[0]) - w.writeVec3fBig(light); - - w.close(); - - std::string VisiGenPath = ExeDir + "/visigen"; -#if _WIN32 - VisiGenPath += ".exe"; -#endif - std::string thrIdx = fmt::format(FMT_STRING("{}"), hecl::ClientProcess::GetThreadWorkerIdx()); - std::string parPid; -#if _WIN32 - parPid = fmt::format(FMT_STRING("{}"), reinterpret_cast(GetCurrentProcess())); -#else - parPid = fmt::format(FMT_STRING("{}"), (unsigned long long)getpid()); -#endif - const char* args[] = {VisiGenPath.c_str(), - visiIntOut.getAbsolutePath().data(), - preVisiPath.getAbsolutePath().data(), - thrIdx.c_str(), - parPid.c_str(), - nullptr}; - if (0 == hecl::RunProcess(VisiGenPath.c_str(), args)) { - athena::io::FileReader r(preVisiPath.getAbsolutePath()); - size_t length = r.length(); - secs.emplace_back(length, 0); - r.readBytesToBuf(secs.back().data(), length); - visiGood = true; - } else { - Log.report(logvisor::Fatal, FMT_STRING("Unable to launch {}"), VisiGenPath); - } - } -#endif -#endif - } - } - if (!visiGood) - secs.emplace_back(4, 0); - - /* PATH */ - { - const hecl::ProjectPath pathPath = GetPathBeginsWith(inPath.getParentPath(), "!path"); - UniqueID32 pathId; - if (pathPath.isFile()) - pathId = pathPath; - secs.emplace_back(4, 0); - athena::io::MemoryWriter w(secs.back().data(), secs.back().size()); - pathId.write(w); - } - - /* Assemble sizes and add padding */ - { - std::vector& sizesSec = secs[1]; - sizesSec.assign((((head.secCount) + 7) & ~7) * 4, 0); - athena::io::MemoryWriter w(sizesSec.data(), sizesSec.size()); - for (auto it = secs.begin() + 2; it != secs.end(); ++it) { - std::vector& sec = *it; - int i = sec.size(); - int end = ROUND_UP_32(i); - sec.resize(end); - w.writeUint32Big(end); - } - } - - /* Output all padded sections to file */ - athena::io::FileWriter writer(outPath.getAbsolutePath()); - for (const std::vector& sec : secs) - writer.writeUBytes(sec.data(), sec.size()); - - return true; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MREA.hpp b/DataSpec/DNAMP1/MREA.hpp deleted file mode 100644 index d0c0b46e5..000000000 --- a/DataSpec/DNAMP1/MREA.hpp +++ /dev/null @@ -1,113 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CMDLMaterials.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP1 { - -struct MREA { - struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - Value localToWorldMtx[3]; - Value meshCount; - Value secCount; - Value geomSecIdx; - Value sclySecIdx; - Value collisionSecIdx; - Value unkSecIdx; - Value lightSecIdx; - Value visiSecIdx; - Value pathSecIdx; - Value arotSecIdx; - Vector secSizes; - }; - - struct MeshHeader : BigDNA { - AT_DECL_DNA - struct VisorFlags : BigDNA { - AT_DECL_DNA - Value flags; - enum class ThermalLevel { Cool, Hot, Warm }; - static const char* GetThermalLevelStr(ThermalLevel t) { - switch (t) { - case ThermalLevel::Cool: - return "COOL"; - case ThermalLevel::Hot: - return "HOT"; - case ThermalLevel::Warm: - return "WARM"; - default: - break; - } - return nullptr; - } - bool disableEnviro() const { return flags >> 1 & 0x1; } - void setDisableEnviro(bool v) { - flags &= ~0x2; - flags |= v << 1; - } - bool disableThermal() const { return flags >> 2 & 0x1; } - void setDisableThermal(bool v) { - flags &= ~0x4; - flags |= v << 2; - } - bool disableXray() const { return flags >> 3 & 0x1; } - void setDisableXray(bool v) { - flags &= ~0x8; - flags |= v << 3; - } - ThermalLevel thermalLevel() const { return ThermalLevel(flags >> 4 & 0x3); } - void setThermalLevel(ThermalLevel v) { - flags &= ~0x30; - flags |= atUint32(v) << 4; - } - const char* thermalLevelStr() const { return GetThermalLevelStr(thermalLevel()); } - void setFromBlenderProps(const std::unordered_map& props); - } visorFlags; - Value xfMtx[3]; - Value aabb[2]; - }; - - struct BabeDeadLight : BigDNA { - AT_DECL_DNA - enum class LightType : atUint32 { LocalAmbient, Directional, Custom, Spot, Spot2, LocalAmbient2 }; - enum class Falloff : atUint32 { Constant, Linear, Quadratic }; - Value lightType; - Value color; - Value position; - Value direction; - Value q; - Value spotCutoff; - Value unk5; - Value castShadows; - Value unk7; - Value falloff; - Value unk9; - }; - - static void ReadBabeDeadToBlender_1_2(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs); - - static void AddCMDLRigPairs(PAKEntryReadStream& rs, PAKRouter& pakRouter, - CharacterAssociations& charAssoc); - - static UniqueID32 GetPATHId(PAKEntryReadStream& rs); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function); - - static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, - PAK::Entry& entry); - - using ColMesh = hecl::blender::ColMesh; - using Light = hecl::blender::Light; - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const std::vector& meshes, const ColMesh& cMesh, const std::vector& lights, - hecl::blender::Token& btok, const hecl::blender::Matrix4f* xf, bool pc); -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/MazeSeeds.hpp b/DataSpec/DNAMP1/MazeSeeds.hpp deleted file mode 100644 index d3826b357..000000000 --- a/DataSpec/DNAMP1/MazeSeeds.hpp +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include - -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct MazeSeeds : BigDNA { - AT_DECL_DNA_YAML - Value seeds[300]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/PAK.cpp b/DataSpec/DNAMP1/PAK.cpp deleted file mode 100644 index 2c00da70d..000000000 --- a/DataSpec/DNAMP1/PAK.cpp +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include "DNAMP1.hpp" -#include "PAK.hpp" -#include "AGSC.hpp" -#include "DataSpec/AssetNameMap.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void PAK::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - if (version != 0x00030005) - Log.report(logvisor::Fatal, FMT_STRING("unexpected PAK magic")); - reader.readUint32Big(); - - atUint32 nameCount = reader.readUint32Big(); - m_nameEntries.clear(); - m_nameEntries.reserve(nameCount); - for (atUint32 n = 0; n < nameCount; ++n) { - m_nameEntries.emplace_back(); - m_nameEntries.back().read(reader); - } - - atUint32 count = reader.readUint32Big(); - m_entries.clear(); - m_entries.reserve(count); - m_firstEntries.clear(); - m_firstEntries.reserve(count); - std::vector entries; - entries.reserve(count); - for (atUint32 e = 0; e < count; ++e) { - entries.emplace_back(); - entries.back().read(reader); - } - for (atUint32 e = 0; e < count; ++e) { - Entry& entry = entries[e]; - if (entry.compressed && m_useLzo) - entry.compressed = 2; - - auto search = m_entries.find(entry.id); - if (search == m_entries.end()) { - m_firstEntries.push_back(entry.id); - m_entries[entry.id] = std::move(entry); - } else { - /* Find next MREA to record which area has dupes */ - for (atUint32 e2 = e + 1; e2 < count; ++e2) { - Entry& entry2 = entries[e2]; - if (entry2.type != FOURCC('MREA')) - continue; - m_dupeMREAs.insert(entry2.id); - break; - } - } - } - - m_nameMap.clear(); - m_nameMap.reserve(nameCount); - for (NameEntry& entry : m_nameEntries) - m_nameMap[entry.name] = entry.id; -} - -template <> -void PAK::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(0x00030005); - writer.writeUint32Big(0); - - writer.writeUint32Big((atUint32)m_nameEntries.size()); - for (const NameEntry& entry : m_nameEntries) { - NameEntry copy = entry; - copy.nameLen = copy.name.size(); - copy.write(writer); - } - - writer.writeUint32Big(m_entries.size()); - for (const auto& entry : m_entries) { - Entry tmp = entry.second; - if (tmp.compressed) - tmp.compressed = 1; - tmp.write(writer); - } -} - -template <> -void PAK::Enumerate(typename BinarySize::StreamT& s) { - s += 12; - - for (const NameEntry& entry : m_nameEntries) - s += 12 + entry.name.size(); - - s += m_entries.size() * 20 + 4; -} - -std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& szOut) const { - if (compressed) { - std::unique_ptr strm = pak.beginReadStream(offset); - - atUint32 decompSz; - strm->read(&decompSz, 4); - decompSz = hecl::SBig(decompSz); - std::unique_ptr buf{new atUint8[decompSz]}; - atUint8* bufCur = buf.get(); - - atUint8 compBuf[0x8000]; - if (compressed == 1) { - atUint32 compRem = size - 4; - z_stream zs = {}; - inflateInit(&zs); - zs.avail_out = decompSz; - zs.next_out = buf.get(); - while (zs.avail_out) { - atUint64 readSz = strm->read(compBuf, std::min(compRem, atUint32(0x8000))); - compRem -= readSz; - zs.avail_in = readSz; - zs.next_in = compBuf; - inflate(&zs, Z_FINISH); - } - inflateEnd(&zs); - } else { - atUint32 rem = decompSz; - while (rem) { - atUint16 chunkSz; - strm->read(&chunkSz, 2); - chunkSz = hecl::SBig(chunkSz); - strm->read(compBuf, chunkSz); - size_t dsz; - lzokay::decompress(compBuf, chunkSz, bufCur, rem, dsz); - bufCur += dsz; - rem -= dsz; - } - } - - szOut = decompSz; - return buf; - } else { - std::unique_ptr buf{new atUint8[size]}; - pak.beginReadStream(offset)->read(buf.get(), size); - szOut = size; - return buf; - } -} - -const PAK::Entry* PAK::lookupEntry(const UniqueID32& id) const { - auto result = m_entries.find(id); - if (result != m_entries.end()) - return &result->second; - return nullptr; -} - -const PAK::Entry* PAK::lookupEntry(std::string_view name) const { - // TODO: Heterogeneous lookup when C++20 available - auto result = m_nameMap.find(name.data()); - if (result != m_nameMap.end()) { - auto result1 = m_entries.find(result->second); - if (result1 != m_entries.end()) - return &result1->second; - } - return nullptr; -} - -std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const { - std::unordered_map::const_iterator search; - if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) { - /* Use internal AGSC name for entry */ - auto rs = search->second.beginReadStream(pakNode); - AGSC::Header header; - header.read(rs); - catalogueName = header.groupName; - return fmt::format(FMT_STRING("{}_{}"), header.groupName, entry.id); - } - - /* Prefer named entries first */ - for (const NameEntry& nentry : m_nameEntries) { - if (nentry.id == entry.id) { - catalogueName = nentry.name; - return fmt::format(FMT_STRING("{}_{}"), nentry.name, entry.id); - } - } - - /* Prefer asset name map second */ - if (const auto* name = AssetNameMap::TranslateIdToName(entry.id)) { - return fmt::format(FMT_STRING("{}_{}"), *name, entry.id); - } - - /* Otherwise return ID format string */ - return fmt::format(FMT_STRING("{}_{}"), entry.type, entry.id); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/PAK.hpp b/DataSpec/DNAMP1/PAK.hpp deleted file mode 100644 index 0d2362ad6..000000000 --- a/DataSpec/DNAMP1/PAK.hpp +++ /dev/null @@ -1,57 +0,0 @@ -#pragma once - -#include - -#include -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAMP1 { - -struct PAK : BigDNA { - bool m_useLzo; - bool m_noShare; - PAK(bool useLzo, bool noShare) : m_useLzo(useLzo), m_noShare(noShare) {} - AT_DECL_EXPLICIT_DNA - - struct NameEntry : BigDNA { - AT_DECL_DNA - DNAFourCC type; - UniqueID32 id; - Value nameLen; - String name; - }; - - struct Entry : BigDNA { - AT_DECL_DNA - Value compressed; - DNAFourCC type; - UniqueID32 id; - Value size; - Value offset; - UniqueResult unique; - std::string name; /* backreferencing name for RE purposes */ - - std::unique_ptr getBuffer(const nod::Node& pak, atUint64& szOut) const; - inline PAKEntryReadStream beginReadStream(const nod::Node& pak, atUint64 off = 0) const { - atUint64 sz; - std::unique_ptr buf = getBuffer(pak, sz); - return PAKEntryReadStream(std::move(buf), sz, off); - } - }; - - std::vector m_nameEntries; - std::unordered_map m_entries; - std::vector m_firstEntries; - std::unordered_map m_nameMap; - std::unordered_set m_dupeMREAs; - - const Entry* lookupEntry(const UniqueID32& id) const; - const Entry* lookupEntry(std::string_view name) const; - std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const; - - bool mreaHasDupeResources(const UniqueID32& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); } - - using IDType = UniqueID32; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/PATH.hpp b/DataSpec/DNAMP1/PATH.hpp deleted file mode 100644 index 07f0179f8..000000000 --- a/DataSpec/DNAMP1/PATH.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "DataSpec/DNACommon/PATH.hpp" - -namespace DataSpec::DNAMP1 { -using PATH = DNAPATH::PATH; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SAVW.hpp b/DataSpec/DNAMP1/SAVW.hpp deleted file mode 100644 index 54e52bbaf..000000000 --- a/DataSpec/DNAMP1/SAVW.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/SAVWCommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct Scan : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 scanId; - Value category; - - Scan() = default; - Scan(const UniqueID32& id) : scanId(id), category(SAVWCommon::EScanCategory::None) {} -}; - -struct SAVW : BigDNA { - AT_DECL_DNA_YAML - SAVWCommon::Header header; - Value skippableCutsceneCount; - Vector skippableCutscenes; - Value relayCount; - Vector relays; - Value layerCount; - Vector layers; - Value doorCount; - Vector doors; - Value scanCount; - Vector scans; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCAN.cpp b/DataSpec/DNAMP1/SCAN.cpp deleted file mode 100644 index 5fa82ce7c..000000000 --- a/DataSpec/DNAMP1/SCAN.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "SCAN.hpp" - -#include -#include - -namespace DataSpec::DNAMP1 { - -constexpr std::array PaneNames{ - "imagepane_pane0"sv, "imagepane_pane1"sv, "imagepane_pane2"sv, "imagepane_pane3"sv, "imagepane_pane01"sv, - "imagepane_pane12"sv, "imagepane_pane23"sv, "imagepane_pane012"sv, "imagepane_pane123"sv, "imagepane_pane0123"sv, - "imagepane_pane4"sv, "imagepane_pane5"sv, "imagepane_pane6"sv, "imagepane_pane7"sv, "imagepane_pane45"sv, - "imagepane_pane56"sv, "imagepane_pane67"sv, "imagepane_pane456"sv, "imagepane_pane567"sv, "imagepane_pane4567"sv, -}; - -template <> -void SCAN::Texture::Enumerate(typename Read::StreamT& r) { - texture.read(r); - appearanceRange = r.readFloatBig(); - position = Position(r.readUint32Big()); - width = r.readUint32Big(); - height = r.readUint32Big(); - interval = r.readFloatBig(); - fadeDuration = r.readFloatBig(); -} - -template <> -void SCAN::Texture::Enumerate(typename Write::StreamT& w) { - texture.write(w); - w.writeFloatBig(appearanceRange); - w.writeUint32Big(atUint32(position)); - w.writeUint32Big(width); - w.writeUint32Big(height); - w.writeFloatBig(interval); - w.writeFloatBig(fadeDuration); -} - -template <> -void SCAN::Texture::Enumerate(typename ReadYaml::StreamT& r) { - r.enumerate("texture", texture); - appearanceRange = r.readFloat("appearanceRange"); - std::string tmp = r.readString("position"); - - auto idx = std::find(PaneNames.begin(), PaneNames.end(), tmp); - if (idx != PaneNames.end()) - position = Position(idx - PaneNames.begin()); - else - position = Position::Invalid; - - width = r.readUint32("width"); - height = r.readUint32("height"); - interval = r.readFloat("interval"); - fadeDuration = r.readFloat("fadeDuration"); -} - -template <> -void SCAN::Texture::Enumerate(typename WriteYaml::StreamT& w) { - w.enumerate("texture", texture); - w.writeFloat("appearanceRange", appearanceRange); - if (position != Position::Invalid) - w.writeString("position", PaneNames.at(atUint32(position))); - else - w.writeString("position", "undefined"); - w.writeUint32("width", width); - w.writeUint32("height", height); - w.writeFloat("interval", interval); - w.writeFloat("fadeDuration", fadeDuration); -} - -std::string_view SCAN::Texture::DNAType() { return "DNAMP1::SCAN::Texture"sv; } - -template <> -void SCAN::Texture::Enumerate(typename BinarySize::StreamT& s) { - texture.binarySize(s); - s += 24; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCAN.hpp b/DataSpec/DNAMP1/SCAN.hpp deleted file mode 100644 index f806fe69d..000000000 --- a/DataSpec/DNAMP1/SCAN.hpp +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct SCAN : BigDNA { - AT_DECL_DNA_YAML - Value version; - Value magic; - UniqueID32 frame; - UniqueID32 string; - - enum class ScanSpeed : atUint32 { Normal, Slow }; - Value scanSpeed; - - enum class Category : atUint32 { None, SpacePirateData, ChozoLore, Creatures, Research }; - - Value category; - - Value isImportant; - - struct Texture : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - UniqueID32 texture; - Value appearanceRange; - enum class Position : atInt32 { - Pane0, - Pane1, - Pane2, - Pane3, - Pane01, - Pane12, - Pane23, - Pane012, - Pane123, - Pane0123, - Pane4, - Pane5, - Pane6, - Pane7, - Pane45, - Pane56, - Pane67, - Pane456, - Pane567, - Pane4567, - Invalid = -1 - }; - Value position; - Value width; // width of animation cell - Value height; // height of animation cell - Value interval; // 0.0 - 1.0 - Value fadeDuration; // 0.0 - 1.0 - }; - - Texture textures[4]; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - SCAN scan; - scan.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(scan, writer); - return true; - } - - static bool Cook(const SCAN& scan, const hecl::ProjectPath& outPath) { - athena::io::FileWriter ws(outPath.getAbsolutePath()); - scan.write(ws); - return true; - } - - static Category GetCategory(const hecl::ProjectPath& inPath) { - SCAN scan; - athena::io::FileReader reader(inPath.getAbsolutePath()); - if (reader.hasError()) - return Category::None; - if (!athena::io::FromYAMLStream(scan, reader)) - return Category::None; - return scan.category; - } - - static void Name(const SpecBase& dataSpec, PAKEntryReadStream& rs, PAKRouter& pakRouter, - PAK::Entry& entry) { - SCAN scan; - scan.read(rs); - if (scan.string.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(scan.string); - ent->name = fmt::format(FMT_STRING("SCAN_{}_strg"), entry.id); - } - for (int i = 0; i < 4; ++i) { - const Texture& tex = scan.textures[i]; - if (tex.texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(tex.texture); - ent->name = fmt::format(FMT_STRING("SCAN_{}_tex{}"), entry.id, i + 1); - } - } - } - - void gatherDependencies(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(frame, pathsOut); - g_curSpec->flattenDependencies(string, pathsOut); - for (int i = 0; i < 4; ++i) - g_curSpec->flattenDependencies(textures[i].texture, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCLY.cpp b/DataSpec/DNAMP1/SCLY.cpp deleted file mode 100644 index 8ac610788..000000000 --- a/DataSpec/DNAMP1/SCLY.cpp +++ /dev/null @@ -1,198 +0,0 @@ -#include "SCLY.hpp" -#include "ScriptObjects/ScriptTypes.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void SCLY::Enumerate(athena::io::IStreamReader& rs) { - fourCC.read(rs); - version = rs.readUint32Big(); - layerCount = rs.readUint32Big(); - rs.enumerateBig(layerSizes, layerCount); - atUint32 i = 0; - rs.enumerate(layers, layerCount, [&i, this](athena::io::IStreamReader& rs, ScriptLayer& layer) { - atUint64 start = rs.position(); - layer.read(rs); - rs.seek(start + layerSizes[i++], athena::SeekOrigin::Begin); - }); -} - -template <> -void SCLY::Enumerate(athena::io::IStreamWriter& ws) { - fourCC.write(ws); - ws.writeUint32Big(version); - ws.writeUint32Big(layerCount); - ws.enumerateBig(layerSizes); - ws.enumerate(layers); -} - -template <> -void SCLY::Enumerate(size_t& __isz) { - __isz += 12; - __isz += layerSizes.size() * 4; - for (const ScriptLayer& layer : layers) - layer.binarySize(__isz); -} - -void SCLY::exportToLayerDirectories(const PAK::Entry& entry, PAKRouter& pakRouter, bool force) const { - for (atUint32 i = 0; i < layerCount; i++) { - bool active; - hecl::ProjectPath layerPath = pakRouter.getAreaLayerWorking(entry.id, i, active); - if (layerPath.isNone()) - layerPath.makeDirChain(true); - - if (active) { - const hecl::ProjectPath activePath(layerPath, "!defaultactive"); - [[maybe_unused]] const auto fp = hecl::FopenUnique(activePath.getAbsolutePath().data(), "wb"); - } - - hecl::ProjectPath yamlFile(layerPath, "!objects.yaml"); - if (force || yamlFile.isNone()) { - athena::io::FileWriter writer(yamlFile.getAbsolutePath()); - athena::io::ToYAMLStream(layers[i], writer); - } - } -} - -void SCLY::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const ScriptLayer& layer : layers) - layer.addCMDLRigPairs(pakRouter, charAssoc); -} - -void SCLY::ScriptLayer::addCMDLRigPairs(PAKRouter& pakRouter, - CharacterAssociations& charAssoc) const { - for (const std::unique_ptr& obj : objects) - obj->addCMDLRigPairs(pakRouter, charAssoc); -} - -void SCLY::nameIDs(PAKRouter& pakRouter) const { - for (const ScriptLayer& layer : layers) - layer.nameIDs(pakRouter); -} - -void SCLY::ScriptLayer::nameIDs(PAKRouter& pakRouter) const { - for (const std::unique_ptr& obj : objects) - obj->nameIDs(pakRouter); -} - -template <> -void SCLY::Enumerate(athena::io::YAMLDocReader& docin) { - Do(athena::io::PropId{"fourCC"}, fourCC, docin); - version = docin.readUint32("version"); - layerCount = docin.enumerate("layerSizes", layerSizes); - docin.enumerate("layers", layers); -} - -template <> -void SCLY::Enumerate(athena::io::YAMLDocWriter& docout) { - Do(athena::io::PropId{"fourCC"}, fourCC, docout); - docout.writeUint32("version", version); - docout.enumerate("layerSizes", layerSizes); - docout.enumerate("layers", layers); -} - -std::string_view SCLY::DNAType() { return "DNAMP1::SCLY"sv; } - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::IStreamReader& rs) { - unknown = rs.readUByte(); - objectCount = rs.readUint32Big(); - objects.clear(); - objects.reserve(objectCount); - for (atUint32 i = 0; i < objectCount; i++) { - atUint8 type = rs.readUByte(); - atUint32 len = rs.readUint32Big(); - atUint64 start = rs.position(); - - auto iter = std::find_if(SCRIPT_OBJECT_DB.begin(), SCRIPT_OBJECT_DB.end(), - [&type](const ScriptObjectSpec* obj) -> bool { return obj->type == type; }); - - if (iter != SCRIPT_OBJECT_DB.end()) { - std::unique_ptr obj((*iter)->loader()); - obj->type = type; - obj->read(rs); - objects.push_back(std::move(obj)); - size_t actualLen = rs.position() - start; - if (actualLen != len) - Log.report(logvisor::Fatal, - FMT_STRING("Error while reading object of type 0x{:02X}, did not read the expected amount of " - "data, read 0x{:x}, expected 0x{:x}"), - (atUint32)type, actualLen, len); - rs.seek(start + len, athena::SeekOrigin::Begin); - } else { - Log.report(logvisor::Fatal, FMT_STRING("Unable to find type 0x{:X} in object database"), - (atUint32)type); - } - } -} - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::YAMLDocReader& rs) { - unknown = rs.readUByte("unknown"); - size_t objCount; - objects.clear(); - if (auto v = rs.enterSubVector("objects", objCount)) { - objectCount = objCount; - objects.reserve(objCount); - for (atUint32 i = 0; i < objectCount; i++) { - if (auto rec = rs.enterSubRecord()) { - atUint8 type = rs.readUByte("type"); - auto iter = std::find_if(SCRIPT_OBJECT_DB.begin(), SCRIPT_OBJECT_DB.end(), - [&type](const ScriptObjectSpec* obj) -> bool { return obj->type == type; }); - - if (iter != SCRIPT_OBJECT_DB.end()) { - std::unique_ptr obj((*iter)->loader()); - obj->read(rs); - obj->type = type; - objects.push_back(std::move(obj)); - } else - Log.report(logvisor::Fatal, FMT_STRING("Unable to find type 0x{:X} in object database"), - (atUint32)type); - } - } - } else - objectCount = 0; -} - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::IStreamWriter& ws) { - ws.writeUByte(unknown); - ws.writeUint32Big(objectCount); - for (const std::unique_ptr& obj : objects) { - ws.writeByte(obj->type); - size_t expLen = 0; - obj->binarySize(expLen); - ws.writeUint32Big(expLen); - auto start = ws.position(); - obj->write(ws); - auto wrote = ws.position() - start; - if (wrote != expLen) - Log.report(logvisor::Error, FMT_STRING("expected writing {} byte SCLY obj; wrote {}"), expLen, wrote); - } -} - -template <> -void SCLY::ScriptLayer::Enumerate(size_t& __isz) { - __isz += 5; - for (const std::unique_ptr& obj : objects) { - __isz += 5; - obj->binarySize(__isz); - } -} - -template <> -void SCLY::ScriptLayer::Enumerate(athena::io::YAMLDocWriter& ws) { - ws.writeUByte("unknown", unknown); - if (auto v = ws.enterSubVector("objects")) { - for (const std::unique_ptr& obj : objects) { - if (auto rec = ws.enterSubRecord()) { - ws.writeUByte("type", obj->type); - obj->write(ws); - } - } - } -} - -std::string_view SCLY::ScriptLayer::DNAType() { return "DNAMP1::SCLY::ScriptLayer"sv; } - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SCLY.hpp b/DataSpec/DNAMP1/SCLY.hpp deleted file mode 100644 index 0104d52d2..000000000 --- a/DataSpec/DNAMP1/SCLY.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "ScriptObjects/IScriptObject.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct SCLY : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - DNAFourCC fourCC; - Value version; - Value layerCount; - - Vector layerSizes; - - struct ScriptLayer : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - Value unknown; - Value objectCount; - Vector, AT_DNA_COUNT(objectCount)> objects; - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - void nameIDs(PAKRouter& pakRouter) const; - }; - Vector layers; - - void exportToLayerDirectories(const PAK::Entry&, PAKRouter&, bool) const; - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - void nameIDs(PAKRouter& pakRouter) const; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SFX/CMakeLists.txt b/DataSpec/DNAMP1/SFX/CMakeLists.txt deleted file mode 100644 index c0de54e48..000000000 --- a/DataSpec/DNAMP1/SFX/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -unset(DNAMP1_SFX_SOURCES) -macro(add_sfx_header HEADER SYMBOL) - bintoc("DNAMP1/SFX/${SYMBOL}.cpp" "DNAMP1/SFX/${HEADER}" "${SYMBOL}") - list(APPEND DNAMP1_SFX_SOURCES "DNAMP1/SFX/${SYMBOL}.cpp" "DNAMP1/SFX/${HEADER}") -endmacro(add_sfx_header) - -add_sfx_header(Atomic.h Atomic_H) -add_sfx_header(BetaBeetle.h BetaBeetle_H) -add_sfx_header(Bird.h Bird_H) -add_sfx_header(BloodFlower.h BloodFlower_H) -add_sfx_header(Burrower.h Burrower_H) -add_sfx_header(ChozoGhost.h ChozoGhost_H) -add_sfx_header(ChubbWeed.h ChubbWeed_H) -add_sfx_header(CineBoots.h CineBoots_H) -add_sfx_header(CineGeneral.h CineGeneral_H) -add_sfx_header(CineGun.h CineGun_H) -add_sfx_header(CineMorphball.h CineMorphball_H) -add_sfx_header(CineSuit.h CineSuit_H) -add_sfx_header(CineVisor.h CineVisor_H) -add_sfx_header(Crater.h Crater_H) -add_sfx_header(Crystallite.h Crystallite_H) -add_sfx_header(Drones.h Drones_H) -add_sfx_header(EliteSpacePirate.h EliteSpacePirate_H) -add_sfx_header(FireFlea.h FireFlea_H) -add_sfx_header(Flaaghra.h Flaaghra_H) -add_sfx_header(FlickerBat.h FlickerBat_H) -add_sfx_header(FlyingPirate.h FlyingPirate_H) -add_sfx_header(FrontEnd.h FrontEnd_H) -add_sfx_header(GagantuanBeatle.h GagantuanBeatle_H) -add_sfx_header(Gnats.h Gnats_H) -add_sfx_header(Gryzbee.h Gryzbee_H) -add_sfx_header(IceCrack.h IceCrack_H) -add_sfx_header(IceWorld.h IceWorld_H) -add_sfx_header(InjuredPirates.h InjuredPirates_H) -add_sfx_header(IntroBoss.h IntroBoss_H) -add_sfx_header(IntroWorld.h IntroWorld_H) -add_sfx_header(JellyZap.h JellyZap_H) -add_sfx_header(LavaWorld.h LavaWorld_H) -add_sfx_header(Magdolite.h Magdolite_H) -add_sfx_header(Metaree.h Metaree_H) -add_sfx_header(MetroidPrime.h MetroidPrime_H) -add_sfx_header(Metroid.h Metroid_H) -add_sfx_header(MinesWorld.h MinesWorld_H) -add_sfx_header(MiscSamus.h MiscSamus_H) -add_sfx_header(Misc.h Misc_H) -add_sfx_header(OmegaPirate.h OmegaPirate_H) -add_sfx_header(OverWorld.h OverWorld_H) -add_sfx_header(Parasite.h Parasite_H) -add_sfx_header(PhazonGun.h PhazonGun_H) -add_sfx_header(Phazon.h Phazon_H) -add_sfx_header(PuddleSpore.h PuddleSpore_H) -add_sfx_header(PuddleToad.h PuddleToad_H) -add_sfx_header(Puffer.h Puffer_H) -add_sfx_header(ReactorDoor.h ReactorDoor_H) -add_sfx_header(Ridley.h Ridley_H) -add_sfx_header(Ripper.h Ripper_H) -add_sfx_header(RuinsWorld.h RuinsWorld_H) -add_sfx_header(SamusShip.h SamusShip_H) -add_sfx_header(Scarab.h Scarab_H) -add_sfx_header(Seedling.h Seedling_H) -add_sfx_header(SheeGoth.h SheeGoth_H) -add_sfx_header(SnakeWeed.h SnakeWeed_H) -add_sfx_header(Sova.h Sova_H) -add_sfx_header(SpacePirate.h SpacePirate_H) -add_sfx_header(SpankWeed.h SpankWeed_H) -add_sfx_header(Thardus.h Thardus_H) -add_sfx_header(TheEnd.h TheEnd_H) -add_sfx_header(Torobyte.h Torobyte_H) -add_sfx_header(Triclops.h Triclops_H) -add_sfx_header(Turret.h Turret_H) -add_sfx_header(UI.h UI_H) -add_sfx_header(WarWasp.h WarWasp_H) -add_sfx_header(Weapons.h Weapons_H) -add_sfx_header(ZZZ.h ZZZ_H) -add_sfx_header(Zoomer.h Zoomer_H) -add_sfx_header(lumigek.h lumigek_H) -add_sfx_header(test.h test_H) - -list(APPEND DNAMP1_SFX_SOURCES "DNAMP1/SFX/SFX.h") diff --git a/DataSpec/DNAMP1/STRG.cpp b/DataSpec/DNAMP1/STRG.cpp deleted file mode 100644 index e866b1a67..000000000 --- a/DataSpec/DNAMP1/STRG.cpp +++ /dev/null @@ -1,465 +0,0 @@ -#include "STRG.hpp" - -#include - -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -constexpr std::array skLanguages{ - FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'), FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN'), -}; - -static uint32_t ParseTag(const char16_t* str) { - char parseStr[9]; - int i; - for (i = 0; i < 8 && str[i]; ++i) - parseStr[i] = str[i]; - parseStr[i] = '\0'; - return strtoul(parseStr, nullptr, 16); -} - -static std::u16string_view::const_iterator SkipCommas(std::u16string& ret, std::u16string_view str, - std::u16string_view::const_iterator it, size_t count) { - for (size_t i = 0; i < count; ++i) { - auto cpos = str.find(u',', it - str.begin()); - if (cpos == std::u16string::npos) - return str.end(); - auto end = str.begin() + cpos + 1; - ret.insert(ret.end(), it, end); - it = end; - } - return it; -} - -static std::u16string_view::const_iterator UncookTextureList(std::u16string& ret, std::u16string_view str, - std::u16string_view::const_iterator it) { - while (true) { - UniqueID32 id = ParseTag(&*it); - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - ret.append(hecl::UTF8ToChar16(path ? path.getRelativePath() : id.toString())); - it += 8; - if (*it == u';') { - ret.push_back(u';'); - return it + 1; - } else if (*it == u',') { - ret.push_back(u','); - ++it; - } else { - break; - } - } - - /* Failsafe */ - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - return str.end(); - return str.begin() + scpos + 1; -} - -static std::u16string_view::const_iterator CookTextureList(std::u16string& ret, std::u16string_view str, - std::u16string_view::const_iterator it) { - while (true) { - auto end = str.find_first_of(u",;", it - str.begin()); - if (end == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing comma/semicolon token while pasing font tag")); - auto endIt = str.begin() + end; - hecl::ProjectPath path = - UniqueIDBridge::MakePathFromString(hecl::Char16ToUTF8(std::u16string(it, endIt))); - ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); - it = endIt; - if (*it == u';') { - ret.push_back(u';'); - return it + 1; - } else if (*it == u',') { - ret.push_back(u','); - ++it; - } else { - break; - } - } - - /* Failsafe */ - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - return str.end(); - return str.begin() + scpos + 1; -} - -static std::u16string_view::const_iterator GatherTextureList(std::vector& pathsOut, - std::u16string_view str, - std::u16string_view::const_iterator it) { - while (true) { - auto end = str.find_first_of(u",;", it - str.begin()); - if (end == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing comma/semicolon token while pasing font tag")); - auto endIt = str.begin() + end; - hecl::ProjectPath path = - UniqueIDBridge::MakePathFromString(hecl::Char16ToUTF8(std::u16string(it, endIt))); - if (path) - pathsOut.push_back(path); - - it = endIt; - if (*it == u';') { - return it + 1; - } else if (*it == u',') { - ++it; - } else { - break; - } - } - - /* Failsafe */ - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - return str.end(); - return str.begin() + scpos + 1; -} - -static std::u16string UncookString(std::u16string_view str) { - std::u16string ret; - ret.reserve(str.size()); - for (auto it = str.begin(); it != str.end();) { - if (*it == u'&') { - ret.push_back(u'&'); - ++it; - if (!str.compare(it - str.begin(), 5, u"image")) { - ret.append(u"image="); - it += 6; - if (!str.compare(it - str.begin(), 1, u"A")) { - it = SkipCommas(ret, str, it, 2); - it = UncookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SA")) { - it = SkipCommas(ret, str, it, 4); - it = UncookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SI")) { - it = SkipCommas(ret, str, it, 3); - it = UncookTextureList(ret, str, it); - continue; - } - } else if (!str.compare(it - str.begin(), 4, u"font")) { - ret.append(u"font="); - it += 5; - UniqueID32 id = ParseTag(&*it); - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id, true); - ret.append(hecl::UTF8ToChar16(path ? path.getRelativePath() : id.toString())); - - ret.push_back(u';'); - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - it = str.end(); - else - it = str.begin() + scpos + 1; - } else { - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) { - it = str.end(); - } else { - auto end = str.begin() + scpos + 1; - ret.insert(ret.end(), it, end); - it = end; - } - } - } else { - ret.push_back(*it); - ++it; - } - } - return ret; -} - -static std::u16string CookString(std::u16string_view str) { - std::u16string ret; - ret.reserve(str.size()); - for (auto it = str.begin(); it != str.end();) { - if (*it == u'&') { - ret.push_back(u'&'); - ++it; - if (!str.compare(it - str.begin(), 5, u"image")) { - ret.append(u"image="); - it += 6; - if (!str.compare(it - str.begin(), 1, u"A")) { - it = SkipCommas(ret, str, it, 2); - it = CookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SA")) { - it = SkipCommas(ret, str, it, 4); - it = CookTextureList(ret, str, it); - continue; - } else if (!str.compare(it - str.begin(), 2, u"SI")) { - it = SkipCommas(ret, str, it, 3); - it = CookTextureList(ret, str, it); - continue; - } - } else if (!str.compare(it - str.begin(), 4, u"font")) { - ret.append(u"font="); - it += 5; - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing semicolon token while pasing font tag")); - hecl::ProjectPath path = - UniqueIDBridge::MakePathFromString(hecl::Char16ToUTF8(std::u16string(it, str.begin() + scpos))); - ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); - ret.push_back(u';'); - it = str.begin() + scpos + 1; - } else { - auto scpos = str.find(u';', it - str.begin()); - if (scpos == std::u16string::npos) { - it = str.end(); - } else { - auto end = str.begin() + scpos + 1; - ret.insert(ret.end(), it, end); - it = end; - } - } - } else { - ret.push_back(*it); - ++it; - } - } - return ret; -} - -void STRG::gatherDependencies(std::vector& pathsOut) const { - std::u16string skip; - for (const auto& lang : langs) { - for (const std::u16string& str : lang.second) { - std::u16string_view strView(str); - for (auto it = strView.begin(); it != strView.end();) { - if (*it == u'&') { - ++it; - if (!str.compare(it - strView.begin(), 5, u"image")) { - it += 6; - if (!str.compare(it - strView.begin(), 1, u"A")) { - it = SkipCommas(skip, str, it, 2); - it = GatherTextureList(pathsOut, str, it); - continue; - } else if (!str.compare(it - strView.begin(), 2, u"SA")) { - it = SkipCommas(skip, str, it, 4); - it = GatherTextureList(pathsOut, str, it); - continue; - } else if (!str.compare(it - strView.begin(), 2, u"SI")) { - it = SkipCommas(skip, str, it, 3); - it = GatherTextureList(pathsOut, str, it); - continue; - } - } else if (!str.compare(it - strView.begin(), 4, u"font")) { - it += 5; - auto scpos = str.find(u';', it - strView.begin()); - if (scpos == std::u16string::npos) - Log.report(logvisor::Fatal, FMT_STRING("Missing semicolon token while pasing font tag")); - hecl::ProjectPath path = UniqueIDBridge::MakePathFromString( - hecl::Char16ToUTF8(std::u16string(it, strView.begin() + scpos))); - if (path) - pathsOut.push_back(path); - it = strView.begin() + scpos + 1; - } else { - auto scpos = str.find(u';', it - strView.begin()); - if (scpos == std::u16string::npos) - it = strView.end(); - else - it = strView.begin() + scpos + 1; - } - } else - ++it; - } - } - } -} - -void STRG::_read(athena::io::IStreamReader& reader) { - atUint32 langCount = reader.readUint32Big(); - atUint32 strCount = reader.readUint32Big(); - - std::vector> readLangs; - - readLangs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - DNAFourCC lang; - lang.read(reader); - atUint32 off = reader.readUint32Big(); - readLangs.emplace_back(lang, off); - } - - atUint32 tablesStart = reader.position(); - langs.clear(); - langs.reserve(skLanguages.size()); - for (const std::pair& lang : readLangs) { - std::vector strs; - reader.seek(tablesStart + lang.second, athena::SeekOrigin::Begin); - reader.readUint32Big(); // table size - atUint32 langStart = reader.position(); - for (atUint32 s = 0; s < strCount; ++s) { - atUint32 strOffset = reader.readUint32Big(); - atUint32 tmpOffset = reader.position(); - reader.seek(langStart + strOffset, athena::SeekOrigin::Begin); - strs.emplace_back(UncookString(reader.readU16StringBig())); - reader.seek(tmpOffset, athena::SeekOrigin::Begin); - } - langs.emplace_back(lang.first, strs); - } - - langMap.clear(); - langMap.reserve(langCount); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(typename Read::StreamT& reader) { - atUint32 magic = reader.readUint32Big(); - if (magic != 0x87654321) - Log.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - - atUint32 version = reader.readUint32Big(); - if (version != 0) - Log.report(logvisor::Error, FMT_STRING("invalid STRG version")); - - _read(reader); -} - -template <> -void STRG::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(0x87654321); - writer.writeUint32Big(0); - writer.writeUint32Big(langs.size()); - atUint32 strCount = STRG::count(); - writer.writeUint32Big(strCount); - - std::vector strings; - strings.reserve(strCount * langs.size()); - - atUint32 offset = 0; - for (const std::pair>& lang : langs) { - DNAFourCC(lang.first).write(writer); - writer.writeUint32Big(offset); - offset += strCount * 4 + 4; - atUint32 langStrCount = lang.second.size(); - for (atUint32 s = 0; s < strCount; ++s) { - std::u16string str = CookString(lang.second[s]); - atUint32 chCount = str.size(); - if (s < langStrCount) - offset += (chCount + 1) * 2; - else - offset += 1; - strings.push_back(std::move(str)); - } - } - - auto langIt = strings.cbegin(); - for (const std::pair>& lang : langs) { - atUint32 langStrCount = lang.second.size(); - atUint32 tableSz = strCount * 4; - auto strIt = langIt; - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - tableSz += ((strIt++)->size() + 1) * 2; - else - tableSz += 1; - } - writer.writeUint32Big(tableSz); - - offset = strCount * 4; - strIt = langIt; - for (atUint32 s = 0; s < strCount; ++s) { - writer.writeUint32Big(offset); - if (s < langStrCount) - offset += ((strIt++)->size() + 1) * 2; - else - offset += 1; - } - - strIt = langIt; - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - writer.writeU16StringBig(*strIt++); - else - writer.writeUByte(0); - } - - langIt = strIt; - } -} - -template <> -void STRG::Enumerate(typename BinarySize::StreamT& _s) { - _s += 16; - _s += langs.size() * 12; - - size_t strCount = STRG::count(); - _s += langs.size() * strCount * 4; - for (const std::pair>& lang : langs) { - atUint32 langStrCount = lang.second.size(); - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - _s += (CookString(lang.second[s]).size() + 1) * 2; - else - _s += 1; - } - } -} - -template <> -void STRG::Enumerate(typename ReadYaml::StreamT& reader) { - const athena::io::YAMLNode* root = reader.getRootNode(); - - /* Validate Pass */ - if (root->m_type == YAML_MAPPING_NODE) { - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "DNAType") - continue; - - if (lang.first.size() != 4) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must be exactly 4 characters; skipping"), - lang.first); - return; - } - if (lang.second->m_type != YAML_SEQUENCE_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must contain a sequence; skipping"), - lang.first); - return; - } - for (const auto& str : lang.second->m_seqChildren) { - if (str->m_type != YAML_SCALAR_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language '{}' must contain all scalars; skipping"), - lang.first); - return; - } - } - } - } else { - Log.report(logvisor::Warning, FMT_STRING("STRG must have a mapping root node; skipping")); - return; - } - - /* Read Pass */ - langs.clear(); - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "DNAType") - continue; - - std::vector strs; - for (const auto& str : lang.second->m_seqChildren) - strs.emplace_back(hecl::UTF8ToChar16(str->m_scalarString)); - langs.emplace_back(FourCC(lang.first.c_str()), strs); - } - - langMap.clear(); - langMap.reserve(langs.size()); - for (auto& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(typename WriteYaml::StreamT& writer) { - for (const auto& lang : langs) { - if (auto v = writer.enterSubVector(lang.first.toString())) - for (const std::u16string& str : lang.second) - writer.writeU16String(str); - } -} - -std::string_view STRG::DNAType() { return "DNAMP1::STRG"sv; } -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/STRG.hpp b/DataSpec/DNAMP1/STRG.hpp deleted file mode 100644 index 9cc4f2285..000000000 --- a/DataSpec/DNAMP1/STRG.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/STRG.hpp" -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { - -struct STRG : ISTRG { - AT_DECL_EXPLICIT_DNA_YAMLV - void _read(athena::io::IStreamReader& reader); - std::vector>> langs; - std::unordered_map*> langMap; - - int32_t lookupIdx(std::string_view name) const override { return -1; } - - size_t count() const override { - size_t retval = 0; - for (const auto& item : langs) { - size_t sz = item.second.size(); - if (sz > retval) - retval = sz; - } - return retval; - } - std::string getUTF8(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return hecl::Char16ToUTF8(search->second->at(idx)); - return std::string(); - } - std::u16string getUTF16(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return search->second->at(idx); - return std::u16string(); - } - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - STRG strg; - strg.read(rs); - athena::io::TransactionalFileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(strg, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - STRG strg; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(strg, reader); - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } - - static bool Cook(const STRG& strg, const hecl::ProjectPath& outPath) { - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } - - void gatherDependencies(std::vector& pathsOut) const override; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AIJumpPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/AIJumpPoint.hpp deleted file mode 100644 index 2595fc26c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AIJumpPoint.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AIJumpPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value apex; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AIKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/AIKeyframe.hpp deleted file mode 100644 index 9d05a3c36..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AIKeyframe.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct AIKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value animationId; - Value looping; - Value lifetime; - Value active; - Value fadeOut; - Value totalPlayback; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Actor.cpp b/DataSpec/DNAMP1/ScriptObjects/Actor.cpp deleted file mode 100644 index da056382e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Actor.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "Actor.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -zeus::CAABox Actor::getVISIAABB(hecl::blender::Token& btok) const { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - zeus::CAABox aabbOut; - - if (model.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(model); - conn.openBlend(path); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } else if (animationParameters.animationCharacterSet.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet); - conn.openBlend(path.getWithExtension(".blend", true)); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } - - if (aabbOut.min.x() > aabbOut.max.x()) - return {}; - - zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location); - return aabbOut.getTransformedAABox(xf); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Actor.hpp b/DataSpec/DNAMP1/ScriptObjects/Actor.hpp deleted file mode 100644 index 9b094f042..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Actor.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Actor : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOffset; - Value mass; - Value zMomentum; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value looping; - Value immovable; - Value solid; - Value cameraPassthrough; - Value active; - Value shaderIdx; - Value xrayAlpha; - Value noThermalHotZ; - Value castsShadow; - Value scaleAdvancementDelta; - Value materialFlag54; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ActorContraption.hpp b/DataSpec/DNAMP1/ScriptObjects/ActorContraption.hpp deleted file mode 100644 index b367b9ca2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ActorContraption.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ActorContraption : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOrigin; - Value mass; - Value zMomentum; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - AnimationParameters animationParameters; - ActorParameters actorParameters; - UniqueID32 particle; - DamageInfo damageInfo; - Value active; // needs verification - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ActorKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/ActorKeyframe.hpp deleted file mode 100644 index 4fb752caa..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ActorKeyframe.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ActorKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value animationId; - Value looping; - Value lifetime; - Value active; - Value fadeOut; - Value totalPlayback; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ActorRotate.hpp b/DataSpec/DNAMP1/ScriptObjects/ActorRotate.hpp deleted file mode 100644 index 41f2a4c1f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ActorRotate.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ActorRotate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value rotationOffset; - Value timeScale; - Value updateActors; - Value updateOnCreation; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp b/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp deleted file mode 100644 index 92eeaf626..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AmbientAI.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AmbientAI : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOffset; - Value mass; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value alertRange; - Value impactRange; - Value alertAnim; - Value impactAnim; - Value active; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AreaAttributes.hpp b/DataSpec/DNAMP1/ScriptObjects/AreaAttributes.hpp deleted file mode 100644 index 5ee96ae11..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AreaAttributes.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AreaAttributes : IScriptObject { - AT_DECL_DNA_YAMLV - enum class EWeatherType : atUint32 { None, Snow, Rain }; - - Value load; /* 0 causes the loader to bail and return null */ - Value skyboxEnabled; - Value weather; - Value envFxDensity; - Value thermalHeat; - Value xrayFogDistance; - Value worldLightingLevel; - UniqueID32 skybox; - Value phazonType; - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(skybox, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AtomicAlpha.hpp b/DataSpec/DNAMP1/ScriptObjects/AtomicAlpha.hpp deleted file mode 100644 index 5ea14c195..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AtomicAlpha.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AtomicAlpha : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 wpsc; - UniqueID32 model; - DamageInfo damageInfo; - Value bombDropDelay; - Value bombReappearDelay; - Value bombReappearTime; - Value invisible; - Value applyBeamAttraction; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/AtomicBeta.hpp b/DataSpec/DNAMP1/ScriptObjects/AtomicBeta.hpp deleted file mode 100644 index e367f683e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/AtomicBeta.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct AtomicBeta : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 elsc; - UniqueID32 wpsc; - DamageInfo damageInfo; - UniqueID32 part; - Value unknown1; - Value unknown2; - Value unknown3; - DamageVulnerability damageVulnerabilty; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (part.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(elsc, pathsOut); - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(part, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Babygoth.hpp b/DataSpec/DNAMP1/ScriptObjects/Babygoth.hpp deleted file mode 100644 index 37c3c7607..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Babygoth.hpp +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Babygoth : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value fireballAttackTime; - Value fireballAttackTimeVariance; - UniqueID32 fireballWeapon; - DamageInfo fireballDamage; - DamageInfo attackContactDamage; - UniqueID32 fireBreathWeapon; - UniqueID32 fireBreathRes; - DamageInfo fireBreathDamage; - DamageVulnerability mouthVulnerabilities; - DamageVulnerability shellVulnerabilities; - UniqueID32 noShellModel; - UniqueID32 noShellSkin; - Value shellHitPoints; - Value shellCrackSfx; - UniqueID32 intermediateCrackParticle; - UniqueID32 crackOneParticle; - UniqueID32 crackTwoParticle; - UniqueID32 destroyShellParticle; - Value crackOneSfx; - Value crackTwoSfx; - Value destroyShellSfx; - Value timeUntilAttack; - Value attackCooldownTime; - Value interestTime; - UniqueID32 flamePlayerSteamTxtr; - Value flamePlayerHitSfx; - UniqueID32 flamePlayerIceTxtr; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - UniqueID32 cinf = patternedInfo.animationParameters.getCINF(pakRouter); - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - - if (noShellModel.isValid() && noShellSkin.isValid()) { - charAssoc.m_cmdlRigs[noShellModel] = {noShellSkin, cinf}; - charAssoc.m_cskrToCharacter[noShellSkin] = - std::make_pair(patternedInfo.animationParameters.animationCharacterSet, - fmt::format(FMT_STRING("ATTACH.SHELLESS_{}.CSKR"), noShellSkin)); - charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, noShellModel, "SHELLESS"); - } - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (fireballWeapon.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(fireballWeapon); - ent->name = name + "_wpsc1"; - } - if (fireBreathWeapon.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(fireBreathWeapon); - ent->name = name + "_wpsc2"; - } - if (fireBreathRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(fireBreathRes); - ent->name = name + "_part1"; - } - if (noShellModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(noShellModel); - ent->name = name + "_emodel"; - } - if (noShellSkin.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(noShellSkin); - ent->name = name + "_eskin"; - } - if (intermediateCrackParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(intermediateCrackParticle); - ent->name = name + "_part2"; - } - if (crackOneParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(crackOneParticle); - ent->name = name + "_part3"; - } - if (crackTwoParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(crackTwoParticle); - ent->name = name + "_part4"; - } - if (destroyShellParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(destroyShellParticle); - ent->name = name + "_part5"; - } - if (flamePlayerSteamTxtr.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(flamePlayerSteamTxtr); - ent->name = name + "_tex"; - } - if (flamePlayerIceTxtr.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(flamePlayerIceTxtr); - ent->name = name + "_part6"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(fireballWeapon, pathsOut); - g_curSpec->flattenDependencies(fireBreathWeapon, pathsOut); - g_curSpec->flattenDependencies(fireBreathRes, pathsOut); - g_curSpec->flattenDependencies(noShellModel, pathsOut); - g_curSpec->flattenDependencies(noShellSkin, pathsOut); - g_curSpec->flattenDependencies(intermediateCrackParticle, pathsOut); - g_curSpec->flattenDependencies(crackOneParticle, pathsOut); - g_curSpec->flattenDependencies(crackTwoParticle, pathsOut); - g_curSpec->flattenDependencies(destroyShellParticle, pathsOut); - g_curSpec->flattenDependencies(flamePlayerSteamTxtr, pathsOut); - g_curSpec->flattenDependencies(flamePlayerIceTxtr, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/BallTrigger.hpp b/DataSpec/DNAMP1/ScriptObjects/BallTrigger.hpp deleted file mode 100644 index b09627694..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/BallTrigger.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct BallTrigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - Value active; - Value force; - Value minAngle; - Value maxDistance; - Value forceAngle; - Value stopPlayer; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Beetle.hpp b/DataSpec/DNAMP1/ScriptObjects/Beetle.hpp deleted file mode 100644 index 2c6c39445..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Beetle.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Beetle : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo touchDamage; - Value tailAimReference; - Value unused; - DamageVulnerability tailVuln; - DamageVulnerability platingVuln; - UniqueID32 tailModel; - Value entranceType; - Value initialAttackDelay; - Value retreatTime; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (tailModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(tailModel); - ent->name = name + "_tailModel"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(tailModel, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/BloodFlower.hpp b/DataSpec/DNAMP1/ScriptObjects/BloodFlower.hpp deleted file mode 100644 index 69e4d1209..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/BloodFlower.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct BloodFlower : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 particle1; - UniqueID32 wpsc1; - UniqueID32 wpsc2; - DamageInfo damageInfo1; - DamageInfo damageInfo2; - DamageInfo damageInfo3; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - Value unknown1; - UniqueID32 particle5; - Value unknown2; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Burrower.hpp b/DataSpec/DNAMP1/ScriptObjects/Burrower.hpp deleted file mode 100644 index 38ca9adde..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Burrower.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Burrower : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 particle1; - UniqueID32 particle2; - UniqueID32 wpsc; - DamageInfo damageInfo; - UniqueID32 particle3; - Value unknown; // always FF - UniqueID32 particle4; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CMakeLists.txt b/DataSpec/DNAMP1/ScriptObjects/CMakeLists.txt deleted file mode 100644 index 53cb30a51..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CMakeLists.txt +++ /dev/null @@ -1,143 +0,0 @@ -make_dnalist( - IScriptObject - Parameters - Actor - ActorContraption - ActorKeyframe - ActorRotate - AIJumpPoint - AIKeyframe - AmbientAI - AreaAttributes - AtomicAlpha - AtomicBeta - Babygoth - BallTrigger - Beetle - BloodFlower - Burrower - Camera - CameraBlurKeyframe - CameraFilterKeyframe - CameraHint - CameraHintTrigger - CameraPitchVolume - CameraShaker - CameraWaypoint - ChozoGhost - ColorModulate - ControllerAction - Counter - CoverPoint - DamageableTrigger - Debris - DebrisExtended - DebugCameraWaypoint - DistanceFog - Dock - DockAreaChange - DoorArea - Drone - Effect - ElectroMagneticPulse - ElitePirate - EnergyBall - EnvFxDensityController - Eyeball - FireFlea - FishCloud - FishCloudModifier - Flaahgra - FlaahgraTentacle - FlickerBat - FlyingPirate - FogVolume - Geemer - Generator - GrapplePoint - GunTurret - HUDMemo - IceSheegoth - IceZoomer - JellyZap - Magdolite - MazeNode - MemoryRelay - MetareeAlpha - MetroidAlpha - MetroidBeta - MetroidPrimeStage1 - MetroidPrimeStage2 - Midi - NewCameraShaker - NewIntroBoss - Oculus - OmegaPirate - Parasite - PathCamera - PhazonHealingNodule - PhazonPool - Pickup - PickupGenerator - Platform - PlayerActor - PlayerHint - PlayerStateChange - PointOfInterest - PuddleSpore - PuddleToadGamma - Puffer - RadialDamage - RandomRelay - Relay - Repulsor - Ridley - Ripper - Ripple - RoomAcoustics - RumbleEffect - ScriptBeam - Seedling - ShadowProjector - SnakeWeedSwarm - Sound - SpacePirate - SpankWeed - SpawnPoint - SpecialFunction - SpiderBallAttractionSurface - SpiderBallWaypoint - SpindleCamera - Steam - StreamedAudio - Switch - TargetingPoint - TeamAIMgr - Thardus - ThardusRockProjectile - ThermalHeatFader - Timer - Trigger - Tryclops - VisorFlare - VisorGoo - WallCrawlerSwarm - Warwasp - Water - Waypoint - WorldLightFader - WorldTeleporter) - -set(ScriptObjectsMP1_SOURCES - ScriptTypes.hpp - IScriptObject.cpp - Parameters.cpp - Actor.cpp - Platform.cpp - DoorArea.cpp - Oculus.cpp - Ridley.cpp - Water.cpp - WorldTeleporter.cpp) - -dataspec_add_list(DNAMP1/ScriptObjects ScriptObjectsMP1_SOURCES) diff --git a/DataSpec/DNAMP1/ScriptObjects/Camera.hpp b/DataSpec/DNAMP1/ScriptObjects/Camera.hpp deleted file mode 100644 index 1eec64c84..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Camera.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Camera : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value shotDuration; - Value lookAtPlayer; - Value outOfPlayerEye; - Value intoPlayerEye; - Value drawPlayer; - Value disableInput; - Value unknown; - Value finishCineSkip; - Value fov; - Value checkFailsafe; - Value disableOutOfInto; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraBlurKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraBlurKeyframe.hpp deleted file mode 100644 index 1565bba1d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraBlurKeyframe.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraBlurKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value btype; - Value amount; - Value unk; - Value timeIn; - Value timeOut; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraFilterKeyframe.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraFilterKeyframe.hpp deleted file mode 100644 index db95965b7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraFilterKeyframe.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraFilterKeyframe : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value ftype; - Value shape; - Value filterIdx; - Value unk; - DNAColor color; - Value timeIn; - Value timeOut; - UniqueID32 texture; - - void nameIDs(PAKRouter& pakRouter) const override { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(texture, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraHint.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraHint.hpp deleted file mode 100644 index 31a2e8390..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraHint.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraHint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value priority; - Value behaviour; - struct CameraHintParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value calculateCamPos; // 0x1 - Value chaseAllowed; // 0x2 - Value boostAllowed; // 0x4 - Value obscureAvoidance; // 0x8 - Value volumeCollider; // 0x10 - Value applyImmediately; // 0x20 - Value lookAtBall; // 0x40 - Value hintDistanceSelection; // 0x80 - Value hintDistanceSelfPos; // 0x100 - Value controlInterpolation; // 0x200 - Value sinusoidalInterpolation; // 0x400 - Value sinusoidalInterpolationHintless; // 0x800 - Value clampVelocity; // 0x1000 - Value skipCinematic; // 0x2000 - Value noElevationInterp; // 0x4000 - Value directElevation; // 0x8000 - Value overrideLookDir; // 0x10000 - Value noElevationVelClamp; // 0x20000 - Value calculateTransformFromPrevCam; // 0x40000 - Value noSpline; // 0x80000 - Value unknown21; // 0x100000 - Value unknown22; // 0x200000 - } cameraHintParameters; - - struct BoolFloat : BigDNA { - AT_DECL_DNA - Value active; - Value value; - } minDist, maxDist, backwardsDist; // 0x400000, 0x800000, 0x1000000 - struct BoolVec3f : BigDNA { - AT_DECL_DNA - Value active; - Value value; - } lookAtOffset, chaseLookAtOffset; // 0x2000000, 0x4000000 - Value ballToCam; - BoolFloat fov, attitudeRange, azimuthRange, anglePerSecond; // 0x8000000, 0x10000000, 0x20000000, 0x40000000 - Value clampVelRange; - Value clampRotRange; - BoolFloat elevation; // 0x80000000 - Value interpolateTime; - Value clampVelTime; - Value controlInterpDur; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraHintTrigger.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraHintTrigger.hpp deleted file mode 100644 index 37287382e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraHintTrigger.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraHintTrigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - Value deactivateOnEntered; - Value deactivateOnExited; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraPitchVolume.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraPitchVolume.hpp deleted file mode 100644 index 9a8566fb5..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraPitchVolume.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraPitchVolume : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - Value upPitch; - Value downPitch; - Value scale; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp deleted file mode 100644 index c953ca45c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraShaker.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraShaker : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value xMag; - Value xB; - Value yMag; - Value yB; - Value zMag; - Value zB; - Value duration; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CameraWaypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/CameraWaypoint.hpp deleted file mode 100644 index 24ddd9604..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CameraWaypoint.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CameraWaypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value hFov; - Value unknown3; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ChozoGhost.hpp b/DataSpec/DNAMP1/ScriptObjects/ChozoGhost.hpp deleted file mode 100644 index a4bb949e1..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ChozoGhost.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ChozoGhost : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - UniqueID32 wpsc2; - DamageInfo damageInfo2; - BehaveChance BehaveChance1; - BehaveChance BehaveChance2; - BehaveChance BehaveChance3; - Value sound1; - Value unknown5; - Value sound2; - Value sound3; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - UniqueID32 particle; - Value soundId4; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ColorModulate.hpp b/DataSpec/DNAMP1/ScriptObjects/ColorModulate.hpp deleted file mode 100644 index a1cc80504..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ColorModulate.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ColorModulate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value colorA; - Value colorB; - Value blendMode; - Value timeA2B; - Value timeB2A; - Value doReverse; - Value resetTargetWhenDone; - Value depthCompare; - Value depthUpdate; - Value depthBackwards; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ControllerAction.hpp b/DataSpec/DNAMP1/ScriptObjects/ControllerAction.hpp deleted file mode 100644 index dff78e217..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ControllerAction.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ControllerAction : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value command; - Value deactivateOnClose; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Counter.hpp b/DataSpec/DNAMP1/ScriptObjects/Counter.hpp deleted file mode 100644 index 460816cae..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Counter.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Counter : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value initial; - Value maxValue; - Value autoReset; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/CoverPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/CoverPoint.hpp deleted file mode 100644 index 040ece63d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/CoverPoint.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct CoverPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value flags; - Value crouch; - Value horizontalAngle; - Value verticleAngle; - Value coverTime; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DamageableTrigger.hpp b/DataSpec/DNAMP1/ScriptObjects/DamageableTrigger.hpp deleted file mode 100644 index ec893629e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DamageableTrigger.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DamageableTrigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value faceFlag; - UniqueID32 patternTex1; - UniqueID32 patternTex2; - UniqueID32 colorTex; - Value lockOn; - Value active; - VisorParameters visorParameters; - - void nameIDs(PAKRouter& pakRouter) const override { - if (patternTex1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternTex1); - ent->name = name + "_patternTex1"; - } - if (patternTex2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternTex2); - ent->name = name + "_patternTex2"; - } - if (colorTex.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorTex); - ent->name = name + "_colorTex"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(patternTex1, pathsOut); - g_curSpec->flattenDependencies(patternTex2, pathsOut); - g_curSpec->flattenDependencies(colorTex, pathsOut); - } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override { - zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f; - zeus::CVector3f loc(location); - return zeus::CAABox(loc - halfExtent, loc + halfExtent); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Debris.hpp b/DataSpec/DNAMP1/ScriptObjects/Debris.hpp deleted file mode 100644 index 401c0ad7f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Debris.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Debris : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value zImpulse; - Value velocity; - DNAColor endsColor; - Value mass; - Value restitution; - Value duration; - Value scaleType; - Value randomAngImpulse; - UniqueID32 model; - ActorParameters actorParameters; - UniqueID32 particle; - Value particleScale; - Value b1; - Value active; - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp b/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp deleted file mode 100644 index 002b3d751..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DebrisExtended.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DebrisExtended : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value linConeAngle; - Value linMinMag; - Value linMaxMag; - Value angMinMag; - Value angMaxMag; - Value minDuration; - Value maxDuration; - Value colorInT; - Value colorOutT; - DNAColor color; - DNAColor endsColor; - Value scaleOutT; - Value endScale; - Value restitution; - Value downwardSpeed; - Value localOffset; - UniqueID32 model; - ActorParameters actorParameters; - UniqueID32 particle1; - Value particle1Scale; - Value particle1GlobalTranslation; - Value deferDeleteTillParticle1Done; - Value particle1Or; - UniqueID32 particle2; - Value particle2Scale; - Value particle2GlobalTranslation; - Value deferDeleteTillParticle2Done; - Value particle2Or; - UniqueID32 particle3; - Value particle3Scale; - Value particle3Or; - Value solid; - Value dieOnProjectile; - Value noBounce; - Value active; - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DebugCameraWaypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/DebugCameraWaypoint.hpp deleted file mode 100644 index aad5f0e39..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DebugCameraWaypoint.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DebugCameraWaypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value unknown1; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DistanceFog.hpp b/DataSpec/DNAMP1/ScriptObjects/DistanceFog.hpp deleted file mode 100644 index 07813fc15..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DistanceFog.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DistanceFog : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value fogMode; - Value fogColor; // CColor - Value range; - Value colorDelta; - Value rangeDelta; - Value expl; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Dock.hpp b/DataSpec/DNAMP1/ScriptObjects/Dock.hpp deleted file mode 100644 index 1d24e3cb1..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Dock.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Dock : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value location; - Value volume; - Value dock; - Value room; - Value loadConnected; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DockAreaChange.hpp b/DataSpec/DNAMP1/ScriptObjects/DockAreaChange.hpp deleted file mode 100644 index 64bb25b9c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DockAreaChange.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DockAreaChange : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value dockReference; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DoorArea.cpp b/DataSpec/DNAMP1/ScriptObjects/DoorArea.cpp deleted file mode 100644 index 766ff4dff..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DoorArea.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "DoorArea.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -zeus::CAABox DoorArea::getVISIAABB(hecl::blender::Token& btok) const { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - zeus::CAABox aabbOut; - - if (animationParameters.animationCharacterSet.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet); - conn.openBlend(path.getWithExtension(".blend", true)); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } - - if (aabbOut.min.x() > aabbOut.max.x()) - return {}; - - zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location); - return aabbOut.getTransformedAABox(xf); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/DoorArea.hpp b/DataSpec/DNAMP1/ScriptObjects/DoorArea.hpp deleted file mode 100644 index 8cfaacb6b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/DoorArea.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct DoorArea : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value orbitPos; - Value collisionExtent; - Value collisionOffset; - Value active; - Value open; - Value projectilesCollide; - Value animationLength; - Value isMorphballDoor; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp b/DataSpec/DNAMP1/ScriptObjects/Drone.hpp deleted file mode 100644 index af29fad9d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp +++ /dev/null @@ -1,90 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Drone : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - Value unknown2; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo damageInfo1; - Value unknown3; - DamageInfo damageInfo2; - UniqueID32 unknown4; - Value unused; - UniqueID32 unknown6; - FlareDefinition flareDefinition1; - FlareDefinition flareDefinition2; - FlareDefinition flareDefinition3; - FlareDefinition flareDefinition4; - FlareDefinition flareDefinition5; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - Value unknown20; - Value unknown21; - Value unknown22; - Value unknown23; - Value unknown24; - Value unknown25; - UniqueID32 crsc; - Value unknon26; - Value unknon27; - Value unknon28; - Value unknon29; - Value sound; // verification needed - Value unknown30; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (crsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(crsc); - ent->name = name + "_crsc"; - } - flareDefinition1.nameIDs(pakRouter, name + "_flare1"); - flareDefinition2.nameIDs(pakRouter, name + "_flare2"); - flareDefinition3.nameIDs(pakRouter, name + "_flare3"); - flareDefinition4.nameIDs(pakRouter, name + "_flare4"); - flareDefinition5.nameIDs(pakRouter, name + "_flare5"); - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(unknown4, pathsOut); - g_curSpec->flattenDependencies(unknown6, pathsOut); - g_curSpec->flattenDependencies(crsc, pathsOut); - flareDefinition1.depIDs(pathsOut); - flareDefinition2.depIDs(pathsOut); - flareDefinition3.depIDs(pathsOut); - flareDefinition4.depIDs(pathsOut); - flareDefinition5.depIDs(pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Effect.hpp b/DataSpec/DNAMP1/ScriptObjects/Effect.hpp deleted file mode 100644 index 05ce2153c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Effect.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Effect : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - UniqueID32 part; - UniqueID32 elsc; - Value hotInThermal; - Value noTimerUnlessAreaOccluded; - Value rebuildSystemsOnActivate; - Value active; - Value useRateInverseCamDist; - Value rateInverseCamDist; - Value rateInverseCamDistRate; - Value duration; - Value durationResetWhileVisible; - Value useRateCamDistRange; - Value rateCamDistRangeMin; - Value rateCamDistRangeMax; - Value rateCamDistRangeFarRate; - Value combatVisorVisible; - Value thermalVisorVisible; - Value xrayVisorVisible; - Value dieWhenSystemsDone; - LightParameters lightParameters; - - void nameIDs(PAKRouter& pakRouter) const override { - if (part.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part); - ent->name = name + "_part"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(part, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ElectroMagneticPulse.hpp b/DataSpec/DNAMP1/ScriptObjects/ElectroMagneticPulse.hpp deleted file mode 100644 index 6a3c92685..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ElectroMagneticPulse.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ElectroMagneticPulse : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value initialRadius; - Value finalRadius; - Value duration; - Value interferenceDur; - Value unknown6; - Value interferenceMag; - Value unknown8; - UniqueID32 particle; - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ElitePirate.hpp b/DataSpec/DNAMP1/ScriptObjects/ElitePirate.hpp deleted file mode 100644 index 1e011506a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ElitePirate.hpp +++ /dev/null @@ -1,123 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ElitePirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters1; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - UniqueID32 particle1; - Value soundID1; - ActorParameters actorParameters2; - AnimationParameters animationParameters; - UniqueID32 particle2; - Value soundID2; - UniqueID32 model; - DamageInfo damageInfo1; - Value unknown9; - UniqueID32 particle3; - UniqueID32 particle4; - UniqueID32 particle5; - UniqueID32 particle6; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value soundID3; - Value soundID4; - UniqueID32 particle7; - DamageInfo damageInfo2; - UniqueID32 elsc; - Value soundID5; - Value unknown17; - Value unknown18; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - if (particle7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); - ent->name = name + "_part7"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters1.nameIDs(pakRouter, name + "_actp1"); - actorParameters2.nameIDs(pakRouter, name + "_actp2"); - animationParameters.nameANCS(pakRouter, name + "_animp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - g_curSpec->flattenDependencies(particle7, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters1.depIDs(pathsOut, lazyOut); - actorParameters2.depIDs(pathsOut, lazyOut); - animationParameters.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { - actorParameters1.scanIDs(scansOut); - actorParameters2.scanIDs(scansOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/EnergyBall.hpp b/DataSpec/DNAMP1/ScriptObjects/EnergyBall.hpp deleted file mode 100644 index 65856253f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/EnergyBall.hpp +++ /dev/null @@ -1,68 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct EnergyBall : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - DamageInfo damageInfo1; - Value unknown3; - UniqueID32 texture; - Value soundID1; - UniqueID32 particle1; - UniqueID32 elsc; - Value soundID2; - Value unknown4; - Value unknown5; - UniqueID32 particle2; - DamageInfo damageInfo2; - Value unknown6; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(texture, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/EnvFxDensityController.hpp b/DataSpec/DNAMP1/ScriptObjects/EnvFxDensityController.hpp deleted file mode 100644 index 19374dfc7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/EnvFxDensityController.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct EnvFxDensityController : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value density; - Value maxDensityDeltaSpeed; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Eyeball.hpp b/DataSpec/DNAMP1/ScriptObjects/Eyeball.hpp deleted file mode 100644 index aaf296802..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Eyeball.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Eyeball : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value attackDelay; - Value attackStartTime; - UniqueID32 wpsc; - DamageInfo damageInfo; - UniqueID32 beamContactFxId; - UniqueID32 beamPulseFxId; - UniqueID32 beamTextureId; - UniqueID32 beamGlowTextureId; - Value anim0; - Value anim1; // always ff - Value anim2; // always ff - Value anim3; // always ff - Value beamSfx; - Value attackDisabled; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - if (beamContactFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamContactFxId); - ent->name = name + "_part1"; - } - if (beamPulseFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamPulseFxId); - ent->name = name + "_part2"; - } - if (beamTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamTextureId); - ent->name = name + "_tex1"; - } - if (beamGlowTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamGlowTextureId); - ent->name = name + "_tex2"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - g_curSpec->flattenDependencies(beamContactFxId, pathsOut); - g_curSpec->flattenDependencies(beamPulseFxId, pathsOut); - g_curSpec->flattenDependencies(beamTextureId, pathsOut); - g_curSpec->flattenDependencies(beamGlowTextureId, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FireFlea.hpp b/DataSpec/DNAMP1/ScriptObjects/FireFlea.hpp deleted file mode 100644 index d80f1ae2a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FireFlea.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FireFlea : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FishCloud.hpp b/DataSpec/DNAMP1/ScriptObjects/FishCloud.hpp deleted file mode 100644 index c55be52cf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FishCloud.hpp +++ /dev/null @@ -1,81 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FishCloud : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - UniqueID32 model; - AnimationParameters animationParameters; - Value numBoids; - Value speed; - Value separationRadius; - Value cohesionMagnitude; - Value alignmentWeight; - Value separationMagnitude; - Value weaponRepelMagnitude; - Value playerRepelMagnitude; - Value containmentMagnitude; - Value scatterVel; - Value maxScatterAngle; - Value weaponRepelDampingSpeed; - Value playerRepelDampingSpeed; - Value containmentRadius; - Value updateShift; - Value color; // CColor - Value killable; - Value weaponKillRadius; - UniqueID32 deathParticle1; - Value deathParticle1Count; - UniqueID32 deathParticle2; - Value deathParticle2Count; - UniqueID32 deathParticle3; - Value deathParticle3Count; - UniqueID32 deathParticle4; - Value deathParticle4Count; - Value deathSFX; - Value repelFromThreats; - Value hotInThermal; - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - if (deathParticle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle1); - ent->name = name + "_deathParticle1"; - } - if (deathParticle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle2); - ent->name = name + "_deathParticle2"; - } - if (deathParticle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle3); - ent->name = name + "_deathParticle3"; - } - if (deathParticle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deathParticle4); - ent->name = name + "_deathParticle4"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - g_curSpec->flattenDependencies(deathParticle1, pathsOut); - g_curSpec->flattenDependencies(deathParticle2, pathsOut); - g_curSpec->flattenDependencies(deathParticle3, pathsOut); - g_curSpec->flattenDependencies(deathParticle4, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FishCloudModifier.hpp b/DataSpec/DNAMP1/ScriptObjects/FishCloudModifier.hpp deleted file mode 100644 index cf691aac0..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FishCloudModifier.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FishCloudModifier : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value position; - Value active; - Value repulsor; - Value swirl; - Value radius; - Value priority; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Flaahgra.hpp b/DataSpec/DNAMP1/ScriptObjects/Flaahgra.hpp deleted file mode 100644 index d8208209b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Flaahgra.hpp +++ /dev/null @@ -1,79 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Flaahgra : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters1; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - DamageVulnerability damageVulnerabilty; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - UniqueID32 wpsc2; - DamageInfo damageInfo2; - UniqueID32 particle; - DamageInfo damageInfo3; - ActorParameters actorParameters2; - Value unknown5; - Value unknown6; - Value unknown7; - AnimationParameters animationParameters; - UniqueID32 dependencyGroup; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (dependencyGroup.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(dependencyGroup); - ent->name = name + "_dgrp"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters1.nameIDs(pakRouter, name + "_actp1"); - actorParameters2.nameIDs(pakRouter, name + "_actp2"); - animationParameters.nameANCS(pakRouter, name + "_animp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(dependencyGroup, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters1.depIDs(pathsOut, lazyOut); - actorParameters2.depIDs(pathsOut, lazyOut); - animationParameters.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { - actorParameters1.scanIDs(scansOut); - actorParameters2.scanIDs(scansOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FlaahgraTentacle.hpp b/DataSpec/DNAMP1/ScriptObjects/FlaahgraTentacle.hpp deleted file mode 100644 index 0922909fe..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FlaahgraTentacle.hpp +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FlaahgraTentacle : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FlickerBat.hpp b/DataSpec/DNAMP1/ScriptObjects/FlickerBat.hpp deleted file mode 100644 index ee0d3afcf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FlickerBat.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FlickerBat : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value collider; - Value startsHidden; - Value enableLineOfSight; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FlyingPirate.hpp b/DataSpec/DNAMP1/ScriptObjects/FlyingPirate.hpp deleted file mode 100644 index ff0f3d5cd..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FlyingPirate.hpp +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FlyingPirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - Value unknown4; - UniqueID32 wpsc2; - DamageInfo damageInfo2; - UniqueID32 wpsc3; - Value unknown5; - Value unknown6; - UniqueID32 particle1; - DamageInfo damageInfo3; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - Value unknown20; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (wpsc3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc3); - ent->name = name + "_wpsc3"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(wpsc3, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/FogVolume.hpp b/DataSpec/DNAMP1/ScriptObjects/FogVolume.hpp deleted file mode 100644 index 421614c35..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/FogVolume.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct FogVolume : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - Value flickerSpeed; - Value unknown2; - Value fogColor; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Geemer.hpp b/DataSpec/DNAMP1/ScriptObjects/Geemer.hpp deleted file mode 100644 index f60cf648c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Geemer.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Geemer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value advanceWpRadius; - Value unknown2; - Value alignAngVel; - Value unknown4; - Value playerObstructionMinDist; - Value haltDelay; - Value forwardMoveWeight; - Value haltSfx; - Value getUpSfx; - Value crouchSfx; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Generator.hpp b/DataSpec/DNAMP1/ScriptObjects/Generator.hpp deleted file mode 100644 index b8a9f8205..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Generator.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Generator : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value spawnCount; - Value noReuseFollowers; - Value noInheritXf; - Value offset; - Value active; - Value minScale; - Value maxScale; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/GrapplePoint.hpp b/DataSpec/DNAMP1/ScriptObjects/GrapplePoint.hpp deleted file mode 100644 index 7090af783..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/GrapplePoint.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct GrapplePoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - GrappleParameters grappleParameters; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp b/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp deleted file mode 100644 index 851dfa4fd..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/GunTurret.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct GunTurret : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - Value collisionExtent; - Value collisionOffset; - AnimationParameters animationParameters; - ActorParameters actorParameters; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value intoDeactivateDelay; - Value reloadTime; - Value reloadTimeVariance; - Value panStartTime; - Value panHoldTime; - Value totalPanSearchTime; - Value leftMaxAngle; - Value rightMaxAngle; - Value downMaxAngle; - Value turnSpeed; - Value detectionRange; - Value detectionZRange; - Value freezeDuration; - Value freezeVariance; - Value freezeTimeout; - UniqueID32 projectileRes; - DamageInfo projectileDamage; - UniqueID32 idleLightRes; - UniqueID32 deactivateLightRes; - UniqueID32 targettingLightRes; - UniqueID32 frozenEffectRes; - UniqueID32 chargingEffectRes; - UniqueID32 panningEffectRes; - UniqueID32 visorEffectRes; - Value trackingSoundId; - Value lockOnSoundId; - Value unfreezeSoundId; - Value stopClankSoundId; - Value chargingSoundId; - Value visorSoundId; - UniqueID32 extensionModelResId; - Value extensionDropDownDist; - Value numInitialShots; - Value initialShotTableIndex; - Value numSubsequentShots; - Value frenzyDuration; - Value scriptedStartOnly; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (projectileRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileRes); - ent->name = name + "_projectileRes"; - } - if (idleLightRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(idleLightRes); - ent->name = name + "_idleLightRes"; - } - if (deactivateLightRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(deactivateLightRes); - ent->name = name + "_deactivateLightRes"; - } - if (targettingLightRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(targettingLightRes); - ent->name = name + "_targettingLightRes"; - } - if (frozenEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(frozenEffectRes); - ent->name = name + "_frozenEffectRes"; - } - if (chargingEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(chargingEffectRes); - ent->name = name + "_chargingEffectRes"; - } - if (panningEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(panningEffectRes); - ent->name = name + "_panningEffectRes"; - } - if (visorEffectRes.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(visorEffectRes); - ent->name = name + "_visorEffectRes"; - } - if (extensionModelResId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(extensionModelResId); - ent->name = name + "_extensionModelResId"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(projectileRes, pathsOut); - g_curSpec->flattenDependencies(idleLightRes, pathsOut); - g_curSpec->flattenDependencies(deactivateLightRes, pathsOut); - g_curSpec->flattenDependencies(targettingLightRes, pathsOut); - g_curSpec->flattenDependencies(frozenEffectRes, pathsOut); - g_curSpec->flattenDependencies(chargingEffectRes, pathsOut); - g_curSpec->flattenDependencies(panningEffectRes, pathsOut); - g_curSpec->flattenDependencies(visorEffectRes, pathsOut); - g_curSpec->flattenDependencies(extensionModelResId, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/HUDMemo.hpp b/DataSpec/DNAMP1/ScriptObjects/HUDMemo.hpp deleted file mode 100644 index 52356d9c5..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/HUDMemo.hpp +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct HUDMemo : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value firstMessageTimer; - Value unknown1; - Value memoType; - UniqueID32 message; - Value active; - - void nameIDs(PAKRouter& pakRouter) const override { - if (message.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(message); - ent->name = name + "_message"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(message, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.cpp b/DataSpec/DNAMP1/ScriptObjects/IScriptObject.cpp deleted file mode 100644 index f29c32671..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.cpp +++ /dev/null @@ -1,425 +0,0 @@ -#include "IScriptObject.hpp" - -#include "Actor.hpp" -#include "ActorContraption.hpp" -#include "ActorKeyframe.hpp" -#include "ActorRotate.hpp" -#include "AIJumpPoint.hpp" -#include "AIKeyframe.hpp" -#include "AmbientAI.hpp" -#include "AreaAttributes.hpp" -#include "AtomicAlpha.hpp" -#include "AtomicBeta.hpp" -#include "Babygoth.hpp" -#include "BallTrigger.hpp" -#include "Beetle.hpp" -#include "BloodFlower.hpp" -#include "Burrower.hpp" -#include "Camera.hpp" -#include "CameraBlurKeyframe.hpp" -#include "CameraFilterKeyframe.hpp" -#include "CameraHint.hpp" -#include "CameraHintTrigger.hpp" -#include "CameraPitchVolume.hpp" -#include "CameraShaker.hpp" -#include "CameraWaypoint.hpp" -#include "ChozoGhost.hpp" -#include "ColorModulate.hpp" -#include "ControllerAction.hpp" -#include "Counter.hpp" -#include "CoverPoint.hpp" -#include "DamageableTrigger.hpp" -#include "Debris.hpp" -#include "DebrisExtended.hpp" -#include "DebugCameraWaypoint.hpp" -#include "DistanceFog.hpp" -#include "Dock.hpp" -#include "DockAreaChange.hpp" -#include "DoorArea.hpp" -#include "Drone.hpp" -#include "Effect.hpp" -#include "ElectroMagneticPulse.hpp" -#include "ElitePirate.hpp" -#include "EnergyBall.hpp" -#include "EnvFxDensityController.hpp" -#include "Eyeball.hpp" -#include "FireFlea.hpp" -#include "FishCloud.hpp" -#include "FishCloudModifier.hpp" -#include "Flaahgra.hpp" -#include "FlaahgraTentacle.hpp" -#include "FlickerBat.hpp" -#include "FlyingPirate.hpp" -#include "FogVolume.hpp" -#include "Geemer.hpp" -#include "Generator.hpp" -#include "GrapplePoint.hpp" -#include "GunTurret.hpp" -#include "HUDMemo.hpp" -#include "IceSheegoth.hpp" -#include "IceZoomer.hpp" -#include "JellyZap.hpp" -#include "Magdolite.hpp" -#include "MazeNode.hpp" -#include "MemoryRelay.hpp" -#include "MetareeAlpha.hpp" -#include "MetroidAlpha.hpp" -#include "MetroidBeta.hpp" -#include "MetroidPrimeStage1.hpp" -#include "MetroidPrimeStage2.hpp" -#include "Midi.hpp" -#include "NewCameraShaker.hpp" -#include "NewIntroBoss.hpp" -#include "Oculus.hpp" -#include "OmegaPirate.hpp" -#include "Parasite.hpp" -#include "PathCamera.hpp" -#include "PhazonHealingNodule.hpp" -#include "PhazonPool.hpp" -#include "Pickup.hpp" -#include "PickupGenerator.hpp" -#include "Platform.hpp" -#include "PlayerActor.hpp" -#include "PlayerHint.hpp" -#include "PlayerStateChange.hpp" -#include "PointOfInterest.hpp" -#include "PuddleSpore.hpp" -#include "PuddleToadGamma.hpp" -#include "Puffer.hpp" -#include "RadialDamage.hpp" -#include "RandomRelay.hpp" -#include "Relay.hpp" -#include "Repulsor.hpp" -#include "Ridley.hpp" -#include "Ripper.hpp" -#include "Ripple.hpp" -#include "RoomAcoustics.hpp" -#include "RumbleEffect.hpp" -#include "ScriptBeam.hpp" -#include "ScriptTypes.hpp" -#include "Seedling.hpp" -#include "ShadowProjector.hpp" -#include "SnakeWeedSwarm.hpp" -#include "Sound.hpp" -#include "SpacePirate.hpp" -#include "SpankWeed.hpp" -#include "SpawnPoint.hpp" -#include "SpecialFunction.hpp" -#include "SpiderBallAttractionSurface.hpp" -#include "SpiderBallWaypoint.hpp" -#include "SpindleCamera.hpp" -#include "Steam.hpp" -#include "StreamedAudio.hpp" -#include "Switch.hpp" -#include "TargetingPoint.hpp" -#include "TeamAIMgr.hpp" -#include "Thardus.hpp" -#include "ThardusRockProjectile.hpp" -#include "ThermalHeatFader.hpp" -#include "Timer.hpp" -#include "Trigger.hpp" -#include "Tryclops.hpp" -#include "VisorFlare.hpp" -#include "VisorGoo.hpp" -#include "WallCrawlerSwarm.hpp" -#include "Warwasp.hpp" -#include "Water.hpp" -#include "Waypoint.hpp" -#include "WorldLightFader.hpp" -#include "WorldTeleporter.hpp" - -namespace DataSpec::DNAMP1 { -namespace priv { -namespace { -constexpr ScriptObjectSpec ActorEnt = {0x00, []() -> IScriptObject* { return new struct Actor(); }}; -constexpr ScriptObjectSpec WaypointEnt = {0x02, []() -> IScriptObject* { return new struct Waypoint(); }}; -constexpr ScriptObjectSpec DoorAreaEnt = {0x03, []() -> IScriptObject* { return new struct DoorArea(); }}; -constexpr ScriptObjectSpec TriggerEnt = {0x04, []() -> IScriptObject* { return new struct Trigger(); }}; -constexpr ScriptObjectSpec TimerEnt = {0x05, []() -> IScriptObject* { return new struct Timer(); }}; -constexpr ScriptObjectSpec CounterEnt = {0x06, []() -> IScriptObject* { return new struct Counter(); }}; -constexpr ScriptObjectSpec EffectEnt = {0x07, []() -> IScriptObject* { return new struct Effect(); }}; -constexpr ScriptObjectSpec PlatformEnt = {0x08, []() -> IScriptObject* { return new struct Platform(); }}; -constexpr ScriptObjectSpec SoundEnt = {0x09, []() -> IScriptObject* { return new struct Sound(); }}; -constexpr ScriptObjectSpec GeneratorEnt = {0x0A, []() -> IScriptObject* { return new struct Generator(); }}; -constexpr ScriptObjectSpec DockEnt = {0x0B, []() -> IScriptObject* { return new struct Dock(); }}; -constexpr ScriptObjectSpec CameraEnt = {0x0C, []() -> IScriptObject* { return new struct Camera(); }}; -constexpr ScriptObjectSpec CameraWaypointEnt = {0x0D, []() -> IScriptObject* { return new struct CameraWaypoint(); }}; -constexpr ScriptObjectSpec NewIntroBossEnt = {0x0E, []() -> IScriptObject* { return new struct NewIntroBoss(); }}; -constexpr ScriptObjectSpec SpawnPointEnt = {0x0F, []() -> IScriptObject* { return new struct SpawnPoint(); }}; -constexpr ScriptObjectSpec CameraHintEnt = {0x10, []() -> IScriptObject* { return new struct CameraHint(); }}; -constexpr ScriptObjectSpec PickupEnt = {0x11, []() -> IScriptObject* { return new struct Pickup(); }}; -constexpr ScriptObjectSpec MemoryRelayEnt = {0x13, []() -> IScriptObject* { return new struct MemoryRelay(); }}; -constexpr ScriptObjectSpec RandomRelayEnt = {0x14, []() -> IScriptObject* { return new struct RandomRelay(); }}; -constexpr ScriptObjectSpec RelayEnt = {0x15, []() -> IScriptObject* { return new struct Relay(); }}; -constexpr ScriptObjectSpec BeetleEnt = {0x16, []() -> IScriptObject* { return new struct Beetle(); }}; -constexpr ScriptObjectSpec HUDMemoEnt = {0x17, []() -> IScriptObject* { return new struct HUDMemo(); }}; -constexpr ScriptObjectSpec CameraFilterKeyframeEnt = { - 0x18, []() -> IScriptObject* { return new struct CameraFilterKeyframe(); }}; -constexpr ScriptObjectSpec CameraBlurKeyframeEnt = {0x19, - []() -> IScriptObject* { return new struct CameraBlurKeyframe(); }}; -constexpr ScriptObjectSpec DamageableTriggerEnt = {0x1A, - []() -> IScriptObject* { return new struct DamageableTrigger(); }}; -constexpr ScriptObjectSpec DebrisEnt = {0x1B, []() -> IScriptObject* { return new struct Debris(); }}; -constexpr ScriptObjectSpec CameraShakerEnt = {0x1C, []() -> IScriptObject* { return new struct CameraShaker(); }}; -constexpr ScriptObjectSpec ActorKeyframeEnt = {0x1D, []() -> IScriptObject* { return new struct ActorKeyframe(); }}; -constexpr ScriptObjectSpec WaterEnt = {0x20, []() -> IScriptObject* { return new struct Water(); }}; -constexpr ScriptObjectSpec WarwaspEnt = {0x21, []() -> IScriptObject* { return new struct Warwasp(); }}; -constexpr ScriptObjectSpec SpacePirateEnt = {0x24, []() -> IScriptObject* { return new struct SpacePirate(); }}; -constexpr ScriptObjectSpec FlyingPirateEnt = {0x25, []() -> IScriptObject* { return new struct FlyingPirate(); }}; -constexpr ScriptObjectSpec ElitePirateEnt = {0x26, []() -> IScriptObject* { return new struct ElitePirate(); }}; -constexpr ScriptObjectSpec MetroidBetaEnt = {0x27, []() -> IScriptObject* { return new struct MetroidBeta(); }}; -constexpr ScriptObjectSpec ChozoGhostEnt = {0x28, []() -> IScriptObject* { return new struct ChozoGhost(); }}; -constexpr ScriptObjectSpec CoverPointEnt = {0x2A, []() -> IScriptObject* { return new struct CoverPoint(); }}; -constexpr ScriptObjectSpec SpiderBallWaypointEnt = {0x2C, - []() -> IScriptObject* { return new struct SpiderBallWaypoint(); }}; -constexpr ScriptObjectSpec BloodFlowerEnt = {0x2D, []() -> IScriptObject* { return new struct BloodFlower(); }}; -constexpr ScriptObjectSpec FlickerBatEnt = {0x2E, []() -> IScriptObject* { return new struct FlickerBat(); }}; -constexpr ScriptObjectSpec PathCameraEnt = {0x2F, []() -> IScriptObject* { return new struct PathCamera(); }}; -constexpr ScriptObjectSpec GrapplePointEnt = {0x30, []() -> IScriptObject* { return new struct GrapplePoint(); }}; -constexpr ScriptObjectSpec PuddleSporeEnt = {0x31, []() -> IScriptObject* { return new struct PuddleSpore(); }}; -constexpr ScriptObjectSpec DebugCameraWaypointEnt = { - 0x32, []() -> IScriptObject* { return new struct DebugCameraWaypoint(); }}; -constexpr ScriptObjectSpec SpiderBallAttractionSurfaceEnt = { - 0x33, []() -> IScriptObject* { return new struct SpiderBallAttractionSurface(); }}; -constexpr ScriptObjectSpec PuddleToadGammaEnt = {0x34, []() -> IScriptObject* { return new struct PuddleToadGamma(); }}; -constexpr ScriptObjectSpec DistanceFogEnt = {0x35, []() -> IScriptObject* { return new struct DistanceFog(); }}; -constexpr ScriptObjectSpec FireFleaEnt = {0x36, []() -> IScriptObject* { return new struct FireFlea(); }}; -constexpr ScriptObjectSpec MetareeAlphaEnt = {0x37, []() -> IScriptObject* { return new struct MetareeAlpha(); }}; -constexpr ScriptObjectSpec DockAreaChangeEnt = {0x38, []() -> IScriptObject* { return new struct DockAreaChange(); }}; -constexpr ScriptObjectSpec ActorRotateEnt = {0x39, []() -> IScriptObject* { return new struct ActorRotate(); }}; -constexpr ScriptObjectSpec SpecialFunctionEnt = {0x3A, []() -> IScriptObject* { return new struct SpecialFunction(); }}; -constexpr ScriptObjectSpec SpankWeedEnt = {0x3B, []() -> IScriptObject* { return new struct SpankWeed(); }}; -constexpr ScriptObjectSpec ParasiteEnt = {0x3D, []() -> IScriptObject* { return new struct Parasite(); }}; -constexpr ScriptObjectSpec PlayerHintEnt = {0x3E, []() -> IScriptObject* { return new struct PlayerHint(); }}; -constexpr ScriptObjectSpec RipperEnt = {0x3F, []() -> IScriptObject* { return new struct Ripper(); }}; -constexpr ScriptObjectSpec PickupGeneratorEnt = {0x40, []() -> IScriptObject* { return new struct PickupGenerator(); }}; -constexpr ScriptObjectSpec AIKeyframeEnt = {0x41, []() -> IScriptObject* { return new struct AIKeyframe(); }}; -constexpr ScriptObjectSpec PointOfInterestEnt = {0x42, []() -> IScriptObject* { return new struct PointOfInterest(); }}; -constexpr ScriptObjectSpec DroneEnt = {0x43, []() -> IScriptObject* { return new struct Drone(); }}; -constexpr ScriptObjectSpec MetroidAlphaEnt = {0x44, []() -> IScriptObject* { return new struct MetroidAlpha(); }}; -constexpr ScriptObjectSpec DebrisExtendedEnt = {0x45, []() -> IScriptObject* { return new struct DebrisExtended(); }}; -constexpr ScriptObjectSpec SteamEnt = {0x46, []() -> IScriptObject* { return new struct Steam(); }}; -constexpr ScriptObjectSpec RippleEnt = {0x47, []() -> IScriptObject* { return new struct Ripple(); }}; -constexpr ScriptObjectSpec BallTriggerEnt = {0x48, []() -> IScriptObject* { return new struct BallTrigger(); }}; -constexpr ScriptObjectSpec TargetingPointEnt = {0x49, []() -> IScriptObject* { return new struct TargetingPoint(); }}; -constexpr ScriptObjectSpec ElectroMagneticPulseEnt = { - 0x4A, []() -> IScriptObject* { return new struct ElectroMagneticPulse(); }}; -constexpr ScriptObjectSpec IceSheegothEnt = {0x4B, []() -> IScriptObject* { return new struct IceSheegoth(); }}; -constexpr ScriptObjectSpec PlayerActorEnt = {0x4C, []() -> IScriptObject* { return new struct PlayerActor(); }}; -constexpr ScriptObjectSpec FlaahgraEnt = {0x4D, []() -> IScriptObject* { return new struct Flaahgra(); }}; -constexpr ScriptObjectSpec AreaAttributesEnt = {0x4E, []() -> IScriptObject* { return new struct AreaAttributes(); }}; -constexpr ScriptObjectSpec FishCloudEnt = {0x4F, []() -> IScriptObject* { return new struct FishCloud(); }}; -constexpr ScriptObjectSpec FishCloudModifierEnt = {0x50, - []() -> IScriptObject* { return new struct FishCloudModifier(); }}; -constexpr ScriptObjectSpec VisorFlareEnt = {0x51, []() -> IScriptObject* { return new struct VisorFlare(); }}; -constexpr ScriptObjectSpec WorldTeleporterx52Ent = {0x52, - []() -> IScriptObject* { return new struct WorldTeleporter(); }}; -constexpr ScriptObjectSpec VisorGooEnt = {0x53, []() -> IScriptObject* { return new struct VisorGoo(); }}; -constexpr ScriptObjectSpec JellyZapEnt = {0x54, []() -> IScriptObject* { return new struct JellyZap(); }}; -constexpr ScriptObjectSpec ControllerActionEnt = {0x55, - []() -> IScriptObject* { return new struct ControllerAction(); }}; -constexpr ScriptObjectSpec SwitchEnt = {0x56, []() -> IScriptObject* { return new struct Switch(); }}; -constexpr ScriptObjectSpec PlayerStateChangeEnt = {0x57, - []() -> IScriptObject* { return new struct PlayerStateChange(); }}; -constexpr ScriptObjectSpec ThardusEnt = {0x58, []() -> IScriptObject* { return new struct Thardus(); }}; -constexpr ScriptObjectSpec WallCrawlerSwarmEnt = {0x5A, - []() -> IScriptObject* { return new struct WallCrawlerSwarm(); }}; -constexpr ScriptObjectSpec AIJumpPointEnt = {0x5B, []() -> IScriptObject* { return new struct AIJumpPoint(); }}; -constexpr ScriptObjectSpec FlaahgraTentacleEnt = {0x5C, - []() -> IScriptObject* { return new struct FlaahgraTentacle(); }}; -constexpr ScriptObjectSpec RoomAcousticsEnt = {0x5D, []() -> IScriptObject* { return new struct RoomAcoustics(); }}; -constexpr ScriptObjectSpec ColorModulateEnt = {0x5E, []() -> IScriptObject* { return new struct ColorModulate(); }}; -constexpr ScriptObjectSpec ThardusRockProjectileEnt = { - 0x5F, []() -> IScriptObject* { return new struct ThardusRockProjectile(); }}; -constexpr ScriptObjectSpec MidiEnt = {0x60, []() -> IScriptObject* { return new struct Midi(); }}; -constexpr ScriptObjectSpec StreamedAudioEnt = {0x61, []() -> IScriptObject* { return new struct StreamedAudio(); }}; -constexpr ScriptObjectSpec WorldTeleporterx62Ent = { - 0x62, []() -> IScriptObject* { return new struct WorldTeleporter(); }}; // o.o, no this is not a trick -constexpr ScriptObjectSpec RepulsorEnt = {0x63, []() -> IScriptObject* { return new struct Repulsor(); }}; -constexpr ScriptObjectSpec GunTurretEnt = {0x64, []() -> IScriptObject* { return new struct GunTurret(); }}; -constexpr ScriptObjectSpec FogVolumeEnt = {0x65, []() -> IScriptObject* { return new struct FogVolume(); }}; -constexpr ScriptObjectSpec BabygothEnt = {0x66, []() -> IScriptObject* { return new struct Babygoth(); }}; -constexpr ScriptObjectSpec EyeballEnt = {0x67, []() -> IScriptObject* { return new struct Eyeball(); }}; -constexpr ScriptObjectSpec RadialDamageEnt = {0x68, []() -> IScriptObject* { return new struct RadialDamage(); }}; -constexpr ScriptObjectSpec CameraPitchVolumeEnt = {0x69, - []() -> IScriptObject* { return new struct CameraPitchVolume(); }}; -constexpr ScriptObjectSpec EnvFxDensityControllerEnt = { - 0x6A, []() -> IScriptObject* { return new struct EnvFxDensityController(); }}; -constexpr ScriptObjectSpec MagdoliteEnt = {0x6B, []() -> IScriptObject* { return new struct Magdolite(); }}; -constexpr ScriptObjectSpec TeamAIMgrEnt = {0x6C, []() -> IScriptObject* { return new struct TeamAIMgr(); }}; -constexpr ScriptObjectSpec SnakeWeedSwarmEnt = {0x6D, []() -> IScriptObject* { return new struct SnakeWeedSwarm(); }}; -constexpr ScriptObjectSpec ActorContraptionEnt = {0x6E, - []() -> IScriptObject* { return new struct ActorContraption(); }}; -constexpr ScriptObjectSpec OculusEnt = {0x6F, []() -> IScriptObject* { return new struct Oculus(); }}; -constexpr ScriptObjectSpec GeemerEnt = {0x70, []() -> IScriptObject* { return new struct Geemer(); }}; -constexpr ScriptObjectSpec SpindleCameraEnt = {0x71, []() -> IScriptObject* { return new struct SpindleCamera(); }}; -constexpr ScriptObjectSpec AtomicAlphaEnt = {0x72, []() -> IScriptObject* { return new struct AtomicAlpha(); }}; -constexpr ScriptObjectSpec CameraHintTriggerEnt = {0x73, - []() -> IScriptObject* { return new struct CameraHintTrigger(); }}; -constexpr ScriptObjectSpec RumbleEffectEnt = {0x74, []() -> IScriptObject* { return new struct RumbleEffect(); }}; -constexpr ScriptObjectSpec AmbientAIEnt = {0x75, []() -> IScriptObject* { return new struct AmbientAI(); }}; -constexpr ScriptObjectSpec AtomicBetaEnt = {0x77, []() -> IScriptObject* { return new struct AtomicBeta(); }}; -constexpr ScriptObjectSpec IceZoomerEnt = {0x78, []() -> IScriptObject* { return new struct IceZoomer(); }}; -constexpr ScriptObjectSpec PufferEnt = {0x79, []() -> IScriptObject* { return new struct Puffer(); }}; -constexpr ScriptObjectSpec TryclopsEnt = {0x7A, []() -> IScriptObject* { return new struct Tryclops(); }}; -constexpr ScriptObjectSpec RidleyEnt = {0x7B, []() -> IScriptObject* { return new struct Ridley(); }}; -constexpr ScriptObjectSpec SeedlingEnt = {0x7C, []() -> IScriptObject* { return new struct Seedling(); }}; -constexpr ScriptObjectSpec ThermalHeatFaderEnt = {0x7D, - []() -> IScriptObject* { return new struct ThermalHeatFader(); }}; -constexpr ScriptObjectSpec BurrowerEnt = {0x7F, []() -> IScriptObject* { return new struct Burrower(); }}; -constexpr ScriptObjectSpec ScriptBeamEnt = {0x81, []() -> IScriptObject* { return new struct ScriptBeam(); }}; -constexpr ScriptObjectSpec WorldLightFaderEnt = {0x82, []() -> IScriptObject* { return new struct WorldLightFader(); }}; -constexpr ScriptObjectSpec MetroidPrimeStage2Ent = {0x83, - []() -> IScriptObject* { return new struct MetroidPrimeStage2(); }}; -constexpr ScriptObjectSpec MetroidPrimeStage1Ent = {0x84, - []() -> IScriptObject* { return new struct MetroidPrimeStage1(); }}; -constexpr ScriptObjectSpec MazeNodeEnt = {0x85, []() -> IScriptObject* { return new struct MazeNode(); }}; -constexpr ScriptObjectSpec OmegaPirateEnt = {0x86, []() -> IScriptObject* { return new struct OmegaPirate(); }}; -constexpr ScriptObjectSpec PhazonPoolEnt = {0x87, []() -> IScriptObject* { return new struct PhazonPool(); }}; -constexpr ScriptObjectSpec PhazonHealingNoduleEnt = { - 0x88, []() -> IScriptObject* { return new struct PhazonHealingNodule(); }}; -constexpr ScriptObjectSpec NewCameraShakerEnt = {0x89, []() -> IScriptObject* { return new struct NewCameraShaker(); }}; -constexpr ScriptObjectSpec ShadowProjectorEnt = {0x8A, []() -> IScriptObject* { return new struct ShadowProjector(); }}; -constexpr ScriptObjectSpec EnergyBallEnt = {0x8B, []() -> IScriptObject* { return new struct EnergyBall(); }}; -} // Anonymous namespace -} // namespace priv - -const ScriptObjectDBArray SCRIPT_OBJECT_DB = { - &priv::AIJumpPointEnt, - &priv::AIKeyframeEnt, - &priv::ActorEnt, - &priv::ActorContraptionEnt, - &priv::ActorKeyframeEnt, - &priv::ActorRotateEnt, - &priv::AmbientAIEnt, - &priv::AreaAttributesEnt, - &priv::AtomicAlphaEnt, - &priv::AtomicBetaEnt, - &priv::BabygothEnt, - &priv::BallTriggerEnt, - &priv::BeetleEnt, - &priv::BloodFlowerEnt, - &priv::BurrowerEnt, - &priv::CameraEnt, - &priv::CameraBlurKeyframeEnt, - &priv::CameraFilterKeyframeEnt, - &priv::CameraHintEnt, - &priv::CameraHintTriggerEnt, - &priv::CameraPitchVolumeEnt, - &priv::CameraShakerEnt, - &priv::CameraWaypointEnt, - &priv::ChozoGhostEnt, - &priv::ColorModulateEnt, - &priv::ControllerActionEnt, - &priv::CounterEnt, - &priv::CoverPointEnt, - &priv::DamageableTriggerEnt, - &priv::DebrisEnt, - &priv::DebrisExtendedEnt, - &priv::DebugCameraWaypointEnt, - &priv::DistanceFogEnt, - &priv::DockEnt, - &priv::DockAreaChangeEnt, - &priv::DoorAreaEnt, - &priv::DroneEnt, - &priv::EffectEnt, - &priv::ElectroMagneticPulseEnt, - &priv::ElitePirateEnt, - &priv::EnergyBallEnt, - &priv::EnvFxDensityControllerEnt, - &priv::EyeballEnt, - &priv::FireFleaEnt, - &priv::FishCloudEnt, - &priv::FishCloudModifierEnt, - &priv::FlaahgraEnt, - &priv::FlaahgraTentacleEnt, - &priv::FlickerBatEnt, - &priv::FlyingPirateEnt, - &priv::FogVolumeEnt, - &priv::GeemerEnt, - &priv::GeneratorEnt, - &priv::GrapplePointEnt, - &priv::GunTurretEnt, - &priv::HUDMemoEnt, - &priv::IceSheegothEnt, - &priv::IceZoomerEnt, - &priv::JellyZapEnt, - &priv::MagdoliteEnt, - &priv::MazeNodeEnt, - &priv::MemoryRelayEnt, - &priv::MetareeAlphaEnt, - &priv::MetroidAlphaEnt, - &priv::MetroidBetaEnt, - &priv::MetroidPrimeStage1Ent, - &priv::MetroidPrimeStage2Ent, - &priv::MidiEnt, - &priv::NewCameraShakerEnt, - &priv::NewIntroBossEnt, - &priv::OculusEnt, - &priv::OmegaPirateEnt, - &priv::ParasiteEnt, - &priv::PathCameraEnt, - &priv::PhazonHealingNoduleEnt, - &priv::PhazonPoolEnt, - &priv::PickupEnt, - &priv::PickupGeneratorEnt, - &priv::PlatformEnt, - &priv::PlayerActorEnt, - &priv::PlayerHintEnt, - &priv::PlayerStateChangeEnt, - &priv::PointOfInterestEnt, - &priv::PuddleSporeEnt, - &priv::PuddleToadGammaEnt, - &priv::PufferEnt, - &priv::RadialDamageEnt, - &priv::RandomRelayEnt, - &priv::RelayEnt, - &priv::RepulsorEnt, - &priv::RidleyEnt, - &priv::RipperEnt, - &priv::RippleEnt, - &priv::RoomAcousticsEnt, - &priv::RumbleEffectEnt, - &priv::ScriptBeamEnt, - &priv::SeedlingEnt, - &priv::ShadowProjectorEnt, - &priv::SnakeWeedSwarmEnt, - &priv::SoundEnt, - &priv::SpacePirateEnt, - &priv::SpankWeedEnt, - &priv::SpawnPointEnt, - &priv::SpecialFunctionEnt, - &priv::SpiderBallAttractionSurfaceEnt, - &priv::SpiderBallWaypointEnt, - &priv::SpindleCameraEnt, - &priv::SteamEnt, - &priv::StreamedAudioEnt, - &priv::SwitchEnt, - &priv::TargetingPointEnt, - &priv::TeamAIMgrEnt, - &priv::ThardusEnt, - &priv::ThardusRockProjectileEnt, - &priv::ThermalHeatFaderEnt, - &priv::TimerEnt, - &priv::TriggerEnt, - &priv::TryclopsEnt, - &priv::VisorFlareEnt, - &priv::VisorGooEnt, - &priv::WallCrawlerSwarmEnt, - &priv::WarwaspEnt, - &priv::WaterEnt, - &priv::WaypointEnt, - &priv::WorldLightFaderEnt, - &priv::WorldTeleporterx52Ent, - &priv::WorldTeleporterx62Ent, -}; - -zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& scale, const zeus::CVector3f& orientation, - const zeus::CVector3f& position) { - zeus::simd_floats f(orientation.mSimd); - return zeus::CTransform::RotateZ(zeus::degToRad(f[2])) * zeus::CTransform::RotateY(zeus::degToRad(f[1])) * - zeus::CTransform::RotateX(zeus::degToRad(f[0])) * zeus::CTransform::Scale(scale) + - position; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp b/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp deleted file mode 100644 index 53f118ef8..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IScriptObject.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once -#include "../../DNACommon/DNACommon.hpp" -#include "../DNAMP1.hpp" -#include "../SAVW.hpp" -#include "zeus/CAABox.hpp" - -#include - -namespace DataSpec::DNAMP1 { - -zeus::CTransform ConvertEditorEulerToTransform4f(const zeus::CVector3f& scale, const zeus::CVector3f& orientation, - const zeus::CVector3f& position); - -struct IScriptObject : BigDNAVYaml { - AT_DECL_DNA_YAMLV - atUint32 type; - Value id; - struct Connection : BigDNA { - AT_DECL_DNA_YAML - Value state; - Value msg; - Value target; - }; - - Value connectionCount; - Vector connections; - Value propertyCount; - ~IScriptObject() override = default; - - virtual void addCMDLRigPairs(PAKRouter&, CharacterAssociations& charAssoc) const {} - virtual void nameIDs(PAKRouter& pakRouter) const {} - virtual void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const {} - virtual void gatherScans(std::vector& scansOut) const {} - virtual zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const { return {}; } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IceSheegoth.hpp b/DataSpec/DNAMP1/ScriptObjects/IceSheegoth.hpp deleted file mode 100644 index 1df66c93a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IceSheegoth.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct IceSheegoth : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - DamageVulnerability damageVulnerabilty3; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - Value unknown5; - Value unknown6; - UniqueID32 wpsc2; - UniqueID32 particle1; - DamageInfo damageInfo2; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - UniqueID32 particle5; - UniqueID32 elsc; - Value unknown7; - Value unknown8; - DamageInfo damageInfo3; - Value soundID1; - Value unknown9; - Value unknown10; - Value unknown11; - UniqueID32 texture; - Value soundID2; - UniqueID32 particle6; - Value unknown12; - Value unknown13; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/IceZoomer.hpp b/DataSpec/DNAMP1/ScriptObjects/IceZoomer.hpp deleted file mode 100644 index b768f8b7f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/IceZoomer.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct IceZoomer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value advanceWpRadius; - Value unknown2; - Value alignAngleVel; - Value unknown4; - Value playerObstructionMinDist; - Value moveForwardWeight; - UniqueID32 modelRes; - UniqueID32 skinRes; - DamageVulnerability damageVulnerabilty; - Value unknown9; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - g_curSpec->flattenDependencies(modelRes, pathsOut); - g_curSpec->flattenDependencies(skinRes, pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/JellyZap.hpp b/DataSpec/DNAMP1/ScriptObjects/JellyZap.hpp deleted file mode 100644 index 26dacd35a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/JellyZap.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct JellyZap : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo damageInfo; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Magdolite.hpp b/DataSpec/DNAMP1/ScriptObjects/Magdolite.hpp deleted file mode 100644 index 0b690e242..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Magdolite.hpp +++ /dev/null @@ -1,83 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Magdolite : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - DamageInfo damageInfo1; - DamageInfo damageInfo2; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - UniqueID32 cmdlHeadless; - UniqueID32 cskrHeadless; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - struct MagdoliteParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value unknown1; - UniqueID32 particle; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - } magdoliteParameters; - Value unknown7; - Value unknown8; - Value unknown9; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - UniqueID32 cinf = patternedInfo.animationParameters.getCINF(pakRouter); - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - - if (cmdlHeadless.isValid() && cskrHeadless.isValid()) { - charAssoc.m_cmdlRigs[cmdlHeadless] = {cskrHeadless, cinf}; - charAssoc.m_cskrToCharacter[cskrHeadless] = - std::make_pair(patternedInfo.animationParameters.animationCharacterSet, - fmt::format(FMT_STRING("ATTACH.HEADLESS_{}.CSKR"), cskrHeadless)); - charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, {}, cmdlHeadless, "HEADLESS"); - } - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (cmdlHeadless.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cmdlHeadless); - ent->name = name + "_emodel"; - } - if (cskrHeadless.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cskrHeadless); - ent->name = name + "_eskin"; - } - if (magdoliteParameters.particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(magdoliteParameters.particle); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(cmdlHeadless, pathsOut); - g_curSpec->flattenDependencies(cskrHeadless, pathsOut); - g_curSpec->flattenDependencies(magdoliteParameters.particle, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MazeNode.hpp b/DataSpec/DNAMP1/ScriptObjects/MazeNode.hpp deleted file mode 100644 index b93a60691..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MazeNode.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MazeNode : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value col; - Value row; - Value side; - Value actorPos; - Value triggerPos; - Value effectPos; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MemoryRelay.hpp b/DataSpec/DNAMP1/ScriptObjects/MemoryRelay.hpp deleted file mode 100644 index 6b95a5788..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MemoryRelay.hpp +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MemoryRelay : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value skipSendActive; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetareeAlpha.hpp b/DataSpec/DNAMP1/ScriptObjects/MetareeAlpha.hpp deleted file mode 100644 index 7d96cc102..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetareeAlpha.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetareeAlpha : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageInfo damageInfo; - Value dropHeight; - Value offset; - Value attackSpeed; - Value delay; - Value unknown5; // Appears to be unused - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidAlpha.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidAlpha.hpp deleted file mode 100644 index 08c2126df..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidAlpha.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidAlpha : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - AnimationParameters animationParameters1; - AnimationParameters animationParameters2; - AnimationParameters animationParameters3; - AnimationParameters animationParameters4; - Value unknown8; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - animationParameters1.nameANCS(pakRouter, name + "_animp1"); - animationParameters2.nameANCS(pakRouter, name + "_animp2"); - animationParameters3.nameANCS(pakRouter, name + "_animp3"); - animationParameters4.nameANCS(pakRouter, name + "_animp4"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - animationParameters1.depANCS(pathsOut); - animationParameters2.depANCS(pathsOut); - animationParameters3.depANCS(pathsOut); - animationParameters4.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidBeta.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidBeta.hpp deleted file mode 100644 index 0b04c0562..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidBeta.hpp +++ /dev/null @@ -1,76 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidBeta : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - DamageVulnerability damageVulnerabilty1; - DamageVulnerability damageVulnerabilty2; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - UniqueID32 particle1; - UniqueID32 swhc; - UniqueID32 particle2; - UniqueID32 particle3; - UniqueID32 particle4; - Value unknown10; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (swhc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(swhc); - ent->name = name + "_swhc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(swhc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage1.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage1.hpp deleted file mode 100644 index f89f2be46..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage1.hpp +++ /dev/null @@ -1,303 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidPrimeStage1 : IScriptObject { - AT_DECL_DNA_YAMLV - Value version; - String<-1> name; - Value location; - Value orientation; - Value scale; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - HealthInfo healthInfo1; - HealthInfo healthInfo2; - Value unknown9; - - struct PrimeParameters1 : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - } primeStruct1[4]; - - Value unknown10; - Value unknown11; - - struct MassivePrimeStruct : BigDNA { - AT_DECL_DNA - Value propertyCount; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown2; - struct CameraShakeData : BigDNA { - AT_DECL_DNA - Value useSfx; - Value duration; - Value sfxDist; - struct CameraShakerComponent : BigDNA { - AT_DECL_DNA - Value useModulation; - struct CameraShakePoint : BigDNA { - AT_DECL_DNA - Value attackTime; - Value sustainTime; - Value duration; - Value magnitude; - }; - CameraShakePoint am; - CameraShakePoint fm; - } shakerComponents[3]; - } shakeDatas[3]; - - struct PrimeStruct2B : BigDNA { - AT_DECL_DNA - Value propertyCount; - UniqueID32 particle1; - UniqueID32 particle2; - UniqueID32 particle3; - DamageInfo damageInfo1; - Value unknown5; - Value unknown6; - UniqueID32 texture1; - Value unknown7; - Value unknown8; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (texture1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1); - ent->name = name + "_tex1"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(texture1, pathsOut); - } - } primeStruct2b; - - UniqueID32 particle4; - - struct PrimeStruct4 : BigDNA { - AT_DECL_DNA - BeamInfo beamInfo; - UniqueID32 wpsc; - DamageInfo damageInfo1; - struct PrimeStruct5 : BigDNA { - AT_DECL_DNA - Value propertyCount; - UniqueID32 unknown1; - Value unknown2; - UniqueID32 unknown3; - UniqueID32 unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (unknown1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown1); - ent->name = name + "_unk1"; - } - if (unknown3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown3); - ent->name = name + "_unk3"; - } - if (unknown4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown4); - ent->name = name + "_unk4"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(unknown1, pathsOut); - g_curSpec->flattenDependencies(unknown3, pathsOut); - g_curSpec->flattenDependencies(unknown4, pathsOut); - } - } primeStruct5; - Value unknown14; - DamageInfo damageInfo2; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - beamInfo.nameIDs(pakRouter, name + "_beamInfo"); - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - primeStruct5.nameIDs(pakRouter, name + "_prime5"); - } - - void depIDs(std::vector& pathsOut) const { - beamInfo.depIDs(pathsOut); - g_curSpec->flattenDependencies(wpsc, pathsOut); - primeStruct5.depIDs(pathsOut); - } - } primeStruct4s[4]; - - UniqueID32 wpsc1; - DamageInfo damageInfo2; - CameraShakeData primeStruct2_4; - UniqueID32 wpsc2; - DamageInfo damageInfo3; - CameraShakeData primeStruct2_5; - - struct PrimeProjectileInfo : BigDNA { - AT_DECL_DNA - Value propertyCount; - UniqueID32 particle; - DamageInfo damageInfo4; - Value unknown9; - Value unknown10; - Value unknown11; - UniqueID32 texture; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_tex"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - } - } projectileInfo; - - DamageInfo damageInfo5; - CameraShakeData primeStruct2_6; - UniqueID32 particle6; - UniqueID32 swhc; - UniqueID32 particle7; - UniqueID32 particle8; - - struct PrimeStruct6 : BigDNA { - AT_DECL_DNA - Value propertyCount; - DamageVulnerability damageVulnerability; - DNAColor unknown1; - Value unknown2; - Value unknown3; - } primeStruct6s[4]; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - primeStruct2b.nameIDs(pakRouter, name + "_prime2b"); - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - if (particle7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); - ent->name = name + "_part7"; - } - if (particle8.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle8); - ent->name = name + "_part8"; - } - if (swhc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(swhc); - ent->name = name + "_swhc"; - } - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - primeStruct4s[0].nameIDs(pakRouter, name + "_prime41"); - primeStruct4s[1].nameIDs(pakRouter, name + "_prime42"); - primeStruct4s[2].nameIDs(pakRouter, name + "_prime43"); - primeStruct4s[3].nameIDs(pakRouter, name + "_prime44"); - projectileInfo.nameIDs(pakRouter, name + "_projectileInfo"); - } - - void depIDs(std::vector& pathsOut, std::vector& lazyOut) const { - primeStruct2b.depIDs(pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - g_curSpec->flattenDependencies(particle7, pathsOut); - g_curSpec->flattenDependencies(particle8, pathsOut); - g_curSpec->flattenDependencies(swhc, pathsOut); - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - primeStruct4s[0].depIDs(pathsOut); - primeStruct4s[1].depIDs(pathsOut); - primeStruct4s[2].depIDs(pathsOut); - primeStruct4s[3].depIDs(pathsOut); - projectileInfo.depIDs(pathsOut); - } - - void scanIDs(std::vector& scansOut) const { actorParameters.scanIDs(scansOut); } - } massivePrimeStruct; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - massivePrimeStruct.actorParameters.addCMDLRigPairs(pakRouter, charAssoc, - massivePrimeStruct.patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - massivePrimeStruct.nameIDs(pakRouter, name + "_massiveStruct"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - massivePrimeStruct.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { massivePrimeStruct.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage2.hpp b/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage2.hpp deleted file mode 100644 index 5ca1e250d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/MetroidPrimeStage2.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct MetroidPrimeStage2 : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 particle1; - DamageInfo damageInfo; - UniqueID32 elsc; - Value unknown; - UniqueID32 particle2; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Midi.hpp b/DataSpec/DNAMP1/ScriptObjects/Midi.hpp deleted file mode 100644 index 99bcb9413..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Midi.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Midi : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - UniqueID32 song; - Value fadeInTime; - Value fadeOutTime; - Value volume; - - void nameIDs(PAKRouter& pakRouter) const override { - if (song.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(song); - ent->name = name + "_song"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - // Dedicated PAK for this - // g_curSpec->flattenDependencies(song, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp b/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp deleted file mode 100644 index 747ebbe16..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/NewCameraShaker.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct NewCameraShaker : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - PropertyFlags flags; - Value duration; - Value sfxDist; - struct CameraShakerComponent : BigDNA { - AT_DECL_DNA - PropertyFlags flags; - struct CameraShakePoint : BigDNA { - AT_DECL_DNA - PropertyFlags flags; - Value attackTime; - Value sustainTime; - Value duration; - Value magnitude; - }; - CameraShakePoint am; - CameraShakePoint fm; - } shakerComponents[3]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp b/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp deleted file mode 100644 index 23174930d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/NewIntroBoss.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct NewIntroBoss : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value minTurnAngle; - UniqueID32 weaponDesc; - DamageInfo damageInfo; - UniqueID32 beamContactFxId; - UniqueID32 beamPulseFxId; - UniqueID32 beamTextureId; - UniqueID32 beamGlowTextureId; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (beamContactFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamContactFxId); - ent->name = name + "_beamContactFxId"; - } - if (beamPulseFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamPulseFxId); - ent->name = name + "_beamPulseFxId"; - } - if (beamTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamTextureId); - ent->name = name + "_beamTextureId"; - } - if (beamGlowTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamGlowTextureId); - ent->name = name + "_beamGlowTextureId"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(weaponDesc, pathsOut); - g_curSpec->flattenDependencies(beamContactFxId, pathsOut); - g_curSpec->flattenDependencies(beamPulseFxId, pathsOut); - g_curSpec->flattenDependencies(beamTextureId, pathsOut); - g_curSpec->flattenDependencies(beamGlowTextureId, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Oculus.cpp b/DataSpec/DNAMP1/ScriptObjects/Oculus.cpp deleted file mode 100644 index 158db716f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Oculus.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "Oculus.hpp" - -namespace DataSpec::DNAMP1 { - -template -void Oculus::Enumerate(typename Op::StreamT& s) { - IScriptObject::Enumerate(s); - Do(athena::io::PropId{"name"}, name, s); - Do(athena::io::PropId{"location"}, location, s); - Do(athena::io::PropId{"orientation"}, orientation, s); - Do(athena::io::PropId{"scale"}, scale, s); - Do(athena::io::PropId{"patternedInfo"}, patternedInfo, s); - Do(athena::io::PropId{"actorParameters"}, actorParameters, s); - Do(athena::io::PropId{"unknown1"}, unknown1, s); - Do(athena::io::PropId{"unknown2"}, unknown2, s); - Do(athena::io::PropId{"unknown3"}, unknown3, s); - Do(athena::io::PropId{"unknown4"}, unknown4, s); - Do(athena::io::PropId{"unknown5"}, unknown5, s); - Do(athena::io::PropId{"unknown6"}, unknown6, s); - Do(athena::io::PropId{"damageVulnerabilty"}, damageVulnerabilty, s); - Do(athena::io::PropId{"unknown7"}, unknown7, s); - Do(athena::io::PropId{"damageInfo"}, damageInfo, s); - if (propertyCount == 16) - Do(athena::io::PropId{"unknown8"}, unknown8, s); - else - unknown8 = 0.f; -} - -std::string_view Oculus::DNAType() { return "DNAMP1::Oculus"sv; } - -AT_SPECIALIZE_DNA_YAML(Oculus) - -} // namespace DataSpec::DNAMP1 \ No newline at end of file diff --git a/DataSpec/DNAMP1/ScriptObjects/Oculus.hpp b/DataSpec/DNAMP1/ScriptObjects/Oculus.hpp deleted file mode 100644 index ee69e2d5f..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Oculus.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Oculus : IScriptObject { - AT_DECL_EXPLICIT_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - DamageVulnerability damageVulnerabilty; - Value unknown7; - DamageInfo damageInfo; - - /* Trilogy addition */ - Value unknown8; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/OmegaPirate.hpp b/DataSpec/DNAMP1/ScriptObjects/OmegaPirate.hpp deleted file mode 100644 index c65cf752c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/OmegaPirate.hpp +++ /dev/null @@ -1,149 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct OmegaPirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters1; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - UniqueID32 particle1; - Value soundID1; - ActorParameters actorParameters2; - AnimationParameters animationParameters; - UniqueID32 particle2; - Value soundID2; - UniqueID32 model1; - DamageInfo damageInfo1; - Value unknown9; - UniqueID32 particle3; - UniqueID32 particle4; - UniqueID32 particle5; - UniqueID32 particle6; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value soundID3; - Value soundID4; - UniqueID32 particle7; - DamageInfo damageInfo2; - UniqueID32 elsc; - Value soundID5; - Value unknown17; - Value unknown18; - UniqueID32 cmdlPhazonVeins; - UniqueID32 cskrPhazonVeins; - UniqueID32 cinfPhazonVeins; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters1.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - actorParameters2.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - if (cmdlPhazonVeins.isValid() && cskrPhazonVeins.isValid() && cinfPhazonVeins.isValid()) { - charAssoc.m_cmdlRigs[cmdlPhazonVeins] = {cskrPhazonVeins, cinfPhazonVeins}; - charAssoc.m_cskrToCharacter[cskrPhazonVeins] = - std::make_pair(patternedInfo.animationParameters.animationCharacterSet, - fmt::format(FMT_STRING("ATTACH.VEINS_{}.CSKR"), cskrPhazonVeins)); - charAssoc.addAttachmentRig(patternedInfo.animationParameters.animationCharacterSet, cinfPhazonVeins, - cmdlPhazonVeins, "VEINS"); - } - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (particle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle3); - ent->name = name + "_part3"; - } - if (particle4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle4); - ent->name = name + "_part4"; - } - if (particle5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle5); - ent->name = name + "_part5"; - } - if (particle6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle6); - ent->name = name + "_part6"; - } - if (particle7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle7); - ent->name = name + "_part7"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - if (model1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model1); - ent->name = name + "_model1"; - } - if (cmdlPhazonVeins.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cmdlPhazonVeins); - ent->name = name + "_model2"; - } - if (cskrPhazonVeins.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cskrPhazonVeins); - ent->name = name + "_skin"; - } - if (cinfPhazonVeins.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(cinfPhazonVeins); - ent->name = name + "_rig"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters1.nameIDs(pakRouter, name + "_actp1"); - actorParameters2.nameIDs(pakRouter, name + "_actp2"); - animationParameters.nameANCS(pakRouter, name + "_animp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(particle3, pathsOut); - g_curSpec->flattenDependencies(particle4, pathsOut); - g_curSpec->flattenDependencies(particle5, pathsOut); - g_curSpec->flattenDependencies(particle6, pathsOut); - g_curSpec->flattenDependencies(particle7, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - g_curSpec->flattenDependencies(model1, pathsOut); - g_curSpec->flattenDependencies(cmdlPhazonVeins, pathsOut); - g_curSpec->flattenDependencies(cskrPhazonVeins, pathsOut); - g_curSpec->flattenDependencies(cinfPhazonVeins, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters1.depIDs(pathsOut, lazyOut); - actorParameters2.depIDs(pathsOut, lazyOut); - animationParameters.depANCS(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { - actorParameters1.scanIDs(scansOut); - actorParameters2.scanIDs(scansOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Parameters.cpp b/DataSpec/DNAMP1/ScriptObjects/Parameters.cpp deleted file mode 100644 index 8fbb0a3d7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Parameters.cpp +++ /dev/null @@ -1,19 +0,0 @@ -#include "Parameters.hpp" -#include "../ANCS.hpp" - -namespace DataSpec::DNAMP1 { - -UniqueID32 AnimationParameters::getCINF(PAKRouter& pakRouter) const { - if (!animationCharacterSet.isValid()) - return UniqueID32(); - const nod::Node* node; - const PAK::Entry* ancsEnt = pakRouter.lookupEntry(animationCharacterSet, &node); - ANCS ancs; - { - PAKEntryReadStream rs = ancsEnt->beginReadStream(*node); - ancs.read(rs); - } - return ancs.characterSet.characters.at(character).cinf; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp b/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp deleted file mode 100644 index 15a7abecb..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Parameters.hpp +++ /dev/null @@ -1,471 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "../DNAMP1.hpp" -#include "../SAVW.hpp" - -namespace DataSpec::DNAMP1 { - -enum class EPickupType : atUint32 { - PowerBeam = 0, - IceBeam = 1, - WaveBeam = 2, - PlasmaBeam = 3, - Missile = 4, - ScanVisor = 5, - MorphBallBomb = 6, - PowerBomb = 7, - Flamethrower = 8, - ThermalVisor = 9, - ChargeBeam = 10, - SuperMissile = 11, - GrappleBeam = 12, - XRayVisor = 13, - IceSpreader = 14, - SpaceJump = 15, - MorphBall = 16, - CombatVisor = 17, - BoostBall = 18, - SpiderBall = 19, - PowerSuit = 20, - GravitySuit = 21, - VariaSuit = 22, - PhazonSuit = 23, - EnergyTank = 24, - UnknownItem1 = 25, - HealthRefill = 26, - UnknownItem2 = 27, - WaveBuster = 28, - Truth = 29, - Strength = 30, - Elder = 31, - Wild = 32, - LifeGiver = 33, - Warrior = 34, - Chozo = 35, - Nature = 36, - Sun = 37, - World = 38, - Spirit = 39, - Newborn = 40 -}; - -enum class ESpecialFunctionType : atUint32 { - What, - PlayerFollowLocator, - SpinnerController, - ObjectFollowLocator, - ChaffTarget, - InventoryActivator, - MapStation, - SaveStation, - IntroBossRingController, - ViewFrustumTest, - ShotSpinnerController, - EscapeSequence, - BossEnergyBar, - EndGame, - HUDFadeIn, - CinematicSkip, - ScriptLayerController, - RainSimulator, - AreaDamage, - ObjectFollowObject, - HintSystem, - DropBomb, - ScaleActor, - MissileStation, - Billboard, - PlayerInAreaRelay, - HUDTarget, - FogFader, - EnterLogbook, - PowerBombStation, - Ending, - FusionRelay, - WeaponSwitch // PAL Only -}; - -struct AnimationParameters : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 animationCharacterSet; - Value character; - Value defaultAnimation; - - UniqueID32 getCINF(PAKRouter& pakRouter) const; - - void nameANCS(PAKRouter& pakRouter, const std::string& name) const { - if (!animationCharacterSet.isValid()) - return; - PAK::Entry* ancsEnt = (PAK::Entry*)pakRouter.lookupEntry(animationCharacterSet); - if (ancsEnt->name.empty()) - ancsEnt->name = name; - } - - void depANCS(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(animationCharacterSet, pathsOut, character); - } - - void depANCSAll(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(animationCharacterSet, pathsOut); - } -}; - -struct BehaveChance : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; -}; - -struct DamageInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value weaponType; - Value damage; - Value radius; - Value knockbackPower; -}; - -struct DamageVulnerability : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value power; - Value ice; - Value wave; - Value plasma; - Value bomb; - Value powerBomb; - Value missile; - Value boostBall; - Value phazon; - Value enemyWeapon1; - Value enemyWeapon2Poison; - Value enemyWeapon3Lava; - Value enemyWeapon4; - Value unkownWeapon1; - Value unkownWeapon2; - Value deflected; - struct ChargedBeams : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value power; - Value ice; - Value wave; - Value plasma; - Value deflected; - } chargedBeams; - - struct BeamCombos : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value superMissiles; - Value iceSpreader; - Value wavebuster; - Value flameThrower; - Value deflected; - } beamCombos; -}; - -struct FlareDefinition : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - UniqueID32 texture; - Value unknown1; - Value unknown2; - Value unknown4; // CColor - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - } - - void depIDs(std::vector& pathsOut) const { g_curSpec->flattenDependencies(texture, pathsOut); } -}; - -struct GrappleParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value disableTurning; -}; - -struct HealthInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value health; - Value knockbackResistance; -}; - -struct LightParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value castShadow; - Value shadowScale; - Value shadowTesselation; - Value shadowAlpha; - Value maxShadowHeight; - Value ambientColor; // CColor - Value makeLights; - Value worldLightingOptions; - Value lightRecalculation; - Value lightingPositionOffset; - Value numDynamicLights; - Value numAreaLights; - Value ambientChannelOverflow; - Value layerIndex; -}; - -struct PatternedInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value mass; - Value speed; - Value turnSpeed; - Value detectionRange; - Value detectionHeightRange; - Value dectectionAngle; - Value minAttackRange; - Value maxAttackRange; - Value averageAttackTime; - Value attackTimeVariation; - Value leashRadius; - Value playerLeashRadius; - Value playerLeashTime; - DamageInfo contactDamage; - Value damageWaitTime; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - Value halfExtent; - Value height; - Value bodyOrigin; - Value stepUpHeight; - Value xDamage; - Value frozenXDamage; - Value xDamageDelay; - Value deathSfx; - AnimationParameters animationParameters; - Value active; - UniqueID32 stateMachine; - Value intoFreezeDur; - Value outOfFreezeDur; - Value unknown10; - Value pathfindingIndex; - Value particle1Scale; - UniqueID32 particle1; - UniqueID32 electric; - Value particle2Scale; - UniqueID32 particle2; - Value iceShatterSfx; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - animationParameters.nameANCS(pakRouter, name + "_animp"); - if (stateMachine.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(stateMachine); - ent->name = name + "_fsm"; - } - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (electric.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric); - ent->name = name + "_elsc"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - } - - void depIDs(std::vector& pathsOut) const { - animationParameters.depANCS(pathsOut); - g_curSpec->flattenDependencies(stateMachine, pathsOut); - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(electric, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - } -}; - -struct PlayerHintParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value unknown2; - Value extendTargetDistance; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; -}; - -struct ScannableParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - UniqueID32 scanId; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (scanId.isValid()) { - PAK::Entry* scanEnt = (PAK::Entry*)pakRouter.lookupEntry(scanId); - scanEnt->name = name + "_scan"; - } - } - - void depIDs(std::vector& pathsOut) const { g_curSpec->flattenDependencies(scanId, pathsOut); } - - void scanIDs(std::vector& scansOut) const { scansOut.emplace_back(scanId); } -}; - -struct VisorParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value unknown1; - Value scanPassthrough; - Value visorMask; -}; - -struct PropertyFlags : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Vector bools; -}; - -struct ActorParameters : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - LightParameters lightParameters; - ScannableParameters scannableParameters; - UniqueID32 cmdlXray; - UniqueID32 cskrXray; - UniqueID32 cmdlThermal; - UniqueID32 cskrThermal; - Value globalTimeProvider; - Value fadeInTime; - Value fadeOutTime; - VisorParameters visorParameters; - Value thermalHeat; - Value renderUnsorted; - Value noSortThermal; - Value thermalMag; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc, - const AnimationParameters& animParms) const { - auto cinf = animParms.getCINF(pakRouter); - if (cmdlXray.isValid() && cskrXray.isValid()) { - charAssoc.m_cmdlRigs[cmdlXray] = {cskrXray, cinf}; - charAssoc.m_cskrToCharacter[cskrXray] = - std::make_pair(animParms.animationCharacterSet, fmt::format(FMT_STRING("ATTACH.XRAY_{}.CSKR"), cskrXray)); - charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlXray, "XRAY"); - } - if (cmdlThermal.isValid() && cskrThermal.isValid()) { - charAssoc.m_cmdlRigs[cmdlThermal] = {cskrThermal, cinf}; - charAssoc.m_cskrToCharacter[cskrThermal] = std::make_pair( - animParms.animationCharacterSet, fmt::format(FMT_STRING("ATTACH.THERMAL_{}.CSKR"), cskrThermal)); - charAssoc.addAttachmentRig(animParms.animationCharacterSet, {}, cmdlThermal, "THERMAL"); - } - } - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - scannableParameters.nameIDs(pakRouter, name); - if (cmdlXray.isValid()) { - PAK::Entry* xmEnt = (PAK::Entry*)pakRouter.lookupEntry(cmdlXray); - xmEnt->name = name + "_xraymodel"; - } - if (cskrXray.isValid()) { - PAK::Entry* xsEnt = (PAK::Entry*)pakRouter.lookupEntry(cskrXray); - xsEnt->name = name + "_xrayskin"; - } - if (cmdlThermal.isValid()) { - PAK::Entry* xmEnt = (PAK::Entry*)pakRouter.lookupEntry(cmdlThermal); - xmEnt->name = name + "_thermalmodel"; - } - if (cskrThermal.isValid()) { - PAK::Entry* xsEnt = (PAK::Entry*)pakRouter.lookupEntry(cskrThermal); - xsEnt->name = name + "_thermalskin"; - } - } - - void depIDs(std::vector& pathsOut, std::vector& lazyOut) const { - scannableParameters.depIDs(lazyOut); - g_curSpec->flattenDependencies(cmdlXray, pathsOut); - g_curSpec->flattenDependencies(cskrXray, pathsOut); - g_curSpec->flattenDependencies(cmdlThermal, pathsOut); - g_curSpec->flattenDependencies(cskrThermal, pathsOut); - } - - void scanIDs(std::vector& scansOut) const { scannableParameters.scanIDs(scansOut); } -}; - -struct BeamInfo : BigDNA { - AT_DECL_DNA_YAML - Value propertyCount; - Value beamAttributes; - UniqueID32 contactFxId; - UniqueID32 pulseFxId; - UniqueID32 textureId; - UniqueID32 glowTextureId; - Value length; - Value radius; - Value expansionSpeed; - Value lifeTime; - Value pulseSpeed; - Value shutdownTime; - Value contactFxScale; - Value pulseFxScale; - Value travelSpeed; - DNAColor innerColor; - DNAColor outerColor; - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (contactFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(contactFxId); - ent->name = name + "_part1"; - } - if (pulseFxId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(pulseFxId); - ent->name = name + "_part2"; - } - if (textureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(textureId); - ent->name = name + "_tex1"; - } - if (glowTextureId.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(glowTextureId); - ent->name = name + "_tex2"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(contactFxId, pathsOut); - g_curSpec->flattenDependencies(pulseFxId, pathsOut); - g_curSpec->flattenDependencies(textureId, pathsOut); - g_curSpec->flattenDependencies(glowTextureId, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Parasite.hpp b/DataSpec/DNAMP1/ScriptObjects/Parasite.hpp deleted file mode 100644 index e748bd5af..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Parasite.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Parasite : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value maxTelegraphReactDist; - Value advanceWpRadius; - Value unknown4; - Value alignAngVel; - Value unknown6; - Value stuckTimeThreshold; - Value collisionCloseMargin; - Value parasiteSearchRadius; - Value parasiteSeparationDist; - Value parasiteSeparationWeight; - Value parasiteAlignmentWeight; - Value parasiteCohesionWeight; - Value destinationSeekWeight; - Value forwardMoveWeight; - Value playerSeparationDist; - Value playerSeparationWeight; - Value playerObstructionMinDist; - Value disableMove; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PathCamera.hpp b/DataSpec/DNAMP1/ScriptObjects/PathCamera.hpp deleted file mode 100644 index e63b82501..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PathCamera.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PathCamera : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - struct CameraParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value closedLoop; - Value noFilter; - Value tangentOrientation; - Value easeDist; - Value useHintLookZ; - Value clampToClosedDoor; - } cameraParameters; - - Value lengthExtent; - Value filterMag; - Value filterProportion; - Value initPos; - Value minEaseDist; - Value maxEaseDist; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PhazonHealingNodule.hpp b/DataSpec/DNAMP1/ScriptObjects/PhazonHealingNodule.hpp deleted file mode 100644 index 4106f2525..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PhazonHealingNodule.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PhazonHealingNodule : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - UniqueID32 elsc; - String<-1> unknown2; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PhazonPool.hpp b/DataSpec/DNAMP1/ScriptObjects/PhazonPool.hpp deleted file mode 100644 index 608be50e2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PhazonPool.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PhazonPool : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value unknown1; - UniqueID32 model1; - UniqueID32 model2; - UniqueID32 particle1; - UniqueID32 particle2; - Value unknown2; - DamageInfo damageInfo; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (model1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model1); - ent->name = name + "_model1"; - } - if (model2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model2); - ent->name = name + "_model2"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(model1, pathsOut); - g_curSpec->flattenDependencies(model2, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp b/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp deleted file mode 100644 index fe70a5049..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Pickup.hpp +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct Pickup : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value hitboxVolume; - Value scanPosition; - Value pickupType; - Value capacity; - Value amount; - Value possibility; - Value lifeTime; - Value fadeInTime; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value active; - Value startDelay; - UniqueID32 pickupParticle; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (pickupParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(pickupParticle); - ent->name = name + "_part"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(pickupParticle, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PickupGenerator.hpp b/DataSpec/DNAMP1/ScriptObjects/PickupGenerator.hpp deleted file mode 100644 index baf4aa9a0..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PickupGenerator.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PickupGenerator : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value offset; - Value active; - Value frequency; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Platform.cpp b/DataSpec/DNAMP1/ScriptObjects/Platform.cpp deleted file mode 100644 index a468a110b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Platform.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "Platform.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP1 { - -zeus::CAABox Platform::getVISIAABB(hecl::blender::Token& btok) const { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - zeus::CAABox aabbOut; - - if (model.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(model); - conn.openBlend(path); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } else if (animationParameters.animationCharacterSet.isValid()) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(animationParameters.animationCharacterSet); - conn.openBlend(path.getWithExtension(".blend", true)); - hecl::blender::DataStream ds = conn.beginData(); - auto aabb = ds.getMeshAABB(); - aabbOut = zeus::CAABox(aabb.first, aabb.second); - } - - if (aabbOut.min.x() > aabbOut.max.x()) - return {}; - - zeus::CTransform xf = ConvertEditorEulerToTransform4f(scale, orientation, location); - return aabbOut.getTransformedAABox(xf); -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Platform.hpp b/DataSpec/DNAMP1/ScriptObjects/Platform.hpp deleted file mode 100644 index ddb88e5f2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Platform.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Platform : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value extent; - Value collisionCenter; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value speed; - Value active; - UniqueID32 dcln; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value detectCollision; - Value xrayAlpha; - Value rainSplashes; - Value maxRainSplashes; - Value rainGenRate; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (dcln.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(dcln); - ent->name = name + "_dcln"; - } - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(dcln, pathsOut); - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PlayerActor.hpp b/DataSpec/DNAMP1/ScriptObjects/PlayerActor.hpp deleted file mode 100644 index 46081d82b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PlayerActor.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PlayerActor : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value boxExtents; - Value boxOffset; - Value mass; - Value zMomentum; - HealthInfo healthInfo; - DamageVulnerability damageVulnerability; - UniqueID32 model; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value loop; - Value snow; - Value solid; - Value active; - PropertyFlags playerParameters; - Value beamId; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - animationParameters.depANCSAll(lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PlayerHint.hpp b/DataSpec/DNAMP1/ScriptObjects/PlayerHint.hpp deleted file mode 100644 index bb6ff2fb2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PlayerHint.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PlayerHint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - PlayerHintParameters playerHintParameters; - Value priority; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PlayerStateChange.hpp b/DataSpec/DNAMP1/ScriptObjects/PlayerStateChange.hpp deleted file mode 100644 index ea3ebf4de..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PlayerStateChange.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PlayerStateChange : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value item; - Value itemCount; - Value itemCapacity; - Value control; - Value controlCommandOption; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PointOfInterest.hpp b/DataSpec/DNAMP1/ScriptObjects/PointOfInterest.hpp deleted file mode 100644 index 59ab42b40..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PointOfInterest.hpp +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PointOfInterest : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - ScannableParameters scannableParameters; - Value pointSize; - - void nameIDs(PAKRouter& pakRouter) const override { - scannableParameters.nameIDs(pakRouter, name + "_scanp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - scannableParameters.depIDs(lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { scannableParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PuddleSpore.hpp b/DataSpec/DNAMP1/ScriptObjects/PuddleSpore.hpp deleted file mode 100644 index fb5dc119e..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PuddleSpore.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PuddleSpore : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown2; - UniqueID32 particle; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - UniqueID32 wpsc; - DamageInfo damageInfo; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(wpsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/PuddleToadGamma.hpp b/DataSpec/DNAMP1/ScriptObjects/PuddleToadGamma.hpp deleted file mode 100644 index ba5a71b6a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/PuddleToadGamma.hpp +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct PuddleToadGamma : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value suckForceMultiplier; - Value suckAngle; - Value playerSuckRange; - Value localShootDir; - Value playerShootSpeed; - Value shouldAttackWaitTime; - Value spotPlayerWaitTime; - DamageInfo playerShootDamage; - DamageInfo damageInfo2; - UniqueID32 dcln; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (dcln.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(dcln); - ent->name = name + "_dcln"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(dcln, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Puffer.hpp b/DataSpec/DNAMP1/ScriptObjects/Puffer.hpp deleted file mode 100644 index 0865c51a1..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Puffer.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Puffer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - UniqueID32 particle; - DamageInfo damageInfo1; - UniqueID32 texture; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - DamageInfo damageInfo2; - Value unknown6; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RadialDamage.hpp b/DataSpec/DNAMP1/ScriptObjects/RadialDamage.hpp deleted file mode 100644 index 942d2a0b6..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RadialDamage.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RadialDamage : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - DamageInfo damageInfo; - Value radius; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RandomRelay.hpp b/DataSpec/DNAMP1/ScriptObjects/RandomRelay.hpp deleted file mode 100644 index 6ad61808d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RandomRelay.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RandomRelay : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value sendSetSize; - Value sendSetVariance; - Value percentSize; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Relay.hpp b/DataSpec/DNAMP1/ScriptObjects/Relay.hpp deleted file mode 100644 index 6a29f6c9a..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Relay.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Relay : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Repulsor.hpp b/DataSpec/DNAMP1/ScriptObjects/Repulsor.hpp deleted file mode 100644 index 4b7d4befa..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Repulsor.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Repulsor : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - Value radius; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ridley.cpp b/DataSpec/DNAMP1/ScriptObjects/Ridley.cpp deleted file mode 100644 index 1fff77f17..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ridley.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "Ridley.hpp" - -namespace DataSpec::DNAMP1 { - -template -void Ridley::Enumerate(typename Op::StreamT& s) { - IScriptObject::Enumerate(s); - Do(athena::io::PropId{"name"}, name, s); - Do(athena::io::PropId{"location"}, location, s); - Do(athena::io::PropId{"orientation"}, orientation, s); - Do(athena::io::PropId{"scale"}, scale, s); - Do(athena::io::PropId{"patternedInfo"}, patternedInfo, s); - Do(athena::io::PropId{"actorParameters"}, actorParameters, s); - Do(athena::io::PropId{"model1"}, model1, s); - Do(athena::io::PropId{"model2"}, model2, s); - if (propertyCount == 48) { - Do(athena::io::PropId{"model3"}, model3, s); - Do(athena::io::PropId{"model4"}, model4, s); - Do(athena::io::PropId{"model5"}, model5, s); - Do(athena::io::PropId{"model6"}, model6, s); - Do(athena::io::PropId{"model7"}, model7, s); - Do(athena::io::PropId{"model8"}, model8, s); - Do(athena::io::PropId{"model9"}, model9, s); - Do(athena::io::PropId{"model10"}, model10, s); - Do(athena::io::PropId{"model11"}, model11, s); - Do(athena::io::PropId{"model12"}, model12, s); - } - Do(athena::io::PropId{"particle"}, particle, s); - Do(athena::io::PropId{"unknown1"}, unknown1, s); - Do(athena::io::PropId{"unknown2"}, unknown2, s); - Do(athena::io::PropId{"unknown3"}, unknown3, s); - Do(athena::io::PropId{"unknown4"}, unknown4, s); - Do(athena::io::PropId{"wpsc1"}, wpsc1, s); - Do(athena::io::PropId{"damageInfo1"}, damageInfo1, s); - Do(athena::io::PropId{"ridleyStruct1"}, ridleyStruct1, s); - Do(athena::io::PropId{"soundID1"}, soundID1, s); - Do(athena::io::PropId{"wpsc2"}, wpsc2, s); - if (propertyCount == 40) - Do(athena::io::PropId{"wpsc3"}, wpsc3, s); - Do(athena::io::PropId{"damageInfo2"}, damageInfo2, s); - Do(athena::io::PropId{"ridleyStruct2_1"}, ridleyStruct2_1, s); - Do(athena::io::PropId{"wpsc4"}, wpsc4, s); - Do(athena::io::PropId{"damageInfo3"}, damageInfo3, s); - Do(athena::io::PropId{"ridleyStruct2_2"}, ridleyStruct2_2, s); - Do(athena::io::PropId{"soundID2"}, soundID2, s); - Do(athena::io::PropId{"damageInfo4"}, damageInfo4, s); - Do(athena::io::PropId{"ridleyStruct2_3"}, ridleyStruct2_3, s); - Do(athena::io::PropId{"unknown5"}, unknown5, s); - Do(athena::io::PropId{"unknown6"}, unknown6, s); - Do(athena::io::PropId{"damageInfo5"}, damageInfo5, s); - Do(athena::io::PropId{"unknown7"}, unknown7, s); - Do(athena::io::PropId{"damageInfo6"}, damageInfo6, s); - Do(athena::io::PropId{"unknown8"}, unknown8, s); - Do(athena::io::PropId{"damageInfo7"}, damageInfo7, s); - Do(athena::io::PropId{"unknown9"}, unknown9, s); - Do(athena::io::PropId{"elsc"}, elsc, s); - Do(athena::io::PropId{"unknown10"}, unknown10, s); - Do(athena::io::PropId{"soundID3"}, soundID3, s); - Do(athena::io::PropId{"damageInfo8"}, damageInfo8, s); - if (propertyCount == 40) - Do(athena::io::PropId{"damageInfo9"}, damageInfo9, s); -} - -std::string_view Ridley::DNAType() { return "DNAMP1::Ridley"sv; } - -AT_SPECIALIZE_DNA_YAML(Ridley) - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ridley.hpp b/DataSpec/DNAMP1/ScriptObjects/Ridley.hpp deleted file mode 100644 index 5bf6ad001..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ridley.hpp +++ /dev/null @@ -1,231 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Ridley : IScriptObject { - AT_DECL_EXPLICIT_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 model1; - UniqueID32 model2; - UniqueID32 model3; - UniqueID32 model4; - UniqueID32 model5; - UniqueID32 model6; - UniqueID32 model7; - UniqueID32 model8; - UniqueID32 model9; - UniqueID32 model10; - UniqueID32 model11; - UniqueID32 model12; - UniqueID32 particle; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - UniqueID32 wpsc1; - DamageInfo damageInfo1; - struct RidleyStruct1 : BigDNA { - AT_DECL_DNA_YAML - Value unknown1; - Value unknown2; - UniqueID32 particle1; - UniqueID32 particle2; - UniqueID32 texture1; - UniqueID32 texture2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; // CColor - Value unknown13; // CColor - - void nameIDs(PAKRouter& pakRouter, const std::string& name) const { - if (particle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1); - ent->name = name + "_part1"; - } - if (particle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2); - ent->name = name + "_part2"; - } - if (texture1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1); - ent->name = name + "_tex1"; - } - if (texture2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2); - ent->name = name + "_tex2"; - } - } - - void depIDs(std::vector& pathsOut) const { - g_curSpec->flattenDependencies(particle1, pathsOut); - g_curSpec->flattenDependencies(particle2, pathsOut); - g_curSpec->flattenDependencies(texture1, pathsOut); - g_curSpec->flattenDependencies(texture2, pathsOut); - } - } ridleyStruct1; - - Value soundID1; - UniqueID32 wpsc2; - UniqueID32 wpsc3; - DamageInfo damageInfo2; - - struct RidleyStruct2 : BigDNA { - AT_DECL_DNA_YAML - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - } ridleyStruct2_1; - - UniqueID32 wpsc4; - DamageInfo damageInfo3; - RidleyStruct2 ridleyStruct2_2; - Value soundID2; - DamageInfo damageInfo4; - RidleyStruct2 ridleyStruct2_3; - Value unknown5; - Value unknown6; - DamageInfo damageInfo5; - Value unknown7; - DamageInfo damageInfo6; - Value unknown8; - DamageInfo damageInfo7; - Value unknown9; - UniqueID32 elsc; - Value unknown10; - Value soundID3; - DamageInfo damageInfo8; - - /* Trilogy addition */ - DamageInfo damageInfo9; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (model1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model1); - ent->name = name + "_model1"; - } - if (model2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model2); - ent->name = name + "_model2"; - } - if (model3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model3); - ent->name = name + "_model3"; - } - if (model4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model4); - ent->name = name + "_model4"; - } - if (model5.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model5); - ent->name = name + "_model5"; - } - if (model6.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model6); - ent->name = name + "_model6"; - } - if (model7.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model7); - ent->name = name + "_model7"; - } - if (model8.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model8); - ent->name = name + "_model8"; - } - if (model9.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model9); - ent->name = name + "_model9"; - } - if (model10.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model10); - ent->name = name + "_model10"; - } - if (model11.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model11); - ent->name = name + "_model11"; - } - if (model12.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model12); - ent->name = name + "_model12"; - } - if (wpsc1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1); - ent->name = name + "_wpsc1"; - } - if (wpsc2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc2); - ent->name = name + "_wpsc2"; - } - if (wpsc3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc3); - ent->name = name + "_wpsc3"; - } - if (wpsc4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc4); - ent->name = name + "_wpsc4"; - } - if (elsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(elsc); - ent->name = name + "_elsc"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - ridleyStruct1.nameIDs(pakRouter, name + "_ridley1"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(model1, pathsOut); - g_curSpec->flattenDependencies(model2, pathsOut); - g_curSpec->flattenDependencies(model3, pathsOut); - g_curSpec->flattenDependencies(model4, pathsOut); - g_curSpec->flattenDependencies(model5, pathsOut); - g_curSpec->flattenDependencies(model6, pathsOut); - g_curSpec->flattenDependencies(model7, pathsOut); - g_curSpec->flattenDependencies(model8, pathsOut); - g_curSpec->flattenDependencies(model9, pathsOut); - g_curSpec->flattenDependencies(model10, pathsOut); - g_curSpec->flattenDependencies(model11, pathsOut); - g_curSpec->flattenDependencies(model12, pathsOut); - g_curSpec->flattenDependencies(wpsc1, pathsOut); - g_curSpec->flattenDependencies(wpsc2, pathsOut); - g_curSpec->flattenDependencies(wpsc3, pathsOut); - g_curSpec->flattenDependencies(wpsc4, pathsOut); - g_curSpec->flattenDependencies(elsc, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - ridleyStruct1.depIDs(pathsOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ripper.hpp b/DataSpec/DNAMP1/ScriptObjects/Ripper.hpp deleted file mode 100644 index 4dd779ddf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ripper.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Ripper : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value unknown1; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - GrappleParameters grappleParameters; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Ripple.hpp b/DataSpec/DNAMP1/ScriptObjects/Ripple.hpp deleted file mode 100644 index ea3b3378b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Ripple.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Ripple : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value active; - Value mag; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RoomAcoustics.hpp b/DataSpec/DNAMP1/ScriptObjects/RoomAcoustics.hpp deleted file mode 100644 index 1c4bfe6e8..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RoomAcoustics.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RoomAcoustics : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value volumeScale; - Value reverbHiEnable; - Value reverbHiTmpDisable; - Value reverbHiColoration; - Value reverbHiMix; - Value reverbHiTime; - Value reverbHiDamping; - Value reverbHiPreDelay; - Value reverbHiCrosstalk; - Value chorusEnable; - Value baseDelay; - Value variation; - Value period; - Value reverbStdEnable; - Value reverbStdTmpDisable; - Value reverbStdColoration; - Value reverbStdMix; - Value reverbStdTime; - Value reverbStdDamping; - Value reverbStdPreDelay; - Value delayEnable; - Value delay[3]; - Value feedback[3]; - Value output[3]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/RumbleEffect.hpp b/DataSpec/DNAMP1/ScriptObjects/RumbleEffect.hpp deleted file mode 100644 index 3dd327406..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/RumbleEffect.hpp +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct RumbleEffect : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value unknown1; - Value unknown2; - Value unknown3; - struct RumbleEffectParameters : BigDNA { - AT_DECL_DNA - Value propertyCount; - Value unknown1; - Value unknown2; - } rumbleParameters; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ScriptBeam.hpp b/DataSpec/DNAMP1/ScriptObjects/ScriptBeam.hpp deleted file mode 100644 index bf2230180..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ScriptBeam.hpp +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ScriptBeam : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - UniqueID32 wpsc; - BeamInfo beamInfo; - DamageInfo damageInfo; - - void nameIDs(PAKRouter& pakRouter) const override { - if (wpsc.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc); - ent->name = name + "_wpsc"; - } - beamInfo.nameIDs(pakRouter, name + "_beamInfo"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(wpsc, pathsOut); - beamInfo.depIDs(pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ScriptTypes.hpp b/DataSpec/DNAMP1/ScriptObjects/ScriptTypes.hpp deleted file mode 100644 index b0febb999..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ScriptTypes.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include - -namespace DataSpec::DNAMP1 { -struct IScriptObject; - -struct ScriptObjectSpec { - atUint8 type; - IScriptObject* (*loader)(); -}; - -using ScriptObjectDBArray = std::array; - -extern const ScriptObjectDBArray SCRIPT_OBJECT_DB; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Seedling.hpp b/DataSpec/DNAMP1/ScriptObjects/Seedling.hpp deleted file mode 100644 index 71250eb37..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Seedling.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Seedling : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - UniqueID32 unknown1; - UniqueID32 unknown2; - DamageInfo damageInfo1; - DamageInfo damageInfo2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (unknown1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown1); - ent->name = name + "_unk1"; - } - if (unknown2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unknown2); - ent->name = name + "_unk2"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(unknown1, pathsOut); - g_curSpec->flattenDependencies(unknown2, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ShadowProjector.hpp b/DataSpec/DNAMP1/ScriptObjects/ShadowProjector.hpp deleted file mode 100644 index f3073eb99..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ShadowProjector.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ShadowProjector : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SnakeWeedSwarm.hpp b/DataSpec/DNAMP1/ScriptObjects/SnakeWeedSwarm.hpp deleted file mode 100644 index 948d6e116..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SnakeWeedSwarm.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SnakeWeedSwarm : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - Value unknown1; - AnimationParameters animationParameters; - ActorParameters actorParameters; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - DamageInfo damageInfo; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Sound.hpp b/DataSpec/DNAMP1/ScriptObjects/Sound.hpp deleted file mode 100644 index b7d029c13..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Sound.hpp +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Sound : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value soundID; - Value active; - Value maxDist; - Value distComp; - Value startDelay; - Value minVol; - Value vol; - Value prio; - Value pan; - Value loop; - Value nonEmitter; - Value autoStart; - Value occlusionTest; - Value acoustics; - Value worldSfx; - Value allowDuplicates; - Value pitch; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpacePirate.hpp b/DataSpec/DNAMP1/ScriptObjects/SpacePirate.hpp deleted file mode 100644 index d1553ecb7..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpacePirate.hpp +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpacePirate : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value AggressionCheck; - Value CoverCheck; - Value SearchRadius; - Value FallBackCheck; - Value FallBackRadius; - Value HearingRadius; - /* - * 0x1: pendingAmbush - * 0x2: ceilingAmbush - * 0x4: nonAggressive - * 0x8: melee - * 0x10: noShuffleCloseCheck - * 0x20: onlyAttackInRange - * 0x40: unk - * 0x80: noKnockbackImpulseReset - * 0x200: noMeleeAttack - * 0x400: breakAttack - * 0x1000: seated - * 0x2000: shadowPirate - * 0x4000: alertBeforeCloak - * 0x8000: noBreakDodge - * 0x10000: floatingCorpse - * 0x20000: ragdollNoAiCollision - * 0x40000: trooper - */ - Value flags; - Value unknown8; - UniqueID32 Projectile; - DamageInfo ProjectileDamage; - Value Sound_Projectile; - DamageInfo BladeDamage; - Value KneelAttackChance; - UniqueID32 KneelAttackShot; - DamageInfo KneelAttackDamage; - Value DodgeCheck; - Value Sound_Impact; - Value averageNextShotTime; - Value nextShotTimeVariation; - Value Sound_Alert; - Value GunTrackDelay; - Value firstBurstCount; - Value CloakOpacity; - Value MaxCloakOpacity; - Value dodgeDelayTimeMin; - Value dodgeDelayTimeMax; - Value Sound_Hurled; - Value Sound_Death; - Value unknown19; - Value AvoidDistance; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (Projectile.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(Projectile); - ent->name = name + "_Projectile"; - } - if (KneelAttackShot.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(KneelAttackShot); - ent->name = name + "_KneelAttackShot"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(Projectile, pathsOut); - g_curSpec->flattenDependencies(KneelAttackShot, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpankWeed.hpp b/DataSpec/DNAMP1/ScriptObjects/SpankWeed.hpp deleted file mode 100644 index eba767cd3..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpankWeed.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpankWeed : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unused; - Value maxDetectionRange; - Value maxHearingrange; - Value maxSightRange; - Value hideTime; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpawnPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/SpawnPoint.hpp deleted file mode 100644 index 25a955e82..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpawnPoint.hpp +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpawnPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value powerBeam; - Value iceBeam; - Value waveBeam; - Value plasmaBeam; - Value missiles; - Value scanVisor; - Value morphBallBombs; - Value powerBombs; - Value flameThrower; - Value thermalVisor; - Value chargeBeam; - Value superMissile; - Value grappleBeam; - Value xrayVisor; - Value iceSpreader; - Value spaceJump; - Value morphBall; - Value combatVisor; - Value boostBall; - Value spiderBall; - Value powerSuit; - Value gravitySuit; - Value variaSuit; - Value phazonSuit; - Value energyTanks; - Value unknownItem1; - Value healthRefill; - Value unknownItem2; - Value waveBuster; - Value defaultSpawn; - Value active; - Value morphed; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpecialFunction.hpp b/DataSpec/DNAMP1/ScriptObjects/SpecialFunction.hpp deleted file mode 100644 index e9dabe3b3..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpecialFunction.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpecialFunction : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value function; - String<-1> unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - struct LayerSwitch : BigDNA { - AT_DECL_DNA - Value area; - Value layerIdx; - } layerSwitch; - Value pickup; - Value unknown5; - Value unknown6; - Value unknown7; // Used by SpinnerController 1 - Value unknown8; // Used by SpinnerController 2 - Value unknown9; // Used by SpinnerController 3 -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpiderBallAttractionSurface.hpp b/DataSpec/DNAMP1/ScriptObjects/SpiderBallAttractionSurface.hpp deleted file mode 100644 index 1b5205fb6..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpiderBallAttractionSurface.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpiderBallAttractionSurface : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpiderBallWaypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/SpiderBallWaypoint.hpp deleted file mode 100644 index 62c2bf7b2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpiderBallWaypoint.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct SpiderBallWaypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value unknown2; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/SpindleCamera.hpp b/DataSpec/DNAMP1/ScriptObjects/SpindleCamera.hpp deleted file mode 100644 index 7ea264dcf..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/SpindleCamera.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct SpindleCamera : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - /* - * 0x1: Look toward hint - * 0x2: Flat look delta - * 0x8: force minimum-clamp ball-to-cam azimuth - * 0x10: minimum-clamp ball-to-cam azimuth - * 0x20: Enable clampedAzimuthFromHintDir - * 0x40: Enable distOffsetFromBallDist - * 0x80: Use ball pos for cam pos Z (vs. hint pos) - * 0x100: Enable deltaAngleScaleWithCamDist - * 0x200: Use ball pos for look pos Z (vs. hint pos) - * 0x400: unused - * 0x800: Variable hint-to-ball direction - * 0x1000: Damp look azimuth with hint ball-to-cam azimuth < 10-degrees - * 0x2000: Enable deleteHintBallDist - * 0x4000: Ignore ball-to-cam azimuth sign - */ - PropertyFlags flags; - Value hintToCamDistMin; - Value hintToCamDistMax; - Value hintToCamVOffMin; - Value hintToCamVOffMax; - struct SpindleCameraParameters : BigDNA { - AT_DECL_DNA_YAML - Value input; - PropertyFlags flags; // high reflect, low reflect - Value lowOut; - Value highOut; - Value lowIn; - Value highIn; - }; - SpindleCameraParameters targetHintToCamDeltaAngleVel; - SpindleCameraParameters deltaAngleScaleWithCamDist; - SpindleCameraParameters hintToCamDist; - SpindleCameraParameters distOffsetFromBallDist; - SpindleCameraParameters hintBallToCamAzimuth; - SpindleCameraParameters unused; - SpindleCameraParameters maxHintBallToCamAzimuth; - SpindleCameraParameters camLookRelAzimuth; - SpindleCameraParameters lookPosZOffset; - SpindleCameraParameters camPosZOffset; - SpindleCameraParameters clampedAzimuthFromHintDir; - SpindleCameraParameters dampingAzimuthSpeed; - SpindleCameraParameters targetHintToCamDeltaAngleVelRange; - SpindleCameraParameters deleteHintBallDist; - SpindleCameraParameters recoverClampedAzimuthFromHintDir; -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Steam.hpp b/DataSpec/DNAMP1/ScriptObjects/Steam.hpp deleted file mode 100644 index bc1ac20f9..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Steam.hpp +++ /dev/null @@ -1,36 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Steam : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - DamageInfo damageInfo; - Value unknown1; - Value unknown2; - Value unknown3; - UniqueID32 texture; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - - void nameIDs(PAKRouter& pakRouter) const override { - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(texture, lazyOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/StreamedAudio.hpp b/DataSpec/DNAMP1/ScriptObjects/StreamedAudio.hpp deleted file mode 100644 index 7a099e5ac..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/StreamedAudio.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct StreamedAudio : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - String<-1> fileName; - Value noStopOnDeactivate; - Value fadeInTime; - Value fadeOutTime; - Value volume; - Value oneShot; - Value music; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Switch.hpp b/DataSpec/DNAMP1/ScriptObjects/Switch.hpp deleted file mode 100644 index 64baaa7cc..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Switch.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Switch : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value opened; - Value closeOnOpened; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/TargetingPoint.hpp b/DataSpec/DNAMP1/ScriptObjects/TargetingPoint.hpp deleted file mode 100644 index 596846efd..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/TargetingPoint.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct TargetingPoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/TeamAIMgr.hpp b/DataSpec/DNAMP1/ScriptObjects/TeamAIMgr.hpp deleted file mode 100644 index 4b77f903b..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/TeamAIMgr.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct TeamAIMgr : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value aiCount; - Value meleeCount; - Value projectileCount; - Value unknownCount; - Value maxMeleeAttackerCount; - Value maxProjectileAttackerCount; - Value positionMode; - Value meleeTimeInterval; - Value projectileTimeInterval; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Thardus.hpp b/DataSpec/DNAMP1/ScriptObjects/Thardus.hpp deleted file mode 100644 index 4146bc5ff..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Thardus.hpp +++ /dev/null @@ -1,165 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Thardus : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - UniqueID32 models[14]; - UniqueID32 particles1[3]; - UniqueID32 stateMachine; - UniqueID32 particles2[6]; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - UniqueID32 texture; - Value unknown9; - UniqueID32 particle; - Value unknown10; - Value unknown11; - Value unknown12; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (models[0].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[0]); - ent->name = name + "_model1"; - } - if (models[1].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[1]); - ent->name = name + "_model2"; - } - if (models[2].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[2]); - ent->name = name + "_model3"; - } - if (models[3].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[3]); - ent->name = name + "_model4"; - } - if (models[4].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[4]); - ent->name = name + "_model5"; - } - if (models[5].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[5]); - ent->name = name + "_model6"; - } - if (models[6].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[6]); - ent->name = name + "_model7"; - } - if (models[7].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[7]); - ent->name = name + "_model8"; - } - if (models[8].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[8]); - ent->name = name + "_model9"; - } - if (models[9].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[9]); - ent->name = name + "_model10"; - } - if (models[10].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[10]); - ent->name = name + "_model11"; - } - if (models[11].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[11]); - ent->name = name + "_model12"; - } - if (models[12].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[12]); - ent->name = name + "_model13"; - } - if (models[13].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(models[13]); - ent->name = name + "_model14"; - } - if (particles1[0].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles1[0]); - ent->name = name + "_part1"; - } - if (particles1[1].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles1[1]); - ent->name = name + "_part2"; - } - if (particles1[2].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles1[2]); - ent->name = name + "_part3"; - } - if (stateMachine.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(stateMachine); - ent->name = name + "_fsm"; - } - if (particles2[0].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[0]); - ent->name = name + "_part4"; - } - if (particles2[1].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[1]); - ent->name = name + "_part5"; - } - if (particles2[2].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[2]); - ent->name = name + "_part6"; - } - if (particles2[3].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[3]); - ent->name = name + "_part7"; - } - if (particles2[4].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[4]); - ent->name = name + "_part8"; - } - if (particles2[5].isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particles2[5]); - ent->name = name + "_part9"; - } - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part10"; - } - if (texture.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture); - ent->name = name + "_texture"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - for (int i = 0; i < 14; ++i) - g_curSpec->flattenDependencies(models[i], pathsOut); - for (int i = 0; i < 3; ++i) - g_curSpec->flattenDependencies(particles1[i], pathsOut); - g_curSpec->flattenDependencies(stateMachine, pathsOut); - for (int i = 0; i < 6; ++i) - g_curSpec->flattenDependencies(particles2[i], pathsOut); - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(texture, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ThardusRockProjectile.hpp b/DataSpec/DNAMP1/ScriptObjects/ThardusRockProjectile.hpp deleted file mode 100644 index 5df16cd50..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ThardusRockProjectile.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ThardusRockProjectile : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - UniqueID32 model; - UniqueID32 stateMachine; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (model.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(model); - ent->name = name + "_model"; - } - if (stateMachine.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(stateMachine); - ent->name = name + "_fsm"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(model, pathsOut); - g_curSpec->flattenDependencies(stateMachine, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/ThermalHeatFader.hpp b/DataSpec/DNAMP1/ScriptObjects/ThermalHeatFader.hpp deleted file mode 100644 index 1048b7127..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/ThermalHeatFader.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct ThermalHeatFader : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value fadedLevel; - Value initialLevel; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Timer.hpp b/DataSpec/DNAMP1/ScriptObjects/Timer.hpp deleted file mode 100644 index fe9c5f67c..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Timer.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Timer : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value startTime; - Value maxRandomAddition; - Value resetToZero; - Value startImmediately; - Value active; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Trigger.hpp b/DataSpec/DNAMP1/ScriptObjects/Trigger.hpp deleted file mode 100644 index 15478e3c3..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Trigger.hpp +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Trigger : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - DamageInfo damageInfo; - Value force; - Value flags; - Value active; - Value deactivateOnEntered; - Value deactivateOnExited; - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override { - zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f; - zeus::CVector3f loc(location); - return zeus::CAABox(loc - halfExtent, loc + halfExtent); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Tryclops.hpp b/DataSpec/DNAMP1/ScriptObjects/Tryclops.hpp deleted file mode 100644 index 4bf127ee8..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Tryclops.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Tryclops : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/VisorFlare.hpp b/DataSpec/DNAMP1/ScriptObjects/VisorFlare.hpp deleted file mode 100644 index f617719ce..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/VisorFlare.hpp +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct VisorFlare : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - FlareDefinition flareDefinitions[5]; - - void nameIDs(PAKRouter& pakRouter) const override { - flareDefinitions[0].nameIDs(pakRouter, name + "_flare1"); - flareDefinitions[1].nameIDs(pakRouter, name + "_flare2"); - flareDefinitions[2].nameIDs(pakRouter, name + "_flare3"); - flareDefinitions[3].nameIDs(pakRouter, name + "_flare4"); - flareDefinitions[4].nameIDs(pakRouter, name + "_flare5"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - for (int i = 0; i < 5; ++i) - flareDefinitions[i].depIDs(pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp b/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp deleted file mode 100644 index 01ba8e833..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/VisorGoo.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct VisorGoo : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value position; - UniqueID32 particle; - UniqueID32 electric; - Value minDist; - Value maxDist; - Value nearProb; - Value farProb; - DNAColor color; - Value sfx; - Value skipAngleTest; - - void nameIDs(PAKRouter& pakRouter) const override { - if (particle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle); - ent->name = name + "_part"; - } - if (electric.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric); - ent->name = name + "_elsc"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(particle, pathsOut); - g_curSpec->flattenDependencies(electric, pathsOut); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WallCrawlerSwarm.hpp b/DataSpec/DNAMP1/ScriptObjects/WallCrawlerSwarm.hpp deleted file mode 100644 index 94c76b4f5..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WallCrawlerSwarm.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct WallCrawlerSwarm : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value volume; - Value active; - ActorParameters actorParameters; - Value flavor; - AnimationParameters animationParameters; - Value launchAnim; - Value attractAnim; - UniqueID32 part1; - UniqueID32 part2; - UniqueID32 part3; - UniqueID32 part4; - DamageInfo crabDamage; - Value crabDamageCooldown; - DamageInfo scarabExplodeDamage; - Value boidRadius; - Value touchRadius; - Value playerTouchRadius; - Value animPlaybackSpeed; - Value numBoids; - Value maxCreatedBoids; - Value separationRadius; - Value cohesionMagnitude; - Value alignmentWeight; - Value separationMagnitude; - Value moveToWaypointWeight; - Value attractionMagnitude; - Value attractionRadius; - Value boidGenRate; - Value maxLaunches; - Value scarabBoxMargin; - Value scarabScatterXYVelocity; - Value scarabTimeToExplode; - HealthInfo healthInfo; - DamageVulnerability damageVulnerabilty; - Value launchSfx; - Value scatterSfx; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (part1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part1); - ent->name = name + "_part1"; - } - if (part2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part2); - ent->name = name + "_part2"; - } - if (part3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part3); - ent->name = name + "_part3"; - } - if (part4.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(part4); - ent->name = name + "_part4"; - } - animationParameters.nameANCS(pakRouter, name + "_animp"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(part1, pathsOut); - g_curSpec->flattenDependencies(part2, pathsOut); - g_curSpec->flattenDependencies(part3, pathsOut); - g_curSpec->flattenDependencies(part4, pathsOut); - animationParameters.depANCS(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Warwasp.hpp b/DataSpec/DNAMP1/ScriptObjects/Warwasp.hpp deleted file mode 100644 index cf6a692ff..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Warwasp.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Warwasp : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value flavor; - Value location; - Value orientation; - Value scale; - PatternedInfo patternedInfo; - ActorParameters actorParameters; - Value colliderType; - DamageInfo damageInfo1; - UniqueID32 projectileWeapon; - DamageInfo projectileDamage; - UniqueID32 projectileVisorParticle; - Value projectileVisorSfx; - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const override { - actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters); - } - - void nameIDs(PAKRouter& pakRouter) const override { - if (projectileWeapon.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileWeapon); - ent->name = name + "_wpsc"; - } - if (projectileVisorParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileVisorParticle); - ent->name = name + "_part"; - } - patternedInfo.nameIDs(pakRouter, name + "_patterned"); - actorParameters.nameIDs(pakRouter, name + "_actp"); - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(projectileWeapon, pathsOut); - g_curSpec->flattenDependencies(projectileVisorParticle, pathsOut); - patternedInfo.depIDs(pathsOut); - actorParameters.depIDs(pathsOut, lazyOut); - } - - void gatherScans(std::vector& scansOut) const override { actorParameters.scanIDs(scansOut); } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Water.cpp b/DataSpec/DNAMP1/ScriptObjects/Water.cpp deleted file mode 100644 index 2306b7943..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Water.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "Water.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void Water::UnusedBitset::Enumerate(typename Read::StreamT& in) { - if (in.readBool()) { - atUint32 bitVal0 = in.readUint16Big(); - atUint32 bitVal1 = in.readUint16Big(); - atUint32 len = ((bitVal0 * bitVal1) + 31) / 31; - in.seek(len * 4); - } -} -template <> -void Water::UnusedBitset::Enumerate(typename Write::StreamT& out) { - out.writeBool(false); -} -template <> -void Water::UnusedBitset::Enumerate(typename ReadYaml::StreamT& r) {} -template <> -void Water::UnusedBitset::Enumerate(typename WriteYaml::StreamT& w) {} -template <> -void Water::UnusedBitset::Enumerate(typename BinarySize::StreamT& s) { - s += 1; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Water.hpp b/DataSpec/DNAMP1/ScriptObjects/Water.hpp deleted file mode 100644 index 51350be4d..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Water.hpp +++ /dev/null @@ -1,163 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Water : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value volume; - DamageInfo damageInfo; - Value orientedForce; - Value triggerFlags; - Value thermalCold; - Value displaySurface; - UniqueID32 patternMap1; - UniqueID32 patternMap2; - UniqueID32 colorMap; - UniqueID32 bumpMap; - UniqueID32 envMap; - UniqueID32 envBumpMap; - Value bumpLightDir; - Value bumpScale; - Value morphInTime; - Value morphOutTime; - Value active; - Value fluidType; - Value unknownBool; - Value alpha; - struct FluidUVMotion : BigDNA { - AT_DECL_DNA - struct FluidLayerMotion : BigDNA { - AT_DECL_DNA - Value motionType; - Value timeToWrap; - Value orientation; - Value magnitude; - Value uvMul; - }; - - FluidLayerMotion pattern1Layer; - FluidLayerMotion pattern2Layer; - FluidLayerMotion colorLayer; - Value timeToWrap; - Value orientation; - } fluidUVMotion; - - Value turbulenceSpeed; - Value turbulenceDistance; - Value turbulenceFrequencyMax; - Value turbulenceFrequencyMin; - Value turbulencePhaseMax; - Value turbulencePhaseMin; - Value turbulenceAmplitudeMax; - Value turbulenceAmplitudeMin; - Value splashColor; - Value insideFogColor; - UniqueID32 splashParticle1; - UniqueID32 splashParticle2; - UniqueID32 splashParticle3; - UniqueID32 visorRunoffParticle; - UniqueID32 unmorphVisorRunoffParticle; - Value visorRunoffSfx; - Value unmorphVisorRunoffSfx; - Value splashSfx1; - Value splashSfx2; - Value splashSfx3; - Value tileSize; - Value tileSubdivisions; - Value specularMin; - Value specularMax; - Value reflectionSize; - Value rippleIntensity; - Value reflectionBlend; - Value fogBias; - Value fogMagnitude; - Value fogSpeed; - Value fogColor; - UniqueID32 lightmap; - Value unitsPerLightmapTexel; - Value alphaInTime; - Value alphaOutTime; - Value unusedInt1; - Value unusedInt2; - - struct UnusedBitset : BigDNA{AT_DECL_EXPLICIT_DNA} unusedBitset; - - void nameIDs(PAKRouter& pakRouter) const override { - if (patternMap1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap1); - ent->name = name + "_patternMap1"; - } - if (patternMap2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(patternMap2); - ent->name = name + "_patternMap2"; - } - if (colorMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(colorMap); - ent->name = name + "_colorMap"; - } - if (bumpMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(bumpMap); - ent->name = name + "_bumpMap"; - } - if (envMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envMap); - ent->name = name + "_envMap"; - } - if (envBumpMap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(envBumpMap); - ent->name = name + "_envBumpMap"; - } - if (lightmap.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(lightmap); - ent->name = name + "_lightmap"; - } - if (splashParticle1.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle1); - ent->name = name + "_splashParticle1"; - } - if (splashParticle2.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle2); - ent->name = name + "_splashParticle2"; - } - if (splashParticle3.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(splashParticle3); - ent->name = name + "_splashParticle3"; - } - if (visorRunoffParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(visorRunoffParticle); - ent->name = name + "_visorRunoffParticle"; - } - if (unmorphVisorRunoffParticle.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(unmorphVisorRunoffParticle); - ent->name = name + "_unmorphVisorRunoffParticle"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(patternMap1, pathsOut); - g_curSpec->flattenDependencies(patternMap2, pathsOut); - g_curSpec->flattenDependencies(colorMap, pathsOut); - g_curSpec->flattenDependencies(bumpMap, pathsOut); - g_curSpec->flattenDependencies(envMap, pathsOut); - g_curSpec->flattenDependencies(envBumpMap, pathsOut); - g_curSpec->flattenDependencies(lightmap, pathsOut); - g_curSpec->flattenDependencies(splashParticle1, pathsOut); - g_curSpec->flattenDependencies(splashParticle2, pathsOut); - g_curSpec->flattenDependencies(splashParticle3, pathsOut); - g_curSpec->flattenDependencies(visorRunoffParticle, pathsOut); - g_curSpec->flattenDependencies(unmorphVisorRunoffParticle, pathsOut); - } - - zeus::CAABox getVISIAABB(hecl::blender::Token& btok) const override { - zeus::CVector3f halfExtent = zeus::CVector3f(volume) / 2.f; - zeus::CVector3f loc(location); - return zeus::CAABox(loc - halfExtent, loc + halfExtent); - } -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/Waypoint.hpp b/DataSpec/DNAMP1/ScriptObjects/Waypoint.hpp deleted file mode 100644 index db0ec0cd2..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/Waypoint.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct Waypoint : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value location; - Value orientation; - Value active; - Value speed; - Value pause; - Value patternTranslate; - Value patternOrient; - Value patternFit; - Value behaviour; - Value behaviourOrient; - Value behaviourModifiers; // 0x2: single, 0x4: double - Value animation; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WorldLightFader.hpp b/DataSpec/DNAMP1/ScriptObjects/WorldLightFader.hpp deleted file mode 100644 index 18eaec3ba..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WorldLightFader.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { -struct WorldLightFader : IScriptObject { - AT_DECL_DNA_YAMLV - String<-1> name; - Value active; - Value fadedLevel; - Value intialLevel; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.cpp b/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.cpp deleted file mode 100644 index 54fcd60b0..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "WorldTeleporter.hpp" - -namespace DataSpec::DNAMP1 { - -template -void WorldTeleporter::Enumerate(typename Op::StreamT& s) { - IScriptObject::Enumerate(s); - Do(athena::io::PropId{"name"}, name, s); - Do(athena::io::PropId{"active"}, active, s); - Do(athena::io::PropId{"mlvl"}, mlvl, s); - Do(athena::io::PropId{"mrea"}, mrea, s); - Do(athena::io::PropId{"animationParameters"}, animationParameters, s); - Do(athena::io::PropId{"playerScale"}, playerScale, s); - Do(athena::io::PropId{"platformModel"}, platformModel, s); - Do(athena::io::PropId{"platformScale"}, platformScale, s); - Do(athena::io::PropId{"blackgroundModel"}, backgroundModel, s); - Do(athena::io::PropId{"backgroundScale"}, backgroundScale, s); - Do(athena::io::PropId{"upElevator"}, upElevator, s); - Do(athena::io::PropId{"elevatorSound"}, elevatorSound, s); - Do(athena::io::PropId{"volume"}, volume, s); - Do(athena::io::PropId{"panning"}, panning, s); - Do(athena::io::PropId{"showText"}, showText, s); - Do(athena::io::PropId{"font"}, font, s); - Do(athena::io::PropId{"strg"}, strg, s); - Do(athena::io::PropId{"fadeWhite"}, fadeWhite, s); - Do(athena::io::PropId{"charFadeInTime"}, charFadeInTime, s); - Do(athena::io::PropId{"charsPerSecond"}, charsPerSecond, s); - Do(athena::io::PropId{"showDelay"}, showDelay, s); - - if (propertyCount == 26) { - Do(athena::io::PropId{"audioStream"}, audioStream, s); - Do(athena::io::PropId{"unknown13"}, unknown13, s); - Do(athena::io::PropId{"unknown14"}, unknown14, s); - Do(athena::io::PropId{"unknown15"}, unknown15, s); - Do(athena::io::PropId{"unknown16"}, unknown16, s); - } else { - unknown13 = false; - unknown14 = 0.0; - unknown15 = 0.0; - unknown16 = 0.0; - } -} - -std::string_view WorldTeleporter::DNAType() { return "DNAMP1::WorldTeleporter"sv; } - -AT_SPECIALIZE_DNA_YAML(WorldTeleporter) - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.hpp b/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.hpp deleted file mode 100644 index 559f2e371..000000000 --- a/DataSpec/DNAMP1/ScriptObjects/WorldTeleporter.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" -#include "IScriptObject.hpp" -#include "Parameters.hpp" - -namespace DataSpec::DNAMP1 { - -struct WorldTeleporter : IScriptObject { - AT_DECL_EXPLICIT_DNA_YAMLV - String<-1> name; - Value active; - UniqueID32 mlvl; - UniqueID32 mrea; - AnimationParameters animationParameters; - Value playerScale; - UniqueID32 platformModel; - Value platformScale; - UniqueID32 backgroundModel; - Value backgroundScale; - Value upElevator; - Value elevatorSound; // needs verifcation - Value volume; - Value panning; - Value showText; - UniqueID32 font; - UniqueID32 strg; - Value fadeWhite; - Value charFadeInTime; - Value charsPerSecond; - Value showDelay; - - /* Trilogy additions (property count 26) */ - String<-1> audioStream; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - - void nameIDs(PAKRouter& pakRouter) const override { - if (platformModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(platformModel); - ent->name = name + "_model1"; - } - if (backgroundModel.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(backgroundModel); - ent->name = name + "_model2"; - } - if (strg.isValid()) { - PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(strg); - ent->name = name + "_strg"; - } - } - - void gatherDependencies(std::vector& pathsOut, - std::vector& lazyOut) const override { - g_curSpec->flattenDependencies(platformModel, pathsOut); - g_curSpec->flattenDependencies(backgroundModel, pathsOut); - g_curSpec->flattenDependencies(strg, pathsOut); - } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/SnowForces.hpp b/DataSpec/DNAMP1/SnowForces.hpp deleted file mode 100644 index d96ca7c2b..000000000 --- a/DataSpec/DNAMP1/SnowForces.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include - -#include "DNAMP1.hpp" - -namespace DataSpec::DNAMP1 { -struct SnowForces : BigDNA { - AT_DECL_DNA_YAML - struct Force : BigDNA { - AT_DECL_DNA - Value gravity; - Value wind; - }; - - Value forces[256]; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.cpp b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.cpp deleted file mode 100644 index ae93c7c1e..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp" - -#include -#include - -#define PREFIX(v) std::string_view("tweak.automap." #v) -namespace DataSpec::DNAMP1 { -namespace { -constexpr std::string_view skShowOneMiniMapArea = PREFIX(ShowOneMiniMapArea); -constexpr std::string_view skScaleMoveSpeedWithCamDist = PREFIX(ScaleMoveSpeedWithCamDist); -constexpr std::string_view skCamDist = PREFIX(CamDist); -constexpr std::string_view skMinCameraDist = PREFIX(MinCamDist); -constexpr std::string_view skMaxCamDist = PREFIX(MaxCamDist); -constexpr std::string_view skMinCamRotX = PREFIX(MinCamRotX); -constexpr std::string_view skMaxCamRotX = PREFIX(MaxCamRotX); -constexpr std::string_view skCamAngle = PREFIX(CamAngle); -constexpr std::string_view skWidgetColor = PREFIX(WidgetColor); -constexpr std::string_view skMiniCamDist = PREFIX(MiniCamDist); -constexpr std::string_view skMiniCamXAngle = PREFIX(MiniCamXAngle); -constexpr std::string_view skMiniCamAngle = PREFIX(MiniCamAngle); -constexpr std::string_view skVisitedSurfaceColor = PREFIX(VisitedSurfaceColor); -constexpr std::string_view skVisitedOutlineColor = PREFIX(VisitedOutlineColor); -constexpr std::string_view skUnvisitedSurfaceColor = PREFIX(UnvisitedSurfaceColor); -constexpr std::string_view skUnvisitedOutlineColor = PREFIX(UnvisitedOutlineColor); -constexpr std::string_view skSelectedVisitedSurfaceColor = PREFIX(SelectedVisitedSurfaceColor); -constexpr std::string_view skSelectedVisitedOutlineColor = PREFIX(SelectedVisitedOutlineColor); -constexpr std::string_view skMapSurfaceNormalColorLinear = PREFIX(MapSurfaceNormalColorLinear); -constexpr std::string_view skMapSurfaceNormalColorConstant = PREFIX(MapSurfaceNormalColorConstant); -hecl::CVar* tw_showOneMiniMapArea = nullptr; -hecl::CVar* tw_scaleMoveSpeedWithCamDist = nullptr; -hecl::CVar* tw_camDist = nullptr; -hecl::CVar* tw_minCamDist = nullptr; -hecl::CVar* tw_maxCamDist = nullptr; -hecl::CVar* tw_minCamRotX = nullptr; -hecl::CVar* tw_maxCamRotX = nullptr; -hecl::CVar* tw_camAngle = nullptr; -hecl::CVar* tw_widgetColor = nullptr; -hecl::CVar* tw_miniCamDist = nullptr; -hecl::CVar* tw_miniCamXAngle = nullptr; -hecl::CVar* tw_miniCamAngle = nullptr; -hecl::CVar* tw_visitedsurfaceColor = nullptr; -hecl::CVar* tw_visitedOutlineColor = nullptr; -hecl::CVar* tw_unvisitedSurfaceColor = nullptr; -hecl::CVar* tw_unvisitedOutlineColor = nullptr; -hecl::CVar* tw_selectedVisitedSurfaceColor = nullptr; -hecl::CVar* tw_selectedVisitedOutlineColor = nullptr; -hecl::CVar* tw_mapSurfaceNormColorLinear = nullptr; -hecl::CVar* tw_mapSurfaceNormColorConstant = nullptr; -} // namespace - -void CTweakAutoMapper::_tweakListener(hecl::CVar* cv) { - if (cv == tw_showOneMiniMapArea) { - x4_24_showOneMiniMapArea = cv->toBoolean(); - } else if (cv == tw_scaleMoveSpeedWithCamDist) { - x4_26_scaleMoveSpeedWithCamDist = cv->toBoolean(); - } else if (cv == tw_camDist) { - x8_camDist = cv->toReal(); - } else if (cv == tw_minCamDist) { - xc_minCamDist = cv->toReal(); - } else if (cv == tw_maxCamDist) { - x10_maxCamDist = cv->toReal(); - } else if (cv == tw_minCamRotX) { - x14_minCamRotateX = cv->toReal(); - } else if (cv == tw_maxCamRotX) { - x18_maxCamRotateX = cv->toReal(); - } else if (cv == tw_camAngle) { - x1c_camAngle = cv->toReal(); - } else if (cv == tw_widgetColor) { - x24_automapperWidgetColor = zeus::CColor(cv->toVec4f()); - } else if (cv == tw_miniCamDist) { - x28_miniCamDist = cv->toReal(); - } else if (cv == tw_miniCamXAngle) { - x2c_miniCamXAngle = tw_miniCamXAngle->toReal(); - } else if (cv == tw_miniCamAngle) { - x30_miniCamAngle = tw_miniCamAngle->toReal(); - } else if (cv == tw_visitedsurfaceColor) { - x3c_surfColorVisited = zeus::CColor(tw_visitedsurfaceColor->toVec4f()); - } else if (cv == tw_visitedOutlineColor) { - x40_outlineColorVisited = zeus::CColor(tw_visitedOutlineColor->toVec4f()); - } else if (cv == tw_unvisitedSurfaceColor) { - x44_surfColorUnvisited = zeus::CColor(tw_unvisitedSurfaceColor->toVec4f()); - } else if (cv == tw_unvisitedOutlineColor) { - x48_outlineColorUnvisited = zeus::CColor(tw_unvisitedOutlineColor->toVec4f()); - } else if (cv == tw_selectedVisitedSurfaceColor) { - x4c_surfaceSelectColorVisited = zeus::CColor(tw_selectedVisitedSurfaceColor->toVec4f()); - } else if (cv == tw_selectedVisitedOutlineColor) { - x50_outlineSelectColorVisited = zeus::CColor(tw_selectedVisitedOutlineColor->toVec4f()); - } else if (cv == tw_mapSurfaceNormColorLinear) { - x54_mapSurfaceNormColorLinear = tw_mapSurfaceNormColorLinear->toReal(); - } else if (cv == tw_mapSurfaceNormColorConstant) { - x58_mapSurfaceNormColorConstant = tw_mapSurfaceNormColorConstant->toReal(); - } -} - -void CTweakAutoMapper::initCVars(hecl::CVarManager* mgr) { - auto assignBool = [this, mgr](std::string_view name, std::string_view desc, bool& v, hecl::CVar::EFlags flags) { - hecl::CVar* cv = mgr->findOrMakeCVar(name, desc, v, flags); - // Check if the CVar was deserialized, this avoid an unnecessary conversion - if (cv->wasDeserialized()) - v = cv->toBoolean(); - cv->addListener([this](hecl::CVar* cv) { _tweakListener(cv); }); - return cv; - }; - - auto assignRealValue = [this, mgr](std::string_view name, std::string_view desc, float& v, hecl::CVar::EFlags flags) { - hecl::CVar* cv = mgr->findOrMakeCVar(name, desc, v, flags); - // Check if the CVar was deserialized, this avoid an unnecessary conversion - if (cv->wasDeserialized()) - v = cv->toReal(); - cv->addListener([this](hecl::CVar* cv) { _tweakListener(cv); }); - return cv; - }; - - auto assignColorValue = [this, mgr](std::string_view name, std::string_view desc, zeus::CColor& v, - hecl::CVar::EFlags flags) { - atVec4f vec{v.mSimd}; - hecl::CVar* cv = mgr->findOrMakeCVar(name, desc, vec, flags | hecl::CVar::EFlags::Color); - // Check if the CVar was deserialized, this avoid an unnecessary conversion - if (cv->wasDeserialized()) - v = zeus::CColor(cv->toVec4f()); - cv->addListener([this](hecl::CVar* cv) { _tweakListener(cv); }); - return cv; - }; - - tw_showOneMiniMapArea = assignBool(skShowOneMiniMapArea, "", x4_24_showOneMiniMapArea, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_scaleMoveSpeedWithCamDist = - assignBool(skScaleMoveSpeedWithCamDist, "", x4_26_scaleMoveSpeedWithCamDist, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_camDist = assignRealValue(skCamDist, "", x8_camDist, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_minCamDist = assignRealValue(skMinCameraDist, "", xc_minCamDist, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_maxCamDist = assignRealValue(skMaxCamDist, "", x10_maxCamDist, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_minCamRotX = assignRealValue(skMinCamRotX, "", x14_minCamRotateX, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_maxCamRotX = assignRealValue(skMaxCamRotX, "", x18_maxCamRotateX, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_camAngle = assignRealValue(skCamAngle, "", x1c_camAngle, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_widgetColor = assignColorValue(skWidgetColor, "", x24_automapperWidgetColor, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_miniCamDist = assignRealValue(skMiniCamDist, "", x28_miniCamDist, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_miniCamXAngle = assignRealValue(skMiniCamXAngle, "", x2c_miniCamXAngle, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_miniCamAngle = assignRealValue(skMiniCamAngle, "", x30_miniCamAngle, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_widgetColor = assignColorValue(skWidgetColor, "", x38_automapperWidgetMiniColor, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_visitedsurfaceColor = assignColorValue(skVisitedSurfaceColor, "", x3c_surfColorVisited, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Color | - hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_visitedOutlineColor = assignColorValue(skVisitedOutlineColor, "", x40_outlineColorVisited, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Color | - hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_unvisitedSurfaceColor = assignColorValue(skUnvisitedSurfaceColor, "", x44_surfColorUnvisited, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Color | - hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_unvisitedOutlineColor = - assignColorValue(skUnvisitedOutlineColor, "", x48_outlineColorUnvisited, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_selectedVisitedSurfaceColor = assignColorValue(skSelectedVisitedSurfaceColor, "", x4c_surfaceSelectColorVisited, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Color | - hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_selectedVisitedOutlineColor = assignColorValue(skSelectedVisitedOutlineColor, "", x50_outlineSelectColorVisited, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Color | - hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_mapSurfaceNormColorLinear = assignRealValue(skMapSurfaceNormalColorLinear, "", x54_mapSurfaceNormColorLinear, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Color | - hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); - tw_mapSurfaceNormColorConstant = assignRealValue(skMapSurfaceNormalColorConstant, "", x58_mapSurfaceNormColorConstant, - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Color | - hecl::CVar::EFlags::Gui | hecl::CVar::EFlags::Archive); -} -} // namespace DataSpec::DNAMP1 \ No newline at end of file diff --git a/DataSpec/DNAMP1/Tweaks/CTweakBall.cpp b/DataSpec/DNAMP1/Tweaks/CTweakBall.cpp deleted file mode 100644 index c67d19b24..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakBall.cpp +++ /dev/null @@ -1,920 +0,0 @@ -#include "CTweakBall.hpp" - -namespace DataSpec::DNAMP1 { - -template <> -void CTweakBall::Enumerate(typename Read::StreamT& __dna_reader) { - /* x4_maxTranslationAcceleration[0] */ - x4_maxTranslationAcceleration[0] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[1] */ - x4_maxTranslationAcceleration[1] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[2] */ - x4_maxTranslationAcceleration[2] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[3] */ - x4_maxTranslationAcceleration[3] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[4] */ - x4_maxTranslationAcceleration[4] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[5] */ - x4_maxTranslationAcceleration[5] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[6] */ - x4_maxTranslationAcceleration[6] = __dna_reader.readFloatBig(); - /* x4_maxTranslationAcceleration[7] */ - x4_maxTranslationAcceleration[7] = __dna_reader.readFloatBig(); - /* x24_translationFriction[0] */ - x24_translationFriction[0] = __dna_reader.readFloatBig(); - /* x24_translationFriction[1] */ - x24_translationFriction[1] = __dna_reader.readFloatBig(); - /* x24_translationFriction[2] */ - x24_translationFriction[2] = __dna_reader.readFloatBig(); - /* x24_translationFriction[3] */ - x24_translationFriction[3] = __dna_reader.readFloatBig(); - /* x24_translationFriction[4] */ - x24_translationFriction[4] = __dna_reader.readFloatBig(); - /* x24_translationFriction[5] */ - x24_translationFriction[5] = __dna_reader.readFloatBig(); - /* x24_translationFriction[6] */ - x24_translationFriction[6] = __dna_reader.readFloatBig(); - /* x24_translationFriction[7] */ - x24_translationFriction[7] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[0] */ - x44_translationMaxSpeed[0] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[1] */ - x44_translationMaxSpeed[1] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[2] */ - x44_translationMaxSpeed[2] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[3] */ - x44_translationMaxSpeed[3] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[4] */ - x44_translationMaxSpeed[4] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[5] */ - x44_translationMaxSpeed[5] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[6] */ - x44_translationMaxSpeed[6] = __dna_reader.readFloatBig(); - /* x44_translationMaxSpeed[7] */ - x44_translationMaxSpeed[7] = __dna_reader.readFloatBig(); - /* x64_ */ - x64_ = __dna_reader.readFloatBig(); - /* x68_ */ - x68_ = __dna_reader.readFloatBig(); - /* x6c_ */ - x6c_ = __dna_reader.readFloatBig(); - /* x70_ */ - x70_ = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[0] */ - xc4_ballForwardBrakingAcceleration[0] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[1] */ - xc4_ballForwardBrakingAcceleration[1] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[2] */ - xc4_ballForwardBrakingAcceleration[2] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[3] */ - xc4_ballForwardBrakingAcceleration[3] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[4] */ - xc4_ballForwardBrakingAcceleration[4] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[5] */ - xc4_ballForwardBrakingAcceleration[5] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[6] */ - xc4_ballForwardBrakingAcceleration[6] = __dna_reader.readFloatBig(); - /* xc4_ballForwardBrakingAcceleration[7] */ - xc4_ballForwardBrakingAcceleration[7] = __dna_reader.readFloatBig(); - /* xe4_ballGravity */ - xe4_ballGravity = __dna_reader.readFloatBig(); - /* xe8_ballWaterGravity */ - xe8_ballWaterGravity = __dna_reader.readFloatBig(); - /* x14c_ */ - x14c_ = __dna_reader.readFloatBig(); - /* x150_ */ - x150_ = __dna_reader.readFloatBig(); - /* x158_ */ - x158_ = __dna_reader.readFloatBig(); - /* x1dc_minimumAlignmentSpeed */ - x1dc_minimumAlignmentSpeed = __dna_reader.readFloatBig(); - /* x1e0_tireness */ - x1e0_tireness = __dna_reader.readFloatBig(); - /* x1ec_maxLeanAngle */ - x1ec_maxLeanAngle = __dna_reader.readFloatBig(); - /* x1f0_tireToMarbleThresholdSpeed */ - x1f0_tireToMarbleThresholdSpeed = __dna_reader.readFloatBig(); - /* x1f4_marbleToTireThresholdSpeed */ - x1f4_marbleToTireThresholdSpeed = __dna_reader.readFloatBig(); - /* x1f8_forceToLeanGain */ - x1f8_forceToLeanGain = __dna_reader.readFloatBig(); - /* x1fc_leanTrackingGain */ - x1fc_leanTrackingGain = __dna_reader.readFloatBig(); - /* x74_ballCameraAnglePerSecond */ - x74_ballCameraAnglePerSecond = __dna_reader.readFloatBig(); - /* x78_ballCameraOffset */ - x78_ballCameraOffset = __dna_reader.readVec3fBig(); - /* x84_ballCameraMinSpeedDistance */ - x84_ballCameraMinSpeedDistance = __dna_reader.readFloatBig(); - /* x88_ballCameraMaxSpeedDistance */ - x88_ballCameraMaxSpeedDistance = __dna_reader.readFloatBig(); - /* x8c_ballCameraBackwardsDistance */ - x8c_ballCameraBackwardsDistance = __dna_reader.readFloatBig(); - /* x90_ */ - x90_ = __dna_reader.readFloatBig(); - /* x94_ballCameraSpringConstant */ - x94_ballCameraSpringConstant = __dna_reader.readFloatBig(); - /* x98_ballCameraSpringMax */ - x98_ballCameraSpringMax = __dna_reader.readFloatBig(); - /* x9c_ballCameraSpringTardis */ - x9c_ballCameraSpringTardis = __dna_reader.readFloatBig(); - /* xa0_ballCameraCentroidSpringConstant */ - xa0_ballCameraCentroidSpringConstant = __dna_reader.readFloatBig(); - /* xa4_ballCameraCentroidSpringMax */ - xa4_ballCameraCentroidSpringMax = __dna_reader.readFloatBig(); - /* xa8_ballCameraCentroidSpringTardis */ - xa8_ballCameraCentroidSpringTardis = __dna_reader.readFloatBig(); - /* xac_ballCameraCentroidDistanceSpringConstant */ - xac_ballCameraCentroidDistanceSpringConstant = __dna_reader.readFloatBig(); - /* xb0_ballCameraCentroidDistanceSpringMax */ - xb0_ballCameraCentroidDistanceSpringMax = __dna_reader.readFloatBig(); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - xb4_ballCameraCentroidDistanceSpringTardis = __dna_reader.readFloatBig(); - /* xb8_ballCameraLookAtSpringConstant */ - xb8_ballCameraLookAtSpringConstant = __dna_reader.readFloatBig(); - /* xbc_ballCameraLookAtSpringMax */ - xbc_ballCameraLookAtSpringMax = __dna_reader.readFloatBig(); - /* xc0_ballCameraLookAtSpringTardis */ - xc0_ballCameraLookAtSpringTardis = __dna_reader.readFloatBig(); - /* x154_ */ - x154_ = __dna_reader.readFloatBig(); - /* x15c_ */ - x15c_ = __dna_reader.readFloatBig(); - /* x160_ */ - x160_ = __dna_reader.readFloatBig(); - /* x164_ */ - x164_ = __dna_reader.readFloatBig(); - /* x168_ */ - x168_ = __dna_reader.readFloatBig(); - /* x16c_ */ - x16c_ = __dna_reader.readFloatBig(); - /* x170_conservativeDoorCamDistance */ - x170_conservativeDoorCamDistance = __dna_reader.readFloatBig(); - /* x174_ */ - x174_ = __dna_reader.readFloatBig(); - /* x178_ballCameraChaseElevation */ - x178_ballCameraChaseElevation = __dna_reader.readFloatBig(); - /* x17c_ballCameraChaseDampenAngle */ - x17c_ballCameraChaseDampenAngle = __dna_reader.readFloatBig(); - /* x180_ballCameraChaseDistance */ - x180_ballCameraChaseDistance = __dna_reader.readFloatBig(); - /* x184_ballCameraChaseYawSpeed */ - x184_ballCameraChaseYawSpeed = __dna_reader.readFloatBig(); - /* x188_ballCameraChaseAnglePerSecond */ - x188_ballCameraChaseAnglePerSecond = __dna_reader.readFloatBig(); - /* x18c_ballCameraChaseLookAtOffset */ - x18c_ballCameraChaseLookAtOffset = __dna_reader.readVec3fBig(); - /* x198_ballCameraChaseSpringConstant */ - x198_ballCameraChaseSpringConstant = __dna_reader.readFloatBig(); - /* x19c_ballCameraChaseSpringMax */ - x19c_ballCameraChaseSpringMax = __dna_reader.readFloatBig(); - /* x1a0_ballCameraChaseSpringTardis */ - x1a0_ballCameraChaseSpringTardis = __dna_reader.readFloatBig(); - /* x1a4_ballCameraBoostElevation */ - x1a4_ballCameraBoostElevation = __dna_reader.readFloatBig(); - /* x1a8_ballCameraBoostDampenAngle */ - x1a8_ballCameraBoostDampenAngle = __dna_reader.readFloatBig(); - /* x1ac_ballCameraBoostDistance */ - x1ac_ballCameraBoostDistance = __dna_reader.readFloatBig(); - /* x1b0_ballCameraBoostYawSpeed */ - x1b0_ballCameraBoostYawSpeed = __dna_reader.readFloatBig(); - /* x1b4_ballCameraBoostAnglePerSecond */ - x1b4_ballCameraBoostAnglePerSecond = __dna_reader.readFloatBig(); - /* x1b8_ballCameraBoostLookAtOffset */ - x1b8_ballCameraBoostLookAtOffset = __dna_reader.readVec3fBig(); - /* x1c4_ballCameraBoostSpringConstant */ - x1c4_ballCameraBoostSpringConstant = __dna_reader.readFloatBig(); - /* x1c8_ballCameraBoostSpringMax */ - x1c8_ballCameraBoostSpringMax = __dna_reader.readFloatBig(); - /* x1cc_ballCameraBoostSpringTardis */ - x1cc_ballCameraBoostSpringTardis = __dna_reader.readFloatBig(); - /* x1d0_ballCameraControlDistance */ - x1d0_ballCameraControlDistance = __dna_reader.readFloatBig(); - /* x1d4_ */ - x1d4_ = __dna_reader.readFloatBig(); - /* x1d8_ */ - x1d8_ = __dna_reader.readFloatBig(); - /* x1e4_leftStickDivisor */ - x1e4_leftStickDivisor = __dna_reader.readFloatBig(); - /* x1e8_rightStickDivisor */ - x1e8_rightStickDivisor = __dna_reader.readFloatBig(); - /* x200_ */ - x200_ = __dna_reader.readFloatBig(); - /* x204_ballTouchRadius */ - x204_ballTouchRadius = __dna_reader.readFloatBig(); - /* x20c_boostBallDrainTime */ - x20c_boostBallDrainTime = __dna_reader.readFloatBig(); - /* x218_boostBallMinChargeTime */ - x218_boostBallMinChargeTime = __dna_reader.readFloatBig(); - /* x21c_boostBallMinRelativeSpeedForDamage */ - x21c_boostBallMinRelativeSpeedForDamage = __dna_reader.readFloatBig(); - /* x220_boostBallChargeTime0 */ - x220_boostBallChargeTime0 = __dna_reader.readFloatBig(); - /* x224_boostBallChargeTime1 */ - x224_boostBallChargeTime1 = __dna_reader.readFloatBig(); - /* x210_boostBallMaxChargeTime */ - x228_boostBallChargeTime2 = x210_boostBallMaxChargeTime = __dna_reader.readFloatBig(); - /* x22c_boostBallIncrementalSpeed0 */ - x22c_boostBallIncrementalSpeed0 = __dna_reader.readFloatBig(); - /* x230_boostBallIncrementalSpeed1 */ - x230_boostBallIncrementalSpeed1 = __dna_reader.readFloatBig(); - /* x234_boostBallIncrementalSpeed2 */ - x234_boostBallIncrementalSpeed2 = __dna_reader.readFloatBig(); -} - -template <> -void CTweakBall::Enumerate(typename Write::StreamT& __dna_writer) { - /* x4_maxTranslationAcceleration[0] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[0]); - /* x4_maxTranslationAcceleration[1] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[1]); - /* x4_maxTranslationAcceleration[2] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[2]); - /* x4_maxTranslationAcceleration[3] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[3]); - /* x4_maxTranslationAcceleration[4] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[4]); - /* x4_maxTranslationAcceleration[5] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[5]); - /* x4_maxTranslationAcceleration[6] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[6]); - /* x4_maxTranslationAcceleration[7] */ - __dna_writer.writeFloatBig(x4_maxTranslationAcceleration[7]); - /* x24_translationFriction[0] */ - __dna_writer.writeFloatBig(x24_translationFriction[0]); - /* x24_translationFriction[1] */ - __dna_writer.writeFloatBig(x24_translationFriction[1]); - /* x24_translationFriction[2] */ - __dna_writer.writeFloatBig(x24_translationFriction[2]); - /* x24_translationFriction[3] */ - __dna_writer.writeFloatBig(x24_translationFriction[3]); - /* x24_translationFriction[4] */ - __dna_writer.writeFloatBig(x24_translationFriction[4]); - /* x24_translationFriction[5] */ - __dna_writer.writeFloatBig(x24_translationFriction[5]); - /* x24_translationFriction[6] */ - __dna_writer.writeFloatBig(x24_translationFriction[6]); - /* x24_translationFriction[7] */ - __dna_writer.writeFloatBig(x24_translationFriction[7]); - /* x44_translationMaxSpeed[0] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[0]); - /* x44_translationMaxSpeed[1] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[1]); - /* x44_translationMaxSpeed[2] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[2]); - /* x44_translationMaxSpeed[3] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[3]); - /* x44_translationMaxSpeed[4] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[4]); - /* x44_translationMaxSpeed[5] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[5]); - /* x44_translationMaxSpeed[6] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[6]); - /* x44_translationMaxSpeed[7] */ - __dna_writer.writeFloatBig(x44_translationMaxSpeed[7]); - /* x64_ */ - __dna_writer.writeFloatBig(x64_); - /* x68_ */ - __dna_writer.writeFloatBig(x68_); - /* x6c_ */ - __dna_writer.writeFloatBig(x6c_); - /* x70_ */ - __dna_writer.writeFloatBig(x70_); - /* xc4_ballForwardBrakingAcceleration[0] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[0]); - /* xc4_ballForwardBrakingAcceleration[1] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[1]); - /* xc4_ballForwardBrakingAcceleration[2] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[2]); - /* xc4_ballForwardBrakingAcceleration[3] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[3]); - /* xc4_ballForwardBrakingAcceleration[4] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[4]); - /* xc4_ballForwardBrakingAcceleration[5] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[5]); - /* xc4_ballForwardBrakingAcceleration[6] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[6]); - /* xc4_ballForwardBrakingAcceleration[7] */ - __dna_writer.writeFloatBig(xc4_ballForwardBrakingAcceleration[7]); - /* xe4_ballGravity */ - __dna_writer.writeFloatBig(xe4_ballGravity); - /* xe8_ballWaterGravity */ - __dna_writer.writeFloatBig(xe8_ballWaterGravity); - /* x14c_ */ - __dna_writer.writeFloatBig(x14c_); - /* x150_ */ - __dna_writer.writeFloatBig(x150_); - /* x158_ */ - __dna_writer.writeFloatBig(x158_); - /* x1dc_minimumAlignmentSpeed */ - __dna_writer.writeFloatBig(x1dc_minimumAlignmentSpeed); - /* x1e0_tireness */ - __dna_writer.writeFloatBig(x1e0_tireness); - /* x1ec_maxLeanAngle */ - __dna_writer.writeFloatBig(x1ec_maxLeanAngle); - /* x1f0_tireToMarbleThresholdSpeed */ - __dna_writer.writeFloatBig(x1f0_tireToMarbleThresholdSpeed); - /* x1f4_marbleToTireThresholdSpeed */ - __dna_writer.writeFloatBig(x1f4_marbleToTireThresholdSpeed); - /* x1f8_forceToLeanGain */ - __dna_writer.writeFloatBig(x1f8_forceToLeanGain); - /* x1fc_leanTrackingGain */ - __dna_writer.writeFloatBig(x1fc_leanTrackingGain); - /* x74_ballCameraAnglePerSecond */ - __dna_writer.writeFloatBig(x74_ballCameraAnglePerSecond); - /* x78_ballCameraOffset */ - __dna_writer.writeVec3fBig(x78_ballCameraOffset); - /* x84_ballCameraMinSpeedDistance */ - __dna_writer.writeFloatBig(x84_ballCameraMinSpeedDistance); - /* x88_ballCameraMaxSpeedDistance */ - __dna_writer.writeFloatBig(x88_ballCameraMaxSpeedDistance); - /* x8c_ballCameraBackwardsDistance */ - __dna_writer.writeFloatBig(x8c_ballCameraBackwardsDistance); - /* x90_ */ - __dna_writer.writeFloatBig(x90_); - /* x94_ballCameraSpringConstant */ - __dna_writer.writeFloatBig(x94_ballCameraSpringConstant); - /* x98_ballCameraSpringMax */ - __dna_writer.writeFloatBig(x98_ballCameraSpringMax); - /* x9c_ballCameraSpringTardis */ - __dna_writer.writeFloatBig(x9c_ballCameraSpringTardis); - /* xa0_ballCameraCentroidSpringConstant */ - __dna_writer.writeFloatBig(xa0_ballCameraCentroidSpringConstant); - /* xa4_ballCameraCentroidSpringMax */ - __dna_writer.writeFloatBig(xa4_ballCameraCentroidSpringMax); - /* xa8_ballCameraCentroidSpringTardis */ - __dna_writer.writeFloatBig(xa8_ballCameraCentroidSpringTardis); - /* xac_ballCameraCentroidDistanceSpringConstant */ - __dna_writer.writeFloatBig(xac_ballCameraCentroidDistanceSpringConstant); - /* xb0_ballCameraCentroidDistanceSpringMax */ - __dna_writer.writeFloatBig(xb0_ballCameraCentroidDistanceSpringMax); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - __dna_writer.writeFloatBig(xb4_ballCameraCentroidDistanceSpringTardis); - /* xb8_ballCameraLookAtSpringConstant */ - __dna_writer.writeFloatBig(xb8_ballCameraLookAtSpringConstant); - /* xbc_ballCameraLookAtSpringMax */ - __dna_writer.writeFloatBig(xbc_ballCameraLookAtSpringMax); - /* xc0_ballCameraLookAtSpringTardis */ - __dna_writer.writeFloatBig(xc0_ballCameraLookAtSpringTardis); - /* x154_ */ - __dna_writer.writeFloatBig(x154_); - /* x15c_ */ - __dna_writer.writeFloatBig(x15c_); - /* x160_ */ - __dna_writer.writeFloatBig(x160_); - /* x164_ */ - __dna_writer.writeFloatBig(x164_); - /* x168_ */ - __dna_writer.writeFloatBig(x168_); - /* x16c_ */ - __dna_writer.writeFloatBig(x16c_); - /* x170_conservativeDoorCamDistance */ - __dna_writer.writeFloatBig(x170_conservativeDoorCamDistance); - /* x174_ */ - __dna_writer.writeFloatBig(x174_); - /* x178_ballCameraChaseElevation */ - __dna_writer.writeFloatBig(x178_ballCameraChaseElevation); - /* x17c_ballCameraChaseDampenAngle */ - __dna_writer.writeFloatBig(x17c_ballCameraChaseDampenAngle); - /* x180_ballCameraChaseDistance */ - __dna_writer.writeFloatBig(x180_ballCameraChaseDistance); - /* x184_ballCameraChaseYawSpeed */ - __dna_writer.writeFloatBig(x184_ballCameraChaseYawSpeed); - /* x188_ballCameraChaseAnglePerSecond */ - __dna_writer.writeFloatBig(x188_ballCameraChaseAnglePerSecond); - /* x18c_ballCameraChaseLookAtOffset */ - __dna_writer.writeVec3fBig(x18c_ballCameraChaseLookAtOffset); - /* x198_ballCameraChaseSpringConstant */ - __dna_writer.writeFloatBig(x198_ballCameraChaseSpringConstant); - /* x19c_ballCameraChaseSpringMax */ - __dna_writer.writeFloatBig(x19c_ballCameraChaseSpringMax); - /* x1a0_ballCameraChaseSpringTardis */ - __dna_writer.writeFloatBig(x1a0_ballCameraChaseSpringTardis); - /* x1a4_ballCameraBoostElevation */ - __dna_writer.writeFloatBig(x1a4_ballCameraBoostElevation); - /* x1a8_ballCameraBoostDampenAngle */ - __dna_writer.writeFloatBig(x1a8_ballCameraBoostDampenAngle); - /* x1ac_ballCameraBoostDistance */ - __dna_writer.writeFloatBig(x1ac_ballCameraBoostDistance); - /* x1b0_ballCameraBoostYawSpeed */ - __dna_writer.writeFloatBig(x1b0_ballCameraBoostYawSpeed); - /* x1b4_ballCameraBoostAnglePerSecond */ - __dna_writer.writeFloatBig(x1b4_ballCameraBoostAnglePerSecond); - /* x1b8_ballCameraBoostLookAtOffset */ - __dna_writer.writeVec3fBig(x1b8_ballCameraBoostLookAtOffset); - /* x1c4_ballCameraBoostSpringConstant */ - __dna_writer.writeFloatBig(x1c4_ballCameraBoostSpringConstant); - /* x1c8_ballCameraBoostSpringMax */ - __dna_writer.writeFloatBig(x1c8_ballCameraBoostSpringMax); - /* x1cc_ballCameraBoostSpringTardis */ - __dna_writer.writeFloatBig(x1cc_ballCameraBoostSpringTardis); - /* x1d0_ballCameraControlDistance */ - __dna_writer.writeFloatBig(x1d0_ballCameraControlDistance); - /* x1d4_ */ - __dna_writer.writeFloatBig(x1d4_); - /* x1d8_ */ - __dna_writer.writeFloatBig(x1d8_); - /* x1e4_leftStickDivisor */ - __dna_writer.writeFloatBig(x1e4_leftStickDivisor); - /* x1e8_rightStickDivisor */ - __dna_writer.writeFloatBig(x1e8_rightStickDivisor); - /* x200_ */ - __dna_writer.writeFloatBig(x200_); - /* x204_ballTouchRadius */ - __dna_writer.writeFloatBig(x204_ballTouchRadius); - /* x20c_boostBallDrainTime */ - __dna_writer.writeFloatBig(x20c_boostBallDrainTime); - /* x218_boostBallMinChargeTime */ - __dna_writer.writeFloatBig(x218_boostBallMinChargeTime); - /* x21c_boostBallMinRelativeSpeedForDamage */ - __dna_writer.writeFloatBig(x21c_boostBallMinRelativeSpeedForDamage); - /* x220_boostBallChargeTime0 */ - __dna_writer.writeFloatBig(x220_boostBallChargeTime0); - /* x224_boostBallChargeTime1 */ - __dna_writer.writeFloatBig(x224_boostBallChargeTime1); - /* x210_boostBallMaxChargeTime */ - __dna_writer.writeFloatBig(x210_boostBallMaxChargeTime); - /* x22c_boostBallIncrementalSpeed0 */ - __dna_writer.writeFloatBig(x22c_boostBallIncrementalSpeed0); - /* x230_boostBallIncrementalSpeed1 */ - __dna_writer.writeFloatBig(x230_boostBallIncrementalSpeed1); - /* x234_boostBallIncrementalSpeed2 */ - __dna_writer.writeFloatBig(x234_boostBallIncrementalSpeed2); -} - -template <> -void CTweakBall::Enumerate(typename ReadYaml::StreamT& __dna_docin) { - /* x4_maxTranslationAcceleration */ - size_t __x4_Count; - if (auto v = __dna_docin.enterSubVector("x4_maxTranslationAcceleration", __x4_Count)) { - /* x4_maxTranslationAcceleration[0] */ - x4_maxTranslationAcceleration[0] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[1] */ - x4_maxTranslationAcceleration[1] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[2] */ - x4_maxTranslationAcceleration[2] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[3] */ - x4_maxTranslationAcceleration[3] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[4] */ - x4_maxTranslationAcceleration[4] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[5] */ - x4_maxTranslationAcceleration[5] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[6] */ - x4_maxTranslationAcceleration[6] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - /* x4_maxTranslationAcceleration[7] */ - x4_maxTranslationAcceleration[7] = __dna_docin.readFloat("x4_maxTranslationAcceleration"); - } - /* x24_translationFriction */ - size_t __x24_Count; - if (auto v = __dna_docin.enterSubVector("x24_translationFriction", __x24_Count)) { - /* x24_translationFriction[0] */ - x24_translationFriction[0] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[1] */ - x24_translationFriction[1] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[2] */ - x24_translationFriction[2] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[3] */ - x24_translationFriction[3] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[4] */ - x24_translationFriction[4] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[5] */ - x24_translationFriction[5] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[6] */ - x24_translationFriction[6] = __dna_docin.readFloat("x24_translationFriction"); - /* x24_translationFriction[7] */ - x24_translationFriction[7] = __dna_docin.readFloat("x24_translationFriction"); - } - /* x44_translationMaxSpeed */ - size_t __x44_Count; - if (auto v = __dna_docin.enterSubVector("x44_translationMaxSpeed", __x44_Count)) { - /* x44_translationMaxSpeed[0] */ - x44_translationMaxSpeed[0] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[1] */ - x44_translationMaxSpeed[1] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[2] */ - x44_translationMaxSpeed[2] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[3] */ - x44_translationMaxSpeed[3] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[4] */ - x44_translationMaxSpeed[4] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[5] */ - x44_translationMaxSpeed[5] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[6] */ - x44_translationMaxSpeed[6] = __dna_docin.readFloat("x44_translationMaxSpeed"); - /* x44_translationMaxSpeed[7] */ - x44_translationMaxSpeed[7] = __dna_docin.readFloat("x44_translationMaxSpeed"); - } - /* x64_ */ - x64_ = __dna_docin.readFloat("x64_"); - /* x68_ */ - x68_ = __dna_docin.readFloat("x68_"); - /* x6c_ */ - x6c_ = __dna_docin.readFloat("x6c_"); - /* x70_ */ - x70_ = __dna_docin.readFloat("x70_"); - /* xc4_ballForwardBrakingAcceleration */ - size_t __xc4_Count; - if (auto v = __dna_docin.enterSubVector("xc4_ballForwardBrakingAcceleration", __xc4_Count)) { - /* xc4_ballForwardBrakingAcceleration[0] */ - xc4_ballForwardBrakingAcceleration[0] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[1] */ - xc4_ballForwardBrakingAcceleration[1] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[2] */ - xc4_ballForwardBrakingAcceleration[2] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[3] */ - xc4_ballForwardBrakingAcceleration[3] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[4] */ - xc4_ballForwardBrakingAcceleration[4] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[5] */ - xc4_ballForwardBrakingAcceleration[5] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[6] */ - xc4_ballForwardBrakingAcceleration[6] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - /* xc4_ballForwardBrakingAcceleration[7] */ - xc4_ballForwardBrakingAcceleration[7] = __dna_docin.readFloat("xc4_ballForwardBrakingAcceleration"); - } - /* xe4_ballGravity */ - xe4_ballGravity = __dna_docin.readFloat("xe4_ballGravity"); - /* xe8_ballWaterGravity */ - xe8_ballWaterGravity = __dna_docin.readFloat("xe8_ballWaterGravity"); - /* x14c_ */ - x14c_ = __dna_docin.readFloat("x14c_"); - /* x150_ */ - x150_ = __dna_docin.readFloat("x150_"); - /* x158_ */ - x158_ = __dna_docin.readFloat("x158_"); - /* x1dc_minimumAlignmentSpeed */ - x1dc_minimumAlignmentSpeed = __dna_docin.readFloat("x1dc_minimumAlignmentSpeed"); - /* x1e0_tireness */ - x1e0_tireness = __dna_docin.readFloat("x1e0_tireness"); - /* x1ec_maxLeanAngle */ - x1ec_maxLeanAngle = __dna_docin.readFloat("x1ec_maxLeanAngle"); - /* x1f0_tireToMarbleThresholdSpeed */ - x1f0_tireToMarbleThresholdSpeed = __dna_docin.readFloat("x1f0_tireToMarbleThresholdSpeed"); - /* x1f4_marbleToTireThresholdSpeed */ - x1f4_marbleToTireThresholdSpeed = __dna_docin.readFloat("x1f4_marbleToTireThresholdSpeed"); - /* x1f8_forceToLeanGain */ - x1f8_forceToLeanGain = __dna_docin.readFloat("x1f8_forceToLeanGain"); - /* x1fc_leanTrackingGain */ - x1fc_leanTrackingGain = __dna_docin.readFloat("x1fc_leanTrackingGain"); - /* x74_ballCameraAnglePerSecond */ - x74_ballCameraAnglePerSecond = __dna_docin.readFloat("x74_ballCameraAnglePerSecond"); - /* x78_ballCameraOffset */ - x78_ballCameraOffset = __dna_docin.readVec3f("x78_ballCameraOffset"); - /* x84_ballCameraMinSpeedDistance */ - x84_ballCameraMinSpeedDistance = __dna_docin.readFloat("x84_ballCameraMinSpeedDistance"); - /* x88_ballCameraMaxSpeedDistance */ - x88_ballCameraMaxSpeedDistance = __dna_docin.readFloat("x88_ballCameraMaxSpeedDistance"); - /* x8c_ballCameraBackwardsDistance */ - x8c_ballCameraBackwardsDistance = __dna_docin.readFloat("x8c_ballCameraBackwardsDistance"); - /* x90_ */ - x90_ = __dna_docin.readFloat("x90_"); - /* x94_ballCameraSpringConstant */ - x94_ballCameraSpringConstant = __dna_docin.readFloat("x94_ballCameraSpringConstant"); - /* x98_ballCameraSpringMax */ - x98_ballCameraSpringMax = __dna_docin.readFloat("x98_ballCameraSpringMax"); - /* x9c_ballCameraSpringTardis */ - x9c_ballCameraSpringTardis = __dna_docin.readFloat("x9c_ballCameraSpringTardis"); - /* xa0_ballCameraCentroidSpringConstant */ - xa0_ballCameraCentroidSpringConstant = __dna_docin.readFloat("xa0_ballCameraCentroidSpringConstant"); - /* xa4_ballCameraCentroidSpringMax */ - xa4_ballCameraCentroidSpringMax = __dna_docin.readFloat("xa4_ballCameraCentroidSpringMax"); - /* xa8_ballCameraCentroidSpringTardis */ - xa8_ballCameraCentroidSpringTardis = __dna_docin.readFloat("xa8_ballCameraCentroidSpringTardis"); - /* xac_ballCameraCentroidDistanceSpringConstant */ - xac_ballCameraCentroidDistanceSpringConstant = __dna_docin.readFloat("xac_ballCameraCentroidDistanceSpringConstant"); - /* xb0_ballCameraCentroidDistanceSpringMax */ - xb0_ballCameraCentroidDistanceSpringMax = __dna_docin.readFloat("xb0_ballCameraCentroidDistanceSpringMax"); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - xb4_ballCameraCentroidDistanceSpringTardis = __dna_docin.readFloat("xb4_ballCameraCentroidDistanceSpringTardis"); - /* xb8_ballCameraLookAtSpringConstant */ - xb8_ballCameraLookAtSpringConstant = __dna_docin.readFloat("xb8_ballCameraLookAtSpringConstant"); - /* xbc_ballCameraLookAtSpringMax */ - xbc_ballCameraLookAtSpringMax = __dna_docin.readFloat("xbc_ballCameraLookAtSpringMax"); - /* xc0_ballCameraLookAtSpringTardis */ - xc0_ballCameraLookAtSpringTardis = __dna_docin.readFloat("xc0_ballCameraLookAtSpringTardis"); - /* x154_ */ - x154_ = __dna_docin.readFloat("x154_"); - /* x15c_ */ - x15c_ = __dna_docin.readFloat("x15c_"); - /* x160_ */ - x160_ = __dna_docin.readFloat("x160_"); - /* x164_ */ - x164_ = __dna_docin.readFloat("x164_"); - /* x168_ */ - x168_ = __dna_docin.readFloat("x168_"); - /* x16c_ */ - x16c_ = __dna_docin.readFloat("x16c_"); - /* x170_conservativeDoorCamDistance */ - x170_conservativeDoorCamDistance = __dna_docin.readFloat("x170_conservativeDoorCamDistance"); - /* x174_ */ - x174_ = __dna_docin.readFloat("x174_"); - /* x178_ballCameraChaseElevation */ - x178_ballCameraChaseElevation = __dna_docin.readFloat("x178_ballCameraChaseElevation"); - /* x17c_ballCameraChaseDampenAngle */ - x17c_ballCameraChaseDampenAngle = __dna_docin.readFloat("x17c_ballCameraChaseDampenAngle"); - /* x180_ballCameraChaseDistance */ - x180_ballCameraChaseDistance = __dna_docin.readFloat("x180_ballCameraChaseDistance"); - /* x184_ballCameraChaseYawSpeed */ - x184_ballCameraChaseYawSpeed = __dna_docin.readFloat("x184_ballCameraChaseYawSpeed"); - /* x188_ballCameraChaseAnglePerSecond */ - x188_ballCameraChaseAnglePerSecond = __dna_docin.readFloat("x188_ballCameraChaseAnglePerSecond"); - /* x18c_ballCameraChaseLookAtOffset */ - x18c_ballCameraChaseLookAtOffset = __dna_docin.readVec3f("x18c_ballCameraChaseLookAtOffset"); - /* x198_ballCameraChaseSpringConstant */ - x198_ballCameraChaseSpringConstant = __dna_docin.readFloat("x198_ballCameraChaseSpringConstant"); - /* x19c_ballCameraChaseSpringMax */ - x19c_ballCameraChaseSpringMax = __dna_docin.readFloat("x19c_ballCameraChaseSpringMax"); - /* x1a0_ballCameraChaseSpringTardis */ - x1a0_ballCameraChaseSpringTardis = __dna_docin.readFloat("x1a0_ballCameraChaseSpringTardis"); - /* x1a4_ballCameraBoostElevation */ - x1a4_ballCameraBoostElevation = __dna_docin.readFloat("x1a4_ballCameraBoostElevation"); - /* x1a8_ballCameraBoostDampenAngle */ - x1a8_ballCameraBoostDampenAngle = __dna_docin.readFloat("x1a8_ballCameraBoostDampenAngle"); - /* x1ac_ballCameraBoostDistance */ - x1ac_ballCameraBoostDistance = __dna_docin.readFloat("x1ac_ballCameraBoostDistance"); - /* x1b0_ballCameraBoostYawSpeed */ - x1b0_ballCameraBoostYawSpeed = __dna_docin.readFloat("x1b0_ballCameraBoostYawSpeed"); - /* x1b4_ballCameraBoostAnglePerSecond */ - x1b4_ballCameraBoostAnglePerSecond = __dna_docin.readFloat("x1b4_ballCameraBoostAnglePerSecond"); - /* x1b8_ballCameraBoostLookAtOffset */ - x1b8_ballCameraBoostLookAtOffset = __dna_docin.readVec3f("x1b8_ballCameraBoostLookAtOffset"); - /* x1c4_ballCameraBoostSpringConstant */ - x1c4_ballCameraBoostSpringConstant = __dna_docin.readFloat("x1c4_ballCameraBoostSpringConstant"); - /* x1c8_ballCameraBoostSpringMax */ - x1c8_ballCameraBoostSpringMax = __dna_docin.readFloat("x1c8_ballCameraBoostSpringMax"); - /* x1cc_ballCameraBoostSpringTardis */ - x1cc_ballCameraBoostSpringTardis = __dna_docin.readFloat("x1cc_ballCameraBoostSpringTardis"); - /* x1d0_ballCameraControlDistance */ - x1d0_ballCameraControlDistance = __dna_docin.readFloat("x1d0_ballCameraControlDistance"); - /* x1d4_ */ - x1d4_ = __dna_docin.readFloat("x1d4_"); - /* x1d8_ */ - x1d8_ = __dna_docin.readFloat("x1d8_"); - /* x1e4_leftStickDivisor */ - x1e4_leftStickDivisor = __dna_docin.readFloat("x1e4_leftStickDivisor"); - /* x1e8_rightStickDivisor */ - x1e8_rightStickDivisor = __dna_docin.readFloat("x1e8_rightStickDivisor"); - /* x200_ */ - x200_ = __dna_docin.readFloat("x200_"); - /* x204_ballTouchRadius */ - x204_ballTouchRadius = __dna_docin.readFloat("x204_ballTouchRadius"); - /* x20c_boostBallDrainTime */ - x20c_boostBallDrainTime = __dna_docin.readFloat("x20c_boostBallDrainTime"); - /* x218_boostBallMinChargeTime */ - x218_boostBallMinChargeTime = __dna_docin.readFloat("x218_boostBallMinChargeTime"); - /* x21c_boostBallMinRelativeSpeedForDamage */ - x21c_boostBallMinRelativeSpeedForDamage = __dna_docin.readFloat("x21c_boostBallMinRelativeSpeedForDamage"); - /* x220_boostBallChargeTime0 */ - x220_boostBallChargeTime0 = __dna_docin.readFloat("x220_boostBallChargeTime0"); - /* x224_boostBallChargeTime1 */ - x224_boostBallChargeTime1 = __dna_docin.readFloat("x224_boostBallChargeTime1"); - /* x210_boostBallMaxChargeTime */ - x228_boostBallChargeTime2 = x210_boostBallMaxChargeTime = __dna_docin.readFloat("x210_boostBallMaxChargeTime"); - /* x22c_boostBallIncrementalSpeed0 */ - x22c_boostBallIncrementalSpeed0 = __dna_docin.readFloat("x22c_boostBallIncrementalSpeed0"); - /* x230_boostBallIncrementalSpeed1 */ - x230_boostBallIncrementalSpeed1 = __dna_docin.readFloat("x230_boostBallIncrementalSpeed1"); - /* x234_boostBallIncrementalSpeed2 */ - x234_boostBallIncrementalSpeed2 = __dna_docin.readFloat("x234_boostBallIncrementalSpeed2"); -} - -template <> -void CTweakBall::Enumerate(typename WriteYaml::StreamT& __dna_docout) { - /* x4_maxTranslationAcceleration */ - if (auto v = __dna_docout.enterSubVector("x4_maxTranslationAcceleration")) { - /* x4_maxTranslationAcceleration[0] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[0]); - /* x4_maxTranslationAcceleration[1] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[1]); - /* x4_maxTranslationAcceleration[2] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[2]); - /* x4_maxTranslationAcceleration[3] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[3]); - /* x4_maxTranslationAcceleration[4] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[4]); - /* x4_maxTranslationAcceleration[5] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[5]); - /* x4_maxTranslationAcceleration[6] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[6]); - /* x4_maxTranslationAcceleration[7] */ - __dna_docout.writeFloat("x4_maxTranslationAcceleration", x4_maxTranslationAcceleration[7]); - } - /* x24_translationFriction */ - if (auto v = __dna_docout.enterSubVector("x24_translationFriction")) { - /* x24_translationFriction[0] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[0]); - /* x24_translationFriction[1] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[1]); - /* x24_translationFriction[2] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[2]); - /* x24_translationFriction[3] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[3]); - /* x24_translationFriction[4] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[4]); - /* x24_translationFriction[5] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[5]); - /* x24_translationFriction[6] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[6]); - /* x24_translationFriction[7] */ - __dna_docout.writeFloat("x24_translationFriction", x24_translationFriction[7]); - } - /* x44_translationMaxSpeed */ - if (auto v = __dna_docout.enterSubVector("x44_translationMaxSpeed")) { - /* x44_translationMaxSpeed[0] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[0]); - /* x44_translationMaxSpeed[1] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[1]); - /* x44_translationMaxSpeed[2] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[2]); - /* x44_translationMaxSpeed[3] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[3]); - /* x44_translationMaxSpeed[4] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[4]); - /* x44_translationMaxSpeed[5] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[5]); - /* x44_translationMaxSpeed[6] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[6]); - /* x44_translationMaxSpeed[7] */ - __dna_docout.writeFloat("x44_translationMaxSpeed", x44_translationMaxSpeed[7]); - } - /* x64_ */ - __dna_docout.writeFloat("x64_", x64_); - /* x68_ */ - __dna_docout.writeFloat("x68_", x68_); - /* x6c_ */ - __dna_docout.writeFloat("x6c_", x6c_); - /* x70_ */ - __dna_docout.writeFloat("x70_", x70_); - /* xc4_ballForwardBrakingAcceleration */ - if (auto v = __dna_docout.enterSubVector("xc4_ballForwardBrakingAcceleration")) { - /* xc4_ballForwardBrakingAcceleration[0] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[0]); - /* xc4_ballForwardBrakingAcceleration[1] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[1]); - /* xc4_ballForwardBrakingAcceleration[2] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[2]); - /* xc4_ballForwardBrakingAcceleration[3] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[3]); - /* xc4_ballForwardBrakingAcceleration[4] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[4]); - /* xc4_ballForwardBrakingAcceleration[5] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[5]); - /* xc4_ballForwardBrakingAcceleration[6] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[6]); - /* xc4_ballForwardBrakingAcceleration[7] */ - __dna_docout.writeFloat("xc4_ballForwardBrakingAcceleration", xc4_ballForwardBrakingAcceleration[7]); - } - /* xe4_ballGravity */ - __dna_docout.writeFloat("xe4_ballGravity", xe4_ballGravity); - /* xe8_ballWaterGravity */ - __dna_docout.writeFloat("xe8_ballWaterGravity", xe8_ballWaterGravity); - /* x14c_ */ - __dna_docout.writeFloat("x14c_", x14c_); - /* x150_ */ - __dna_docout.writeFloat("x150_", x150_); - /* x158_ */ - __dna_docout.writeFloat("x158_", x158_); - /* x1dc_minimumAlignmentSpeed */ - __dna_docout.writeFloat("x1dc_minimumAlignmentSpeed", x1dc_minimumAlignmentSpeed); - /* x1e0_tireness */ - __dna_docout.writeFloat("x1e0_tireness", x1e0_tireness); - /* x1ec_maxLeanAngle */ - __dna_docout.writeFloat("x1ec_maxLeanAngle", x1ec_maxLeanAngle); - /* x1f0_tireToMarbleThresholdSpeed */ - __dna_docout.writeFloat("x1f0_tireToMarbleThresholdSpeed", x1f0_tireToMarbleThresholdSpeed); - /* x1f4_marbleToTireThresholdSpeed */ - __dna_docout.writeFloat("x1f4_marbleToTireThresholdSpeed", x1f4_marbleToTireThresholdSpeed); - /* x1f8_forceToLeanGain */ - __dna_docout.writeFloat("x1f8_forceToLeanGain", x1f8_forceToLeanGain); - /* x1fc_leanTrackingGain */ - __dna_docout.writeFloat("x1fc_leanTrackingGain", x1fc_leanTrackingGain); - /* x74_ballCameraAnglePerSecond */ - __dna_docout.writeFloat("x74_ballCameraAnglePerSecond", x74_ballCameraAnglePerSecond); - /* x78_ballCameraOffset */ - __dna_docout.writeVec3f("x78_ballCameraOffset", x78_ballCameraOffset); - /* x84_ballCameraMinSpeedDistance */ - __dna_docout.writeFloat("x84_ballCameraMinSpeedDistance", x84_ballCameraMinSpeedDistance); - /* x88_ballCameraMaxSpeedDistance */ - __dna_docout.writeFloat("x88_ballCameraMaxSpeedDistance", x88_ballCameraMaxSpeedDistance); - /* x8c_ballCameraBackwardsDistance */ - __dna_docout.writeFloat("x8c_ballCameraBackwardsDistance", x8c_ballCameraBackwardsDistance); - /* x90_ */ - __dna_docout.writeFloat("x90_", x90_); - /* x94_ballCameraSpringConstant */ - __dna_docout.writeFloat("x94_ballCameraSpringConstant", x94_ballCameraSpringConstant); - /* x98_ballCameraSpringMax */ - __dna_docout.writeFloat("x98_ballCameraSpringMax", x98_ballCameraSpringMax); - /* x9c_ballCameraSpringTardis */ - __dna_docout.writeFloat("x9c_ballCameraSpringTardis", x9c_ballCameraSpringTardis); - /* xa0_ballCameraCentroidSpringConstant */ - __dna_docout.writeFloat("xa0_ballCameraCentroidSpringConstant", xa0_ballCameraCentroidSpringConstant); - /* xa4_ballCameraCentroidSpringMax */ - __dna_docout.writeFloat("xa4_ballCameraCentroidSpringMax", xa4_ballCameraCentroidSpringMax); - /* xa8_ballCameraCentroidSpringTardis */ - __dna_docout.writeFloat("xa8_ballCameraCentroidSpringTardis", xa8_ballCameraCentroidSpringTardis); - /* xac_ballCameraCentroidDistanceSpringConstant */ - __dna_docout.writeFloat("xac_ballCameraCentroidDistanceSpringConstant", xac_ballCameraCentroidDistanceSpringConstant); - /* xb0_ballCameraCentroidDistanceSpringMax */ - __dna_docout.writeFloat("xb0_ballCameraCentroidDistanceSpringMax", xb0_ballCameraCentroidDistanceSpringMax); - /* xb4_ballCameraCentroidDistanceSpringTardis */ - __dna_docout.writeFloat("xb4_ballCameraCentroidDistanceSpringTardis", xb4_ballCameraCentroidDistanceSpringTardis); - /* xb8_ballCameraLookAtSpringConstant */ - __dna_docout.writeFloat("xb8_ballCameraLookAtSpringConstant", xb8_ballCameraLookAtSpringConstant); - /* xbc_ballCameraLookAtSpringMax */ - __dna_docout.writeFloat("xbc_ballCameraLookAtSpringMax", xbc_ballCameraLookAtSpringMax); - /* xc0_ballCameraLookAtSpringTardis */ - __dna_docout.writeFloat("xc0_ballCameraLookAtSpringTardis", xc0_ballCameraLookAtSpringTardis); - /* x154_ */ - __dna_docout.writeFloat("x154_", x154_); - /* x15c_ */ - __dna_docout.writeFloat("x15c_", x15c_); - /* x160_ */ - __dna_docout.writeFloat("x160_", x160_); - /* x164_ */ - __dna_docout.writeFloat("x164_", x164_); - /* x168_ */ - __dna_docout.writeFloat("x168_", x168_); - /* x16c_ */ - __dna_docout.writeFloat("x16c_", x16c_); - /* x170_conservativeDoorCamDistance */ - __dna_docout.writeFloat("x170_conservativeDoorCamDistance", x170_conservativeDoorCamDistance); - /* x174_ */ - __dna_docout.writeFloat("x174_", x174_); - /* x178_ballCameraChaseElevation */ - __dna_docout.writeFloat("x178_ballCameraChaseElevation", x178_ballCameraChaseElevation); - /* x17c_ballCameraChaseDampenAngle */ - __dna_docout.writeFloat("x17c_ballCameraChaseDampenAngle", x17c_ballCameraChaseDampenAngle); - /* x180_ballCameraChaseDistance */ - __dna_docout.writeFloat("x180_ballCameraChaseDistance", x180_ballCameraChaseDistance); - /* x184_ballCameraChaseYawSpeed */ - __dna_docout.writeFloat("x184_ballCameraChaseYawSpeed", x184_ballCameraChaseYawSpeed); - /* x188_ballCameraChaseAnglePerSecond */ - __dna_docout.writeFloat("x188_ballCameraChaseAnglePerSecond", x188_ballCameraChaseAnglePerSecond); - /* x18c_ballCameraChaseLookAtOffset */ - __dna_docout.writeVec3f("x18c_ballCameraChaseLookAtOffset", x18c_ballCameraChaseLookAtOffset); - /* x198_ballCameraChaseSpringConstant */ - __dna_docout.writeFloat("x198_ballCameraChaseSpringConstant", x198_ballCameraChaseSpringConstant); - /* x19c_ballCameraChaseSpringMax */ - __dna_docout.writeFloat("x19c_ballCameraChaseSpringMax", x19c_ballCameraChaseSpringMax); - /* x1a0_ballCameraChaseSpringTardis */ - __dna_docout.writeFloat("x1a0_ballCameraChaseSpringTardis", x1a0_ballCameraChaseSpringTardis); - /* x1a4_ballCameraBoostElevation */ - __dna_docout.writeFloat("x1a4_ballCameraBoostElevation", x1a4_ballCameraBoostElevation); - /* x1a8_ballCameraBoostDampenAngle */ - __dna_docout.writeFloat("x1a8_ballCameraBoostDampenAngle", x1a8_ballCameraBoostDampenAngle); - /* x1ac_ballCameraBoostDistance */ - __dna_docout.writeFloat("x1ac_ballCameraBoostDistance", x1ac_ballCameraBoostDistance); - /* x1b0_ballCameraBoostYawSpeed */ - __dna_docout.writeFloat("x1b0_ballCameraBoostYawSpeed", x1b0_ballCameraBoostYawSpeed); - /* x1b4_ballCameraBoostAnglePerSecond */ - __dna_docout.writeFloat("x1b4_ballCameraBoostAnglePerSecond", x1b4_ballCameraBoostAnglePerSecond); - /* x1b8_ballCameraBoostLookAtOffset */ - __dna_docout.writeVec3f("x1b8_ballCameraBoostLookAtOffset", x1b8_ballCameraBoostLookAtOffset); - /* x1c4_ballCameraBoostSpringConstant */ - __dna_docout.writeFloat("x1c4_ballCameraBoostSpringConstant", x1c4_ballCameraBoostSpringConstant); - /* x1c8_ballCameraBoostSpringMax */ - __dna_docout.writeFloat("x1c8_ballCameraBoostSpringMax", x1c8_ballCameraBoostSpringMax); - /* x1cc_ballCameraBoostSpringTardis */ - __dna_docout.writeFloat("x1cc_ballCameraBoostSpringTardis", x1cc_ballCameraBoostSpringTardis); - /* x1d0_ballCameraControlDistance */ - __dna_docout.writeFloat("x1d0_ballCameraControlDistance", x1d0_ballCameraControlDistance); - /* x1d4_ */ - __dna_docout.writeFloat("x1d4_", x1d4_); - /* x1d8_ */ - __dna_docout.writeFloat("x1d8_", x1d8_); - /* x1e4_leftStickDivisor */ - __dna_docout.writeFloat("x1e4_leftStickDivisor", x1e4_leftStickDivisor); - /* x1e8_rightStickDivisor */ - __dna_docout.writeFloat("x1e8_rightStickDivisor", x1e8_rightStickDivisor); - /* x200_ */ - __dna_docout.writeFloat("x200_", x200_); - /* x204_ballTouchRadius */ - __dna_docout.writeFloat("x204_ballTouchRadius", x204_ballTouchRadius); - /* x20c_boostBallDrainTime */ - __dna_docout.writeFloat("x20c_boostBallDrainTime", x20c_boostBallDrainTime); - /* x218_boostBallMinChargeTime */ - __dna_docout.writeFloat("x218_boostBallMinChargeTime", x218_boostBallMinChargeTime); - /* x21c_boostBallMinRelativeSpeedForDamage */ - __dna_docout.writeFloat("x21c_boostBallMinRelativeSpeedForDamage", x21c_boostBallMinRelativeSpeedForDamage); - /* x220_boostBallChargeTime0 */ - __dna_docout.writeFloat("x220_boostBallChargeTime0", x220_boostBallChargeTime0); - /* x224_boostBallChargeTime1 */ - __dna_docout.writeFloat("x224_boostBallChargeTime1", x224_boostBallChargeTime1); - /* x210_boostBallMaxChargeTime */ - __dna_docout.writeFloat("x210_boostBallMaxChargeTime", x210_boostBallMaxChargeTime); - /* x22c_boostBallIncrementalSpeed0 */ - __dna_docout.writeFloat("x22c_boostBallIncrementalSpeed0", x22c_boostBallIncrementalSpeed0); - /* x230_boostBallIncrementalSpeed1 */ - __dna_docout.writeFloat("x230_boostBallIncrementalSpeed1", x230_boostBallIncrementalSpeed1); - /* x234_boostBallIncrementalSpeed2 */ - __dna_docout.writeFloat("x234_boostBallIncrementalSpeed2", x234_boostBallIncrementalSpeed2); -} - -std::string_view CTweakBall::DNAType() { return "DataSpec::DNAMP1::CTweakBall"sv; } - -template <> -void CTweakBall::Enumerate(typename BinarySize::StreamT& s) { - s += 456; -} - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakCameraBob.hpp b/DataSpec/DNAMP1/Tweaks/CTweakCameraBob.hpp deleted file mode 100644 index 743705047..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakCameraBob.hpp +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include "../../DNACommon/DNACommon.hpp" - -namespace DataSpec::DNAMP1 { -struct CTweakCameraBob : BigDNA { - AT_DECL_DNA_YAML - Value cameraBobExtentX; - Value cameraBobExtentY; - Value cameraBobPeriod; - Value orbitScale; - Value maxOrbitScale; - Value slowSpeedPeriodScale; - Value targetMagnitudeTrackingRate; - Value landingBobSpringConstant; - Value viewWanderRadius; - Value viewWanderSpeedMin; - Value viewWanderSpeedMax; - Value viewWanderRollVariation; - Value gunBobMagnitude; - Value helmetBobMagnitude; -}; -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakParticle.hpp b/DataSpec/DNAMP1/Tweaks/CTweakParticle.hpp deleted file mode 100644 index 79e4cfb02..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakParticle.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakParticle.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakParticle final : ITweakParticle { - AT_DECL_DNA_YAML - String<-1> m_particle; - String<-1> m_powerBeam; - String<-1> m_genThrust; - - CTweakParticle() = default; - CTweakParticle(athena::io::IStreamReader& reader) { this->read(reader); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayer.cpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayer.cpp deleted file mode 100644 index e3fbea5c7..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayer.cpp +++ /dev/null @@ -1,2656 +0,0 @@ -#include "CTweakPlayer.hpp" -#include "zeus/Math.hpp" - -#include -#include - -#define DEFINE_CVAR_GLOBAL(name) \ - constexpr std::string_view sk##name = std::string_view("tweak.player." #name); \ - hecl::CVar* tw_##name = nullptr; - -#define CREATE_CVAR(name, help, value, flags) \ - tw_##name = mgr->findOrMakeCVar(sk##name, help, value, flags); \ - if (tw_##name->wasDeserialized()) { \ - tw_##name->toValue(value); \ - } \ - tw_##name->addListener([this](hecl::CVar* cv) { _tweakListener(cv); }); - -#define CREATE_CVAR_BITFIELD(name, help, value, flags) \ - { \ - bool tmp = value; \ - CREATE_CVAR(name, help, tmp, flags) \ - } - -#define UPDATE_CVAR(name, cv, value) \ - if ((cv) == tw_##name) { \ - (cv)->toValue(value); \ - return; \ - } - -#define UPDATE_CVAR_BITFIELD(name, cv, value) \ - { \ - bool tmp = value; \ - UPDATE_CVAR(name, cv, tmp) \ - (value) = tmp; \ - } - -namespace DataSpec::DNAMP1 { -namespace { -static constexpr hecl::CVar::EFlags skDefaultFlags = - hecl::CVar::EFlags::Game | hecl::CVar::EFlags::Cheat | hecl::CVar::EFlags::Archive; -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationNormal); -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationAir); -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationIce); -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationOrganic); -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationWater); -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationLava); -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationPhazon); -DEFINE_CVAR_GLOBAL(MaxTranslationAccelerationShrubbery); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationNormal); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationAir); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationIce); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationOrganic); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationWater); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationLava); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationPhazon); -DEFINE_CVAR_GLOBAL(MaxRotationAccelerationShrubbery); -DEFINE_CVAR_GLOBAL(TranslationFrictionNormal); -DEFINE_CVAR_GLOBAL(TranslationFrictionAir); -DEFINE_CVAR_GLOBAL(TranslationFrictionIce); -DEFINE_CVAR_GLOBAL(TranslationFrictionOrganic); -DEFINE_CVAR_GLOBAL(TranslationFrictionWater); -DEFINE_CVAR_GLOBAL(TranslationFrictionLava); -DEFINE_CVAR_GLOBAL(TranslationFrictionPhazon); -DEFINE_CVAR_GLOBAL(TranslationFrictionShrubbery); -DEFINE_CVAR_GLOBAL(RotationFrictionNormal); -DEFINE_CVAR_GLOBAL(RotationFrictionAir); -DEFINE_CVAR_GLOBAL(RotationFrictionIce); -DEFINE_CVAR_GLOBAL(RotationFrictionOrganic); -DEFINE_CVAR_GLOBAL(RotationFrictionWater); -DEFINE_CVAR_GLOBAL(RotationFrictionLava); -DEFINE_CVAR_GLOBAL(RotationFrictionPhazon); -DEFINE_CVAR_GLOBAL(RotationFrictionShrubbery); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedNormal); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedAir); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedIce); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedOrganic); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedWater); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedLava); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedPhazon); -DEFINE_CVAR_GLOBAL(RotationMaxSpeedShrubbery); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedNormal); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedAir); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedIce); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedOrganic); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedWater); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedLava); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedPhazon); -DEFINE_CVAR_GLOBAL(TranslationMaxSpeedShrubbery); -DEFINE_CVAR_GLOBAL(NormalGravityAcceleration); -DEFINE_CVAR_GLOBAL(FluidGravityAcceleration); -DEFINE_CVAR_GLOBAL(VerticalJumpAcceleration); -DEFINE_CVAR_GLOBAL(HorizontalJumpAcceleration); -DEFINE_CVAR_GLOBAL(VerticalDoubleJumpAcceleration); -DEFINE_CVAR_GLOBAL(HorizontalDoubleJumpAcceleration); -DEFINE_CVAR_GLOBAL(WaterJumpFactor); -DEFINE_CVAR_GLOBAL(WaterBallJumpFactor); -DEFINE_CVAR_GLOBAL(LavaJumpFactor); -DEFINE_CVAR_GLOBAL(LavaBallJumpFactor); -DEFINE_CVAR_GLOBAL(PhazonJumpFactor); -DEFINE_CVAR_GLOBAL(PhazonBallJumpFactor); -DEFINE_CVAR_GLOBAL(AllowedJumpTime); -DEFINE_CVAR_GLOBAL(AllowedDoubleJumpTime); -DEFINE_CVAR_GLOBAL(MinDoubleJumpWindow); -DEFINE_CVAR_GLOBAL(MaxDoubleJumpWindow) -// DEFINE_CVAR_GLOBAL(); // x104_ -DEFINE_CVAR_GLOBAL(MinJumpTime); -DEFINE_CVAR_GLOBAL(MinDoubleJumpTime); -DEFINE_CVAR_GLOBAL(AllowedLedgeTime); -DEFINE_CVAR_GLOBAL(DoubleJumpImpulse); -DEFINE_CVAR_GLOBAL(BackwardsForceMultiplier); -DEFINE_CVAR_GLOBAL(BombJumpRadius); -DEFINE_CVAR_GLOBAL(BombJumpHeight); -DEFINE_CVAR_GLOBAL(EyeOffset); -DEFINE_CVAR_GLOBAL(TurnSpeedMultiplier); -DEFINE_CVAR_GLOBAL(FreeLookTurnSpeedMultiplier); -DEFINE_CVAR_GLOBAL(HorizontalFreeLookAngleVelocity); -DEFINE_CVAR_GLOBAL(VerticalFreeLookAngleVelocity); -DEFINE_CVAR_GLOBAL(FreeLookSpeed); -DEFINE_CVAR_GLOBAL(FreeLookSnapSpeed); -// DEFINE_CVAR_GLOBAL(); // x140_ -DEFINE_CVAR_GLOBAL(FreeLookCenteredThresholdAngle); -DEFINE_CVAR_GLOBAL(FreeLookCenteredTime); -DEFINE_CVAR_GLOBAL(FreeLookDampenFactor); -DEFINE_CVAR_GLOBAL(LeftDivisor); -DEFINE_CVAR_GLOBAL(RightDivisor); -DEFINE_CVAR_GLOBAL(OrbitMinDistanceClose); -DEFINE_CVAR_GLOBAL(OrbitMinDistanceFar); -DEFINE_CVAR_GLOBAL(OrbitMinDistanceDefault); -DEFINE_CVAR_GLOBAL(OrbitNormalDistanceClose); -DEFINE_CVAR_GLOBAL(OrbitNormalDistanceFar); -DEFINE_CVAR_GLOBAL(OrbitNormalDistanceDefault); -DEFINE_CVAR_GLOBAL(OrbitMaxDistanceClose); -DEFINE_CVAR_GLOBAL(OrbitMaxDistanceFar); -DEFINE_CVAR_GLOBAL(OrbitMaxDistanceDefault); -// DEFINE_CVAR_GLOBAL(); // x17c_ -DEFINE_CVAR_GLOBAL(OrbitmodeTimer); -DEFINE_CVAR_GLOBAL(OrbitCameraSpeed); -DEFINE_CVAR_GLOBAL(OrbitUpperAngle); -DEFINE_CVAR_GLOBAL(OrbitLowerAngle); -DEFINE_CVAR_GLOBAL(OrbitHorizontalAngle); -// DEFINE_CVAR_GLOBAL(); // x194_ -// DEFINE_CVAR_GLOBAL(); // x198_ -DEFINE_CVAR_GLOBAL(OrbitMaxTargetDistance); -DEFINE_CVAR_GLOBAL(OrbitMaxLockDistance); -DEFINE_CVAR_GLOBAL(OrbitDistanceThreshold); -DEFINE_CVAR_GLOBAL(OrbitScreenTargetingBoxHalfExtentX); -DEFINE_CVAR_GLOBAL(OrbitScreenScanBoxHalfExtentX); -DEFINE_CVAR_GLOBAL(OrbitScreenTargetingBoxHalfExtentY); -DEFINE_CVAR_GLOBAL(OrbitScreenScanBoxHalfExtentY); -DEFINE_CVAR_GLOBAL(OrbitScreenTargetingBoxCenterX); -DEFINE_CVAR_GLOBAL(OrbitScreenScanBoxCenterX); -DEFINE_CVAR_GLOBAL(OrbitScreenTargetingBoxCenterY); -DEFINE_CVAR_GLOBAL(OrbitScreenScanBoxCenterY); -DEFINE_CVAR_GLOBAL(OrbitZoneTargetingIdealX); -DEFINE_CVAR_GLOBAL(OrbitZoneScanIdealX); -DEFINE_CVAR_GLOBAL(OrbitZoneTargetingIdealY); -DEFINE_CVAR_GLOBAL(OrbitZoneScanIdealY); -DEFINE_CVAR_GLOBAL(OrbitNearX); -DEFINE_CVAR_GLOBAL(OrbitNearZ); -// DEFINE_CVAR_GLOBAL(); // x1e0_ -// DEFINE_CVAR_GLOBAL(); // x1e4_ -DEFINE_CVAR_GLOBAL(OrbitFixedOffsetZDiff); -DEFINE_CVAR_GLOBAL(OrbitZRange); -// DEFINE_CVAR_GLOBAL(); // x1f0_ -// DEFINE_CVAR_GLOBAL(); // x1f4_ -// DEFINE_CVAR_GLOBAL(); // x1f8_ -DEFINE_CVAR_GLOBAL(OrbitPreventionTime); -DEFINE_CVAR_GLOBAL(DashEnabled); -DEFINE_CVAR_GLOBAL(DashOnButtonRelease); -DEFINE_CVAR_GLOBAL(DashButtonHoldCancelTime); -DEFINE_CVAR_GLOBAL(DashStrafeInputThreshold); -DEFINE_CVAR_GLOBAL(SidewaysDoubleJumpImpulse); -DEFINE_CVAR_GLOBAL(SidewaysVerticalDoubleJumpAccel); -DEFINE_CVAR_GLOBAL(SidewaysHorizontalDoubleJumpAccel); -DEFINE_CVAR_GLOBAL(ScanningRange); -DEFINE_CVAR_GLOBAL(ScanRetention); -DEFINE_CVAR_GLOBAL(ScanFreezesGame); -DEFINE_CVAR_GLOBAL(OrbitWhileScanning); -DEFINE_CVAR_GLOBAL(ScanMaxTargetDistance); -DEFINE_CVAR_GLOBAL(ScanMaxLockDistance) -DEFINE_CVAR_GLOBAL(FreeLookTurnsPlayer); -// DEFINE_CVAR_GLOBAL(); // x228_25_ -// DEFINE_CVAR_GLOBAL(); // x228_26_ -DEFINE_CVAR_GLOBAL(MoveDuringFreelook); -DEFINE_CVAR_GLOBAL(HoldButtonsForFreeLook); -// DEFINE_CVAR_GLOBAL(); // x228_30_ -// DEFINE_CVAR_GLOBAL(); // x228_31_ -// DEFINE_CVAR_GLOBAL(); // x229_24_ -DEFINE_CVAR_GLOBAL(AimWhenOrbitingPoint); -DEFINE_CVAR_GLOBAL(StayInFreeLookWhileFiring); -// DEFINE_CVAR_GLOBAL(); // x229_27_ -// DEFINE_CVAR_GLOBAL(); // x229_28_ -DEFINE_CVAR_GLOBAL(OrbitFixedOffset); -DEFINE_CVAR_GLOBAL(GunButtonTogglesHolster); -DEFINE_CVAR_GLOBAL(GunNotFiringHolstersGun); -DEFINE_CVAR_GLOBAL(FallingDoubleJump); -DEFINE_CVAR_GLOBAL(ImpulseDoubleJump); -DEFINE_CVAR_GLOBAL(FiringCancelsCameraPitch); -DEFINE_CVAR_GLOBAL(AssistedAimingIgnoreHorizontal); -DEFINE_CVAR_GLOBAL(AssistedAimingIgnoreVertical); -// DEFINE_CVAR_GLOBAL(); // x22c -// DEFINE_CVAR_GLOBAL(); // x230_ -DEFINE_CVAR_GLOBAL(AimMaxDistance); -// DEFINE_CVAR_GLOBAL(); // x238_ -// DEFINE_CVAR_GLOBAL(); // x23c_ -// DEFINE_CVAR_GLOBAL(); // x240_ -// DEFINE_CVAR_GLOBAL(); // x244_ -// DEFINE_CVAR_GLOBAL(); // x248_ -DEFINE_CVAR_GLOBAL(AimThresholdDistance); -// DEFINE_CVAR_GLOBAL(); // x250_ -// DEFINE_CVAR_GLOBAL(); // x254_ -DEFINE_CVAR_GLOBAL(AimBoxWidth); -DEFINE_CVAR_GLOBAL(AimBoxHeight); -DEFINE_CVAR_GLOBAL(AimTargetTimer); -DEFINE_CVAR_GLOBAL(AimAssistHorizontalAngle); -DEFINE_CVAR_GLOBAL(AimAssistVerticalAngle); -DEFINE_CVAR_GLOBAL(PlayerHeight); -DEFINE_CVAR_GLOBAL(PlayerXYHalfExtent); -DEFINE_CVAR_GLOBAL(StepUpHeight); -DEFINE_CVAR_GLOBAL(StepDownHeight); -DEFINE_CVAR_GLOBAL(PlayerBallHalfExtent); -DEFINE_CVAR_GLOBAL(FirstPersonCameraSpeed); -// DEFINE_CVAR_GLOBAL(); // x284_ -DEFINE_CVAR_GLOBAL(JumpCameraPitchDownStart); -DEFINE_CVAR_GLOBAL(JumpCameraPitchDownFull); -DEFINE_CVAR_GLOBAL(JumpCameraPitchDownAngle); -DEFINE_CVAR_GLOBAL(FallCameraPitchDownStart); -DEFINE_CVAR_GLOBAL(FallCameraPitchDownFull); -DEFINE_CVAR_GLOBAL(FallCameraPitchDownAngle); -DEFINE_CVAR_GLOBAL(OrbitDistanceMax); -DEFINE_CVAR_GLOBAL(GrappleSwingLength); -DEFINE_CVAR_GLOBAL(GrappleSwingPeriod); -DEFINE_CVAR_GLOBAL(GrapplePullSpeedMin); -DEFINE_CVAR_GLOBAL(GrappleCameraSpeed); -DEFINE_CVAR_GLOBAL(MaxGrappleLockedTurnAlignDistance); -DEFINE_CVAR_GLOBAL(GrapplePullSpeedProportion); -DEFINE_CVAR_GLOBAL(GrapplePullSpeedMax); -DEFINE_CVAR_GLOBAL(GrappleLookCenterSpeed); -DEFINE_CVAR_GLOBAL(MaxGrappleTurnSpeed); -DEFINE_CVAR_GLOBAL(GrappleJumpForce); -DEFINE_CVAR_GLOBAL(GrappleReleaseTime); -DEFINE_CVAR_GLOBAL(GrappleJumpMode); -DEFINE_CVAR_GLOBAL(OrbitReleaseBreaksGrapple); -DEFINE_CVAR_GLOBAL(InvertGrappleTurn); -DEFINE_CVAR_GLOBAL(GrappleBeamSpeed); -DEFINE_CVAR_GLOBAL(GrappleBeamXWaveAmplitude); -DEFINE_CVAR_GLOBAL(GrappleBeamZWaveAmplitude); -DEFINE_CVAR_GLOBAL(GrappleBeamAnglePhaseDelta); -// DEFINE_CVAR_GLOBAL(); // x2e8_ -// DEFINE_CVAR_GLOBAL(); // x2ec_ -// DEFINE_CVAR_GLOBAL(); // x2f0_ -// DEFINE_CVAR_GLOBAL(); // x2f4_ -DEFINE_CVAR_GLOBAL(FrozenTimeout); -DEFINE_CVAR_GLOBAL(IceBreakJumpCount); -DEFINE_CVAR_GLOBAL(VariaDamageReduction); -DEFINE_CVAR_GLOBAL(GravityDamageReduction); -DEFINE_CVAR_GLOBAL(PhazonDamageReduction); -} // namespace -template <> -void CTweakPlayer::Enumerate(athena::io::IStreamReader& __dna_reader) { - /* x4_maxTranslationalAcceleration[0] */ - x4_maxTranslationalAcceleration[0] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[1] */ - x4_maxTranslationalAcceleration[1] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[2] */ - x4_maxTranslationalAcceleration[2] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[3] */ - x4_maxTranslationalAcceleration[3] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[4] */ - x4_maxTranslationalAcceleration[4] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[5] */ - x4_maxTranslationalAcceleration[5] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[6] */ - x4_maxTranslationalAcceleration[6] = __dna_reader.readFloatBig(); - /* x4_maxTranslationalAcceleration[7] */ - x4_maxTranslationalAcceleration[7] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[0] */ - x24_maxRotationalAcceleration[0] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[1] */ - x24_maxRotationalAcceleration[1] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[2] */ - x24_maxRotationalAcceleration[2] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[3] */ - x24_maxRotationalAcceleration[3] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[4] */ - x24_maxRotationalAcceleration[4] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[5] */ - x24_maxRotationalAcceleration[5] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[6] */ - x24_maxRotationalAcceleration[6] = __dna_reader.readFloatBig(); - /* x24_maxRotationalAcceleration[7] */ - x24_maxRotationalAcceleration[7] = __dna_reader.readFloatBig(); - /* x44_translationFriction[0] */ - x44_translationFriction[0] = __dna_reader.readFloatBig(); - /* x44_translationFriction[1] */ - x44_translationFriction[1] = __dna_reader.readFloatBig(); - /* x44_translationFriction[2] */ - x44_translationFriction[2] = __dna_reader.readFloatBig(); - /* x44_translationFriction[3] */ - x44_translationFriction[3] = __dna_reader.readFloatBig(); - /* x44_translationFriction[4] */ - x44_translationFriction[4] = __dna_reader.readFloatBig(); - /* x44_translationFriction[5] */ - x44_translationFriction[5] = __dna_reader.readFloatBig(); - /* x44_translationFriction[6] */ - x44_translationFriction[6] = __dna_reader.readFloatBig(); - /* x44_translationFriction[7] */ - x44_translationFriction[7] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[0] */ - x64_rotationFriction[0] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[1] */ - x64_rotationFriction[1] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[2] */ - x64_rotationFriction[2] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[3] */ - x64_rotationFriction[3] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[4] */ - x64_rotationFriction[4] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[5] */ - x64_rotationFriction[5] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[6] */ - x64_rotationFriction[6] = __dna_reader.readFloatBig(); - /* x64_rotationFriction[7] */ - x64_rotationFriction[7] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[0] */ - x84_rotationMaxSpeed[0] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[1] */ - x84_rotationMaxSpeed[1] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[2] */ - x84_rotationMaxSpeed[2] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[3] */ - x84_rotationMaxSpeed[3] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[4] */ - x84_rotationMaxSpeed[4] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[5] */ - x84_rotationMaxSpeed[5] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[6] */ - x84_rotationMaxSpeed[6] = __dna_reader.readFloatBig(); - /* x84_rotationMaxSpeed[7] */ - x84_rotationMaxSpeed[7] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[0] */ - xa4_translationMaxSpeed[0] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[1] */ - xa4_translationMaxSpeed[1] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[2] */ - xa4_translationMaxSpeed[2] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[3] */ - xa4_translationMaxSpeed[3] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[4] */ - xa4_translationMaxSpeed[4] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[5] */ - xa4_translationMaxSpeed[5] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[6] */ - xa4_translationMaxSpeed[6] = __dna_reader.readFloatBig(); - /* xa4_translationMaxSpeed[7] */ - xa4_translationMaxSpeed[7] = __dna_reader.readFloatBig(); - /* xc4_normalGravAccel */ - xc4_normalGravAccel = __dna_reader.readFloatBig(); - /* xc8_fluidGravAccel */ - xc8_fluidGravAccel = __dna_reader.readFloatBig(); - /* xcc_verticalJumpAccel */ - xcc_verticalJumpAccel = __dna_reader.readFloatBig(); - /* xd0_horizontalJumpAccel */ - xd0_horizontalJumpAccel = __dna_reader.readFloatBig(); - /* xd4_verticalDoubleJumpAccel */ - xd4_verticalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* xd8_horizontalDoubleJumpAccel */ - xd8_horizontalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* xdc_waterJumpFactor */ - xdc_waterJumpFactor = __dna_reader.readFloatBig(); - /* xe0_waterBallJumpFactor */ - xe0_waterBallJumpFactor = __dna_reader.readFloatBig(); - /* xe4_lavaJumpFactor */ - xe4_lavaJumpFactor = __dna_reader.readFloatBig(); - /* xe8_lavaBallJumpFactor */ - xe8_lavaBallJumpFactor = __dna_reader.readFloatBig(); - /* xec_phazonJumpFactor */ - xec_phazonJumpFactor = __dna_reader.readFloatBig(); - /* xf0_phazonBallJumpFactor */ - xf0_phazonBallJumpFactor = __dna_reader.readFloatBig(); - /* xf4_allowedJumpTime */ - xf4_allowedJumpTime = __dna_reader.readFloatBig(); - /* xf8_allowedDoubleJumpTime */ - xf8_allowedDoubleJumpTime = __dna_reader.readFloatBig(); - /* xfc_minDoubleJumpWindow */ - xfc_minDoubleJumpWindow = __dna_reader.readFloatBig(); - /* x100_maxDoubleJumpWindow */ - x100_maxDoubleJumpWindow = __dna_reader.readFloatBig(); - /* x104_ */ - x104_ = __dna_reader.readFloatBig(); - /* x108_minJumpTime */ - x108_minJumpTime = __dna_reader.readFloatBig(); - /* x10c_minDoubleJumpTime */ - x10c_minDoubleJumpTime = __dna_reader.readFloatBig(); - /* x110_allowedLedgeTime */ - x110_allowedLedgeTime = __dna_reader.readFloatBig(); - /* x114_doubleJumpImpulse */ - x114_doubleJumpImpulse = __dna_reader.readFloatBig(); - /* x118_backwardsForceMultiplier */ - x118_backwardsForceMultiplier = __dna_reader.readFloatBig(); - /* x11c_bombJumpRadius */ - x11c_bombJumpRadius = __dna_reader.readFloatBig(); - /* x120_bombJumpHeight */ - x120_bombJumpHeight = __dna_reader.readFloatBig(); - /* x124_eyeOffset */ - x124_eyeOffset = __dna_reader.readFloatBig(); - /* x128_turnSpeedMultiplier */ - x128_turnSpeedMultiplier = __dna_reader.readFloatBig(); - /* x12c_freeLookTurnSpeedMultiplier */ - x12c_freeLookTurnSpeedMultiplier = __dna_reader.readFloatBig(); - /* x130_horizontalFreeLookAngleVel */ - x130_horizontalFreeLookAngleVel = __dna_reader.readFloatBig(); - /* x134_verticalFreeLookAngleVel */ - x134_verticalFreeLookAngleVel = __dna_reader.readFloatBig(); - /* x138_freeLookSpeed */ - x138_freeLookSpeed = __dna_reader.readFloatBig(); - /* x13c_freeLookSnapSpeed */ - x13c_freeLookSnapSpeed = __dna_reader.readFloatBig(); - /* x140_ */ - x140_ = __dna_reader.readFloatBig(); - /* x144_freeLookCenteredThresholdAngle */ - x144_freeLookCenteredThresholdAngle = __dna_reader.readFloatBig(); - /* x148_freeLookCenteredTime */ - x148_freeLookCenteredTime = __dna_reader.readFloatBig(); - /* x14c_freeLookDampenFactor */ - x14c_freeLookDampenFactor = __dna_reader.readFloatBig(); - /* x150_leftDiv */ - x150_leftDiv = __dna_reader.readFloatBig(); - /* x154_rightDiv */ - x154_rightDiv = __dna_reader.readFloatBig(); - /* x228_24_freelookTurnsPlayer */ - x228_24_freelookTurnsPlayer = __dna_reader.readBool(); - /* x228_25_ */ - x228_25_ = __dna_reader.readBool(); - /* x228_26_ */ - x228_26_ = __dna_reader.readBool(); - /* x228_27_moveDuringFreeLook */ - x228_27_moveDuringFreeLook = __dna_reader.readBool(); - /* x228_28_holdButtonsForFreeLook */ - x228_28_holdButtonsForFreeLook = __dna_reader.readBool(); - /* x228_29_twoButtonsForFreeLook */ - x228_29_twoButtonsForFreeLook = __dna_reader.readBool(); - /* x228_30_ */ - x228_30_ = __dna_reader.readBool(); - /* x228_31_ */ - x228_31_ = __dna_reader.readBool(); - /* x229_24_ */ - x229_24_ = __dna_reader.readBool(); - /* x229_25_aimWhenOrbitingPoint */ - x229_25_aimWhenOrbitingPoint = __dna_reader.readBool(); - /* x229_26_stayInFreeLookWhileFiring */ - x229_26_stayInFreeLookWhileFiring = __dna_reader.readBool(); - /* x229_27_ */ - x229_27_ = __dna_reader.readBool(); - /* x229_28_ */ - x229_28_ = __dna_reader.readBool(); - /* x229_29_orbitFixedOffset */ - x229_29_orbitFixedOffset = __dna_reader.readBool(); - /* x229_30_gunButtonTogglesHolster */ - x229_30_gunButtonTogglesHolster = __dna_reader.readBool(); - /* x229_31_gunNotFiringHolstersGun */ - x229_31_gunNotFiringHolstersGun = __dna_reader.readBool(); - /* x22a_24_fallingDoubleJump */ - x22a_24_fallingDoubleJump = __dna_reader.readBool(); - /* x22a_25_impulseDoubleJump */ - x22a_25_impulseDoubleJump = __dna_reader.readBool(); - /* x22a_26_firingCancelsCameraPitch */ - x22a_26_firingCancelsCameraPitch = __dna_reader.readBool(); - /* x22a_27_assistedAimingIgnoreHorizontal */ - x22a_27_assistedAimingIgnoreHorizontal = __dna_reader.readBool(); - /* x22a_28_assistedAimingIgnoreVertical */ - x22a_28_assistedAimingIgnoreVertical = __dna_reader.readBool(); - /* x22c_ */ - x22c_ = __dna_reader.readFloatBig(); - /* x230_ */ - x230_ = __dna_reader.readFloatBig(); - /* x234_aimMaxDistance */ - x234_aimMaxDistance = __dna_reader.readFloatBig(); - /* x238_ */ - x238_ = __dna_reader.readFloatBig(); - /* x23c_ */ - x23c_ = __dna_reader.readFloatBig(); - /* x240_ */ - x240_ = __dna_reader.readFloatBig(); - /* x244_ */ - x244_ = __dna_reader.readFloatBig(); - /* x248_ */ - x248_ = __dna_reader.readFloatBig(); - /* x24c_aimThresholdDistance */ - x24c_aimThresholdDistance = __dna_reader.readFloatBig(); - /* x250_ */ - x250_ = __dna_reader.readFloatBig(); - /* x254_ */ - x254_ = __dna_reader.readFloatBig(); - /* x258_aimBoxWidth */ - x258_aimBoxWidth = __dna_reader.readFloatBig(); - /* x25c_aimBoxHeight */ - x25c_aimBoxHeight = __dna_reader.readFloatBig(); - /* x260_aimTargetTimer */ - x260_aimTargetTimer = __dna_reader.readFloatBig(); - /* x264_aimAssistHorizontalAngle */ - x264_aimAssistHorizontalAngle = __dna_reader.readFloatBig(); - /* x268_aimAssistVerticalAngle */ - x268_aimAssistVerticalAngle = __dna_reader.readFloatBig(); - /* x158_orbitMinDistance[0] */ - x158_orbitMinDistance[0] = __dna_reader.readFloatBig(); - /* x164_orbitNormalDistance[0] */ - x164_orbitNormalDistance[0] = __dna_reader.readFloatBig(); - /* x170_orbitMaxDistance[0] */ - x170_orbitMaxDistance[0] = __dna_reader.readFloatBig(); - /* x158_orbitMinDistance[1] */ - x158_orbitMinDistance[1] = __dna_reader.readFloatBig(); - /* x164_orbitNormalDistance[1] */ - x164_orbitNormalDistance[1] = __dna_reader.readFloatBig(); - /* x170_orbitMaxDistance[1] */ - x170_orbitMaxDistance[1] = __dna_reader.readFloatBig(); - /* x158_orbitMinDistance[2] */ - x158_orbitMinDistance[2] = __dna_reader.readFloatBig(); - /* x164_orbitNormalDistance[2] */ - x164_orbitNormalDistance[2] = __dna_reader.readFloatBig(); - /* x170_orbitMaxDistance[2] */ - x170_orbitMaxDistance[2] = __dna_reader.readFloatBig(); - /* x17c_ */ - x17c_ = __dna_reader.readFloatBig(); - /* x180_orbitModeTimer */ - x180_orbitModeTimer = __dna_reader.readFloatBig(); - /* x184_orbitCameraSpeed */ - x184_orbitCameraSpeed = __dna_reader.readFloatBig(); - /* x188_orbitUpperAngle */ - x188_orbitUpperAngle = __dna_reader.readFloatBig(); - /* x18c_orbitLowerAngle */ - x18c_orbitLowerAngle = __dna_reader.readFloatBig(); - /* x190_orbitHorizAngle */ - x190_orbitHorizAngle = __dna_reader.readFloatBig(); - /* x194_ */ - x194_ = __dna_reader.readFloatBig(); - /* x198_ */ - x198_ = __dna_reader.readFloatBig(); - /* x19c_orbitMaxTargetDistance */ - x19c_orbitMaxTargetDistance = __dna_reader.readFloatBig(); - /* x1a0_orbitMaxLockDistance */ - x1a0_orbitMaxLockDistance = __dna_reader.readFloatBig(); - /* x1a4_orbitDistanceThreshold */ - x1a4_orbitDistanceThreshold = __dna_reader.readFloatBig(); - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - x1a8_orbitScreenBoxHalfExtentX[0] = __dna_reader.readUint32Big(); - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - x1b0_orbitScreenBoxHalfExtentY[0] = __dna_reader.readUint32Big(); - /* x1b8_orbitScreenBoxCenterX[0] */ - x1b8_orbitScreenBoxCenterX[0] = __dna_reader.readUint32Big(); - /* x1c0_orbitScreenBoxCenterY[0] */ - x1c0_orbitScreenBoxCenterY[0] = __dna_reader.readUint32Big(); - /* x1c8_orbitZoneIdealX[0] */ - x1c8_orbitZoneIdealX[0] = __dna_reader.readUint32Big(); - /* x1d0_orbitZoneIdealY[0] */ - x1d0_orbitZoneIdealY[0] = __dna_reader.readUint32Big(); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - x1a8_orbitScreenBoxHalfExtentX[1] = __dna_reader.readUint32Big(); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - x1b0_orbitScreenBoxHalfExtentY[1] = __dna_reader.readUint32Big(); - /* x1b8_orbitScreenBoxCenterX[1] */ - x1b8_orbitScreenBoxCenterX[1] = __dna_reader.readUint32Big(); - /* x1c0_orbitScreenBoxCenterY[1] */ - x1c0_orbitScreenBoxCenterY[1] = __dna_reader.readUint32Big(); - /* x1c8_orbitZoneIdealX[1] */ - x1c8_orbitZoneIdealX[1] = __dna_reader.readUint32Big(); - /* x1d0_orbitZoneIdealY[1] */ - x1d0_orbitZoneIdealY[1] = __dna_reader.readUint32Big(); - /* x1d8_orbitNearX */ - x1d8_orbitNearX = __dna_reader.readFloatBig(); - /* x1dc_orbitNearZ */ - x1dc_orbitNearZ = __dna_reader.readFloatBig(); - /* x1e0_ */ - x1e0_ = __dna_reader.readFloatBig(); - /* x1e4_ */ - x1e4_ = __dna_reader.readFloatBig(); - /* x1e8_orbitFixedOffsetZDiff */ - x1e8_orbitFixedOffsetZDiff = __dna_reader.readFloatBig(); - /* x1ec_orbitZRange */ - x1ec_orbitZRange = __dna_reader.readFloatBig(); - /* x1f0_ */ - x1f0_ = __dna_reader.readFloatBig(); - /* x1f4_ */ - x1f4_ = __dna_reader.readFloatBig(); - /* x1f8_ */ - x1f8_ = __dna_reader.readFloatBig(); - /* x1fc_orbitPreventionTime */ - x1fc_orbitPreventionTime = __dna_reader.readFloatBig(); - /* x200_24_dashEnabled */ - x200_24_dashEnabled = __dna_reader.readBool(); - /* x200_25_dashOnButtonRelease */ - x200_25_dashOnButtonRelease = __dna_reader.readBool(); - /* x204_dashButtonHoldCancelTime */ - x204_dashButtonHoldCancelTime = __dna_reader.readFloatBig(); - /* x208_dashStrafeInputThreshold */ - x208_dashStrafeInputThreshold = __dna_reader.readFloatBig(); - /* x20c_sidewaysDoubleJumpImpulse */ - x20c_sidewaysDoubleJumpImpulse = __dna_reader.readFloatBig(); - /* x210_sidewaysVerticalDoubleJumpAccel */ - x210_sidewaysVerticalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - x214_sidewaysHorizontalDoubleJumpAccel = __dna_reader.readFloatBig(); - /* x218_scanningRange */ - x218_scanningRange = __dna_reader.readFloatBig(); - /* x21c_24_scanRetention */ - x21c_24_scanRetention = __dna_reader.readBool(); - /* x21c_25_scanFreezesGame */ - x21c_25_scanFreezesGame = __dna_reader.readBool(); - /* x21c_26_orbitWhileScanning */ - x21c_26_orbitWhileScanning = __dna_reader.readBool(); - /* x220_scanMaxTargetDistance */ - x220_scanMaxTargetDistance = __dna_reader.readFloatBig(); - /* x224_scanMaxLockDistance */ - x224_scanMaxLockDistance = __dna_reader.readFloatBig(); - /* x2a0_orbitDistanceMax */ - x2a0_orbitDistanceMax = __dna_reader.readFloatBig(); - /* x2a4_grappleSwingLength */ - x2a4_grappleSwingLength = __dna_reader.readFloatBig(); - /* x2a8_grappleSwingPeriod */ - x2a8_grappleSwingPeriod = __dna_reader.readFloatBig(); - /* x2ac_grapplePullSpeedMin */ - x2ac_grapplePullSpeedMin = __dna_reader.readFloatBig(); - /* x2b0_grappleCameraSpeed */ - x2b0_grappleCameraSpeed = __dna_reader.readFloatBig(); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - x2b4_maxGrappleLockedTurnAlignDistance = __dna_reader.readFloatBig(); - /* x2b8_grapplePullSpeedProportion */ - x2b8_grapplePullSpeedProportion = __dna_reader.readFloatBig(); - /* x2bc_grapplePullSpeedMax */ - x2bc_grapplePullSpeedMax = __dna_reader.readFloatBig(); - /* x2c0_grappleLookCenterSpeed */ - x2c0_grappleLookCenterSpeed = __dna_reader.readFloatBig(); - /* x2c4_maxGrappleTurnSpeed */ - x2c4_maxGrappleTurnSpeed = __dna_reader.readFloatBig(); - /* x2c8_grappleJumpForce */ - x2c8_grappleJumpForce = __dna_reader.readFloatBig(); - /* x2cc_grappleReleaseTime */ - x2cc_grappleReleaseTime = __dna_reader.readFloatBig(); - /* x2d0_grappleJumpMode */ - x2d0_grappleJumpMode = __dna_reader.readUint32Big(); - /* x2d4_orbitReleaseBreaksGrapple */ - x2d4_orbitReleaseBreaksGrapple = __dna_reader.readBool(); - /* x2d5_invertGrappleTurn */ - x2d5_invertGrappleTurn = __dna_reader.readBool(); - /* x2d8_grappleBeamSpeed */ - x2d8_grappleBeamSpeed = __dna_reader.readFloatBig(); - /* x2dc_grappleBeamXWaveAmplitude */ - x2dc_grappleBeamXWaveAmplitude = __dna_reader.readFloatBig(); - /* x2e0_grappleBeamZWaveAmplitude */ - x2e0_grappleBeamZWaveAmplitude = __dna_reader.readFloatBig(); - /* x2e4_grappleBeamAnglePhaseDelta */ - x2e4_grappleBeamAnglePhaseDelta = __dna_reader.readFloatBig(); - /* x26c_playerHeight */ - x26c_playerHeight = __dna_reader.readFloatBig(); - /* x270_playerXYHalfExtent */ - x270_playerXYHalfExtent = __dna_reader.readFloatBig(); - /* x274_stepUpHeight */ - x274_stepUpHeight = __dna_reader.readFloatBig(); - /* x278_stepDownHeight */ - x278_stepDownHeight = __dna_reader.readFloatBig(); - /* x27c_playerBallHalfExtent */ - x27c_playerBallHalfExtent = __dna_reader.readFloatBig(); - /* x280_ */ - x280_firstPersonCameraSpeed = __dna_reader.readFloatBig(); - /* x284_ */ - x284_ = __dna_reader.readFloatBig(); - /* x288_jumpCameraPitchDownStart */ - x288_jumpCameraPitchDownStart = __dna_reader.readFloatBig(); - /* x28c_jumpCameraPitchDownFull */ - x28c_jumpCameraPitchDownFull = __dna_reader.readFloatBig(); - /* x290_jumpCameraPitchDownAngle */ - x290_jumpCameraPitchDownAngle = __dna_reader.readFloatBig(); - /* x294_fallCameraPitchDownStart */ - x294_fallCameraPitchDownStart = __dna_reader.readFloatBig(); - /* x298_fallCameraPitchDownFull */ - x298_fallCameraPitchDownFull = __dna_reader.readFloatBig(); - /* x29c_fallCameraPitchDownAngle */ - x29c_fallCameraPitchDownAngle = __dna_reader.readFloatBig(); - /* x2e8_ */ - x2e8_ = __dna_reader.readFloatBig(); - /* x2ec_ */ - x2ec_ = __dna_reader.readFloatBig(); - /* x2f0_ */ - x2f0_ = __dna_reader.readFloatBig(); - /* x2f4_ */ - x2f4_ = __dna_reader.readBool(); - /* x2f8_frozenTimeout */ - x2f8_frozenTimeout = __dna_reader.readFloatBig(); - /* x2fc_iceBreakJumpCount */ - x2fc_iceBreakJumpCount = __dna_reader.readUint32Big(); - /* x300_variaDamageReduction */ - x300_variaDamageReduction = __dna_reader.readFloatBig(); - /* x304_gravityDamageReduction */ - x304_gravityDamageReduction = __dna_reader.readFloatBig(); - /* x308_phazonDamageReduction */ - x308_phazonDamageReduction = __dna_reader.readFloatBig(); -} - -template <> -void CTweakPlayer::Enumerate(athena::io::IStreamWriter& __dna_writer) { - /* x4_maxTranslationalAcceleration[0] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[0]); - /* x4_maxTranslationalAcceleration[1] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[1]); - /* x4_maxTranslationalAcceleration[2] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[2]); - /* x4_maxTranslationalAcceleration[3] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[3]); - /* x4_maxTranslationalAcceleration[4] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[4]); - /* x4_maxTranslationalAcceleration[5] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[5]); - /* x4_maxTranslationalAcceleration[6] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[6]); - /* x4_maxTranslationalAcceleration[7] */ - __dna_writer.writeFloatBig(x4_maxTranslationalAcceleration[7]); - /* x24_maxRotationalAcceleration[0] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[0]); - /* x24_maxRotationalAcceleration[1] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[1]); - /* x24_maxRotationalAcceleration[2] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[2]); - /* x24_maxRotationalAcceleration[3] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[3]); - /* x24_maxRotationalAcceleration[4] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[4]); - /* x24_maxRotationalAcceleration[5] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[5]); - /* x24_maxRotationalAcceleration[6] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[6]); - /* x24_maxRotationalAcceleration[7] */ - __dna_writer.writeFloatBig(x24_maxRotationalAcceleration[7]); - /* x44_translationFriction[0] */ - __dna_writer.writeFloatBig(x44_translationFriction[0]); - /* x44_translationFriction[1] */ - __dna_writer.writeFloatBig(x44_translationFriction[1]); - /* x44_translationFriction[2] */ - __dna_writer.writeFloatBig(x44_translationFriction[2]); - /* x44_translationFriction[3] */ - __dna_writer.writeFloatBig(x44_translationFriction[3]); - /* x44_translationFriction[4] */ - __dna_writer.writeFloatBig(x44_translationFriction[4]); - /* x44_translationFriction[5] */ - __dna_writer.writeFloatBig(x44_translationFriction[5]); - /* x44_translationFriction[6] */ - __dna_writer.writeFloatBig(x44_translationFriction[6]); - /* x44_translationFriction[7] */ - __dna_writer.writeFloatBig(x44_translationFriction[7]); - /* x64_rotationFriction[0] */ - __dna_writer.writeFloatBig(x64_rotationFriction[0]); - /* x64_rotationFriction[1] */ - __dna_writer.writeFloatBig(x64_rotationFriction[1]); - /* x64_rotationFriction[2] */ - __dna_writer.writeFloatBig(x64_rotationFriction[2]); - /* x64_rotationFriction[3] */ - __dna_writer.writeFloatBig(x64_rotationFriction[3]); - /* x64_rotationFriction[4] */ - __dna_writer.writeFloatBig(x64_rotationFriction[4]); - /* x64_rotationFriction[5] */ - __dna_writer.writeFloatBig(x64_rotationFriction[5]); - /* x64_rotationFriction[6] */ - __dna_writer.writeFloatBig(x64_rotationFriction[6]); - /* x64_rotationFriction[7] */ - __dna_writer.writeFloatBig(x64_rotationFriction[7]); - /* x84_rotationMaxSpeed[0] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[0]); - /* x84_rotationMaxSpeed[1] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[1]); - /* x84_rotationMaxSpeed[2] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[2]); - /* x84_rotationMaxSpeed[3] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[3]); - /* x84_rotationMaxSpeed[4] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[4]); - /* x84_rotationMaxSpeed[5] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[5]); - /* x84_rotationMaxSpeed[6] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[6]); - /* x84_rotationMaxSpeed[7] */ - __dna_writer.writeFloatBig(x84_rotationMaxSpeed[7]); - /* xa4_translationMaxSpeed[0] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[0]); - /* xa4_translationMaxSpeed[1] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[1]); - /* xa4_translationMaxSpeed[2] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[2]); - /* xa4_translationMaxSpeed[3] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[3]); - /* xa4_translationMaxSpeed[4] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[4]); - /* xa4_translationMaxSpeed[5] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[5]); - /* xa4_translationMaxSpeed[6] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[6]); - /* xa4_translationMaxSpeed[7] */ - __dna_writer.writeFloatBig(xa4_translationMaxSpeed[7]); - /* xc4_normalGravAccel */ - __dna_writer.writeFloatBig(xc4_normalGravAccel); - /* xc8_fluidGravAccel */ - __dna_writer.writeFloatBig(xc8_fluidGravAccel); - /* xcc_verticalJumpAccel */ - __dna_writer.writeFloatBig(xcc_verticalJumpAccel); - /* xd0_horizontalJumpAccel */ - __dna_writer.writeFloatBig(xd0_horizontalJumpAccel); - /* xd4_verticalDoubleJumpAccel */ - __dna_writer.writeFloatBig(xd4_verticalDoubleJumpAccel); - /* xd8_horizontalDoubleJumpAccel */ - __dna_writer.writeFloatBig(xd8_horizontalDoubleJumpAccel); - /* xdc_waterJumpFactor */ - __dna_writer.writeFloatBig(xdc_waterJumpFactor); - /* xe0_waterBallJumpFactor */ - __dna_writer.writeFloatBig(xe0_waterBallJumpFactor); - /* xe4_lavaJumpFactor */ - __dna_writer.writeFloatBig(xe4_lavaJumpFactor); - /* xe8_lavaBallJumpFactor */ - __dna_writer.writeFloatBig(xe8_lavaBallJumpFactor); - /* xec_phazonJumpFactor */ - __dna_writer.writeFloatBig(xec_phazonJumpFactor); - /* xf0_phazonBallJumpFactor */ - __dna_writer.writeFloatBig(xf0_phazonBallJumpFactor); - /* xf4_allowedJumpTime */ - __dna_writer.writeFloatBig(xf4_allowedJumpTime); - /* xf8_allowedDoubleJumpTime */ - __dna_writer.writeFloatBig(xf8_allowedDoubleJumpTime); - /* xfc_minDoubleJumpWindow */ - __dna_writer.writeFloatBig(xfc_minDoubleJumpWindow); - /* x100_maxDoubleJumpWindow */ - __dna_writer.writeFloatBig(x100_maxDoubleJumpWindow); - /* x104_ */ - __dna_writer.writeFloatBig(x104_); - /* x108_minJumpTime */ - __dna_writer.writeFloatBig(x108_minJumpTime); - /* x10c_minDoubleJumpTime */ - __dna_writer.writeFloatBig(x10c_minDoubleJumpTime); - /* x110_allowedLedgeTime */ - __dna_writer.writeFloatBig(x110_allowedLedgeTime); - /* x114_doubleJumpImpulse */ - __dna_writer.writeFloatBig(x114_doubleJumpImpulse); - /* x118_backwardsForceMultiplier */ - __dna_writer.writeFloatBig(x118_backwardsForceMultiplier); - /* x11c_bombJumpRadius */ - __dna_writer.writeFloatBig(x11c_bombJumpRadius); - /* x120_bombJumpHeight */ - __dna_writer.writeFloatBig(x120_bombJumpHeight); - /* x124_eyeOffset */ - __dna_writer.writeFloatBig(x124_eyeOffset); - /* x128_turnSpeedMultiplier */ - __dna_writer.writeFloatBig(x128_turnSpeedMultiplier); - /* x12c_freeLookTurnSpeedMultiplier */ - __dna_writer.writeFloatBig(x12c_freeLookTurnSpeedMultiplier); - /* x130_horizontalFreeLookAngleVel */ - __dna_writer.writeFloatBig(x130_horizontalFreeLookAngleVel); - /* x134_verticalFreeLookAngleVel */ - __dna_writer.writeFloatBig(x134_verticalFreeLookAngleVel); - /* x138_freeLookSpeed */ - __dna_writer.writeFloatBig(x138_freeLookSpeed); - /* x13c_freeLookSnapSpeed */ - __dna_writer.writeFloatBig(x13c_freeLookSnapSpeed); - /* x140_ */ - __dna_writer.writeFloatBig(x140_); - /* x144_freeLookCenteredThresholdAngle */ - __dna_writer.writeFloatBig(x144_freeLookCenteredThresholdAngle); - /* x148_freeLookCenteredTime */ - __dna_writer.writeFloatBig(x148_freeLookCenteredTime); - /* x14c_freeLookDampenFactor */ - __dna_writer.writeFloatBig(x14c_freeLookDampenFactor); - /* x150_leftDiv */ - __dna_writer.writeFloatBig(x150_leftDiv); - /* x154_rightDiv */ - __dna_writer.writeFloatBig(x154_rightDiv); - /* x228_24_freelookTurnsPlayer */ - __dna_writer.writeBool(x228_24_freelookTurnsPlayer); - /* x228_25_ */ - __dna_writer.writeBool(x228_25_); - /* x228_26_ */ - __dna_writer.writeBool(x228_26_); - /* x228_27_moveDuringFreeLook */ - __dna_writer.writeBool(x228_27_moveDuringFreeLook); - /* x228_28_holdButtonsForFreeLook */ - __dna_writer.writeBool(x228_28_holdButtonsForFreeLook); - /* x228_29_twoButtonsForFreeLook */ - __dna_writer.writeBool(x228_29_twoButtonsForFreeLook); - /* x228_30_ */ - __dna_writer.writeBool(x228_30_); - /* x228_31_ */ - __dna_writer.writeBool(x228_31_); - /* x229_24_ */ - __dna_writer.writeBool(x229_24_); - /* x229_25_aimWhenOrbitingPoint */ - __dna_writer.writeBool(x229_25_aimWhenOrbitingPoint); - /* x229_26_stayInFreeLookWhileFiring */ - __dna_writer.writeBool(x229_26_stayInFreeLookWhileFiring); - /* x229_27_ */ - __dna_writer.writeBool(x229_27_); - /* x229_28_ */ - __dna_writer.writeBool(x229_28_); - /* x229_29_orbitFixedOffset */ - __dna_writer.writeBool(x229_29_orbitFixedOffset); - /* x229_30_gunButtonTogglesHolster */ - __dna_writer.writeBool(x229_30_gunButtonTogglesHolster); - /* x229_31_gunNotFiringHolstersGun */ - __dna_writer.writeBool(x229_31_gunNotFiringHolstersGun); - /* x22a_24_fallingDoubleJump */ - __dna_writer.writeBool(x22a_24_fallingDoubleJump); - /* x22a_25_impulseDoubleJump */ - __dna_writer.writeBool(x22a_25_impulseDoubleJump); - /* x22a_26_firingCancelsCameraPitch */ - __dna_writer.writeBool(x22a_26_firingCancelsCameraPitch); - /* x22a_27_assistedAimingIgnoreHorizontal */ - __dna_writer.writeBool(x22a_27_assistedAimingIgnoreHorizontal); - /* x22a_28_assistedAimingIgnoreVertical */ - __dna_writer.writeBool(x22a_28_assistedAimingIgnoreVertical); - /* x22c_ */ - __dna_writer.writeFloatBig(x22c_); - /* x230_ */ - __dna_writer.writeFloatBig(x230_); - /* x234_aimMaxDistance */ - __dna_writer.writeFloatBig(x234_aimMaxDistance); - /* x238_ */ - __dna_writer.writeFloatBig(x238_); - /* x23c_ */ - __dna_writer.writeFloatBig(x23c_); - /* x240_ */ - __dna_writer.writeFloatBig(x240_); - /* x244_ */ - __dna_writer.writeFloatBig(x244_); - /* x248_ */ - __dna_writer.writeFloatBig(x248_); - /* x24c_aimThresholdDistance */ - __dna_writer.writeFloatBig(x24c_aimThresholdDistance); - /* x250_ */ - __dna_writer.writeFloatBig(x250_); - /* x254_ */ - __dna_writer.writeFloatBig(x254_); - /* x258_aimBoxWidth */ - __dna_writer.writeFloatBig(x258_aimBoxWidth); - /* x25c_aimBoxHeight */ - __dna_writer.writeFloatBig(x25c_aimBoxHeight); - /* x260_aimTargetTimer */ - __dna_writer.writeFloatBig(x260_aimTargetTimer); - /* x264_aimAssistHorizontalAngle */ - __dna_writer.writeFloatBig(x264_aimAssistHorizontalAngle); - /* x268_aimAssistVerticalAngle */ - __dna_writer.writeFloatBig(x268_aimAssistVerticalAngle); - /* x158_orbitMinDistance[0] */ - __dna_writer.writeFloatBig(x158_orbitMinDistance[0]); - /* x164_orbitNormalDistance[0] */ - __dna_writer.writeFloatBig(x164_orbitNormalDistance[0]); - /* x170_orbitMaxDistance[0] */ - __dna_writer.writeFloatBig(x170_orbitMaxDistance[0]); - /* x158_orbitMinDistance[1] */ - __dna_writer.writeFloatBig(x158_orbitMinDistance[1]); - /* x164_orbitNormalDistance[1] */ - __dna_writer.writeFloatBig(x164_orbitNormalDistance[1]); - /* x170_orbitMaxDistance[1] */ - __dna_writer.writeFloatBig(x170_orbitMaxDistance[1]); - /* x158_orbitMinDistance[2] */ - __dna_writer.writeFloatBig(x158_orbitMinDistance[2]); - /* x164_orbitNormalDistance[2] */ - __dna_writer.writeFloatBig(x164_orbitNormalDistance[2]); - /* x170_orbitMaxDistance[2] */ - __dna_writer.writeFloatBig(x170_orbitMaxDistance[2]); - /* x17c_ */ - __dna_writer.writeFloatBig(x17c_); - /* x180_orbitModeTimer */ - __dna_writer.writeFloatBig(x180_orbitModeTimer); - /* x184_orbitCameraSpeed */ - __dna_writer.writeFloatBig(x184_orbitCameraSpeed); - /* x188_orbitUpperAngle */ - __dna_writer.writeFloatBig(x188_orbitUpperAngle); - /* x18c_orbitLowerAngle */ - __dna_writer.writeFloatBig(x18c_orbitLowerAngle); - /* x190_orbitHorizAngle */ - __dna_writer.writeFloatBig(x190_orbitHorizAngle); - /* x194_ */ - __dna_writer.writeFloatBig(x194_); - /* x198_ */ - __dna_writer.writeFloatBig(x198_); - /* x19c_orbitMaxTargetDistance */ - __dna_writer.writeFloatBig(x19c_orbitMaxTargetDistance); - /* x1a0_orbitMaxLockDistance */ - __dna_writer.writeFloatBig(x1a0_orbitMaxLockDistance); - /* x1a4_orbitDistanceThreshold */ - __dna_writer.writeFloatBig(x1a4_orbitDistanceThreshold); - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - __dna_writer.writeUint32Big(x1a8_orbitScreenBoxHalfExtentX[0]); - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - __dna_writer.writeUint32Big(x1b0_orbitScreenBoxHalfExtentY[0]); - /* x1b8_orbitScreenBoxCenterX[0] */ - __dna_writer.writeUint32Big(x1b8_orbitScreenBoxCenterX[0]); - /* x1c0_orbitScreenBoxCenterY[0] */ - __dna_writer.writeUint32Big(x1c0_orbitScreenBoxCenterY[0]); - /* x1c8_orbitZoneIdealX[0] */ - __dna_writer.writeUint32Big(x1c8_orbitZoneIdealX[0]); - /* x1d0_orbitZoneIdealY[0] */ - __dna_writer.writeUint32Big(x1d0_orbitZoneIdealY[0]); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - __dna_writer.writeUint32Big(x1a8_orbitScreenBoxHalfExtentX[1]); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - __dna_writer.writeUint32Big(x1b0_orbitScreenBoxHalfExtentY[1]); - /* x1b8_orbitScreenBoxCenterX[1] */ - __dna_writer.writeUint32Big(x1b8_orbitScreenBoxCenterX[1]); - /* x1c0_orbitScreenBoxCenterY[1] */ - __dna_writer.writeUint32Big(x1c0_orbitScreenBoxCenterY[1]); - /* x1c8_orbitZoneIdealX[1] */ - __dna_writer.writeUint32Big(x1c8_orbitZoneIdealX[1]); - /* x1d0_orbitZoneIdealY[1] */ - __dna_writer.writeUint32Big(x1d0_orbitZoneIdealY[1]); - /* x1d8_orbitNearX */ - __dna_writer.writeFloatBig(x1d8_orbitNearX); - /* x1dc_orbitNearZ */ - __dna_writer.writeFloatBig(x1dc_orbitNearZ); - /* x1e0_ */ - __dna_writer.writeFloatBig(x1e0_); - /* x1e4_ */ - __dna_writer.writeFloatBig(x1e4_); - /* x1e8_orbitFixedOffsetZDiff */ - __dna_writer.writeFloatBig(x1e8_orbitFixedOffsetZDiff); - /* x1ec_orbitZRange */ - __dna_writer.writeFloatBig(x1ec_orbitZRange); - /* x1f0_ */ - __dna_writer.writeFloatBig(x1f0_); - /* x1f4_ */ - __dna_writer.writeFloatBig(x1f4_); - /* x1f8_ */ - __dna_writer.writeFloatBig(x1f8_); - /* x1fc_orbitPreventionTime */ - __dna_writer.writeFloatBig(x1fc_orbitPreventionTime); - /* x200_24_dashEnabled */ - __dna_writer.writeBool(x200_24_dashEnabled); - /* x200_25_dashOnButtonRelease */ - __dna_writer.writeBool(x200_25_dashOnButtonRelease); - /* x204_dashButtonHoldCancelTime */ - __dna_writer.writeFloatBig(x204_dashButtonHoldCancelTime); - /* x208_dashStrafeInputThreshold */ - __dna_writer.writeFloatBig(x208_dashStrafeInputThreshold); - /* x20c_sidewaysDoubleJumpImpulse */ - __dna_writer.writeFloatBig(x20c_sidewaysDoubleJumpImpulse); - /* x210_sidewaysVerticalDoubleJumpAccel */ - __dna_writer.writeFloatBig(x210_sidewaysVerticalDoubleJumpAccel); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - __dna_writer.writeFloatBig(x214_sidewaysHorizontalDoubleJumpAccel); - /* x218_scanningRange */ - __dna_writer.writeFloatBig(x218_scanningRange); - /* x21c_24_scanRetention */ - __dna_writer.writeBool(x21c_24_scanRetention); - /* x21c_25_scanFreezesGame */ - __dna_writer.writeBool(x21c_25_scanFreezesGame); - /* x21c_26_orbitWhileScanning */ - __dna_writer.writeBool(x21c_26_orbitWhileScanning); - /* x220_scanMaxTargetDistance */ - __dna_writer.writeFloatBig(x220_scanMaxTargetDistance); - /* x224_scanMaxLockDistance */ - __dna_writer.writeFloatBig(x224_scanMaxLockDistance); - /* x2a0_orbitDistanceMax */ - __dna_writer.writeFloatBig(x2a0_orbitDistanceMax); - /* x2a4_grappleSwingLength */ - __dna_writer.writeFloatBig(x2a4_grappleSwingLength); - /* x2a8_grappleSwingPeriod */ - __dna_writer.writeFloatBig(x2a8_grappleSwingPeriod); - /* x2ac_grapplePullSpeedMin */ - __dna_writer.writeFloatBig(x2ac_grapplePullSpeedMin); - /* x2b0_grappleCameraSpeed */ - __dna_writer.writeFloatBig(x2b0_grappleCameraSpeed); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - __dna_writer.writeFloatBig(x2b4_maxGrappleLockedTurnAlignDistance); - /* x2b8_grapplePullSpeedProportion */ - __dna_writer.writeFloatBig(x2b8_grapplePullSpeedProportion); - /* x2bc_grapplePullSpeedMax */ - __dna_writer.writeFloatBig(x2bc_grapplePullSpeedMax); - /* x2c0_grappleLookCenterSpeed */ - __dna_writer.writeFloatBig(x2c0_grappleLookCenterSpeed); - /* x2c4_maxGrappleTurnSpeed */ - __dna_writer.writeFloatBig(x2c4_maxGrappleTurnSpeed); - /* x2c8_grappleJumpForce */ - __dna_writer.writeFloatBig(x2c8_grappleJumpForce); - /* x2cc_grappleReleaseTime */ - __dna_writer.writeFloatBig(x2cc_grappleReleaseTime); - /* x2d0_grappleJumpMode */ - __dna_writer.writeUint32Big(x2d0_grappleJumpMode); - /* x2d4_orbitReleaseBreaksGrapple */ - __dna_writer.writeBool(x2d4_orbitReleaseBreaksGrapple); - /* x2d5_invertGrappleTurn */ - __dna_writer.writeBool(x2d5_invertGrappleTurn); - /* x2d8_grappleBeamSpeed */ - __dna_writer.writeFloatBig(x2d8_grappleBeamSpeed); - /* x2dc_grappleBeamXWaveAmplitude */ - __dna_writer.writeFloatBig(x2dc_grappleBeamXWaveAmplitude); - /* x2e0_grappleBeamZWaveAmplitude */ - __dna_writer.writeFloatBig(x2e0_grappleBeamZWaveAmplitude); - /* x2e4_grappleBeamAnglePhaseDelta */ - __dna_writer.writeFloatBig(x2e4_grappleBeamAnglePhaseDelta); - /* x26c_playerHeight */ - __dna_writer.writeFloatBig(x26c_playerHeight); - /* x270_playerXYHalfExtent */ - __dna_writer.writeFloatBig(x270_playerXYHalfExtent); - /* x274_stepUpHeight */ - __dna_writer.writeFloatBig(x274_stepUpHeight); - /* x278_stepDownHeight */ - __dna_writer.writeFloatBig(x278_stepDownHeight); - /* x27c_playerBallHalfExtent */ - __dna_writer.writeFloatBig(x27c_playerBallHalfExtent); - /* x280_ */ - __dna_writer.writeFloatBig(x280_firstPersonCameraSpeed); - /* x284_ */ - __dna_writer.writeFloatBig(x284_); - /* x288_jumpCameraPitchDownStart */ - __dna_writer.writeFloatBig(x288_jumpCameraPitchDownStart); - /* x28c_jumpCameraPitchDownFull */ - __dna_writer.writeFloatBig(x28c_jumpCameraPitchDownFull); - /* x290_jumpCameraPitchDownAngle */ - __dna_writer.writeFloatBig(x290_jumpCameraPitchDownAngle); - /* x294_fallCameraPitchDownStart */ - __dna_writer.writeFloatBig(x294_fallCameraPitchDownStart); - /* x298_fallCameraPitchDownFull */ - __dna_writer.writeFloatBig(x298_fallCameraPitchDownFull); - /* x29c_fallCameraPitchDownAngle */ - __dna_writer.writeFloatBig(x29c_fallCameraPitchDownAngle); - /* x2e8_ */ - __dna_writer.writeFloatBig(x2e8_); - /* x2ec_ */ - __dna_writer.writeFloatBig(x2ec_); - /* x2f0_ */ - __dna_writer.writeFloatBig(x2f0_); - /* x2f4_ */ - __dna_writer.writeBool(x2f4_); - /* x2f8_frozenTimeout */ - __dna_writer.writeFloatBig(x2f8_frozenTimeout); - /* x2fc_iceBreakJumpCount */ - __dna_writer.writeUint32Big(x2fc_iceBreakJumpCount); - /* x300_variaDamageReduction */ - __dna_writer.writeFloatBig(x300_variaDamageReduction); - /* x304_gravityDamageReduction */ - __dna_writer.writeFloatBig(x304_gravityDamageReduction); - /* x308_phazonDamageReduction */ - __dna_writer.writeFloatBig(x308_phazonDamageReduction); -} - -template <> -void CTweakPlayer::Enumerate(athena::io::YAMLDocReader& __dna_docin) { - /* x4_maxTranslationalAcceleration */ - size_t __x4_Count; - if (auto v = __dna_docin.enterSubVector("x4_maxTranslationalAcceleration", __x4_Count)) { - /* x4_maxTranslationalAcceleration[0] */ - x4_maxTranslationalAcceleration[0] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[1] */ - x4_maxTranslationalAcceleration[1] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[2] */ - x4_maxTranslationalAcceleration[2] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[3] */ - x4_maxTranslationalAcceleration[3] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[4] */ - x4_maxTranslationalAcceleration[4] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[5] */ - x4_maxTranslationalAcceleration[5] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[6] */ - x4_maxTranslationalAcceleration[6] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - /* x4_maxTranslationalAcceleration[7] */ - x4_maxTranslationalAcceleration[7] = __dna_docin.readFloat("x4_maxTranslationalAcceleration"); - } - /* x24_maxRotationalAcceleration */ - size_t __x24_Count; - if (auto v = __dna_docin.enterSubVector("x24_maxRotationalAcceleration", __x24_Count)) { - /* x24_maxRotationalAcceleration[0] */ - x24_maxRotationalAcceleration[0] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[1] */ - x24_maxRotationalAcceleration[1] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[2] */ - x24_maxRotationalAcceleration[2] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[3] */ - x24_maxRotationalAcceleration[3] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[4] */ - x24_maxRotationalAcceleration[4] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[5] */ - x24_maxRotationalAcceleration[5] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[6] */ - x24_maxRotationalAcceleration[6] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - /* x24_maxRotationalAcceleration[7] */ - x24_maxRotationalAcceleration[7] = __dna_docin.readFloat("x24_maxRotationalAcceleration"); - } - /* x44_translationFriction */ - size_t __x44_Count; - if (auto v = __dna_docin.enterSubVector("x44_translationFriction", __x44_Count)) { - /* x44_translationFriction[0] */ - x44_translationFriction[0] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[1] */ - x44_translationFriction[1] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[2] */ - x44_translationFriction[2] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[3] */ - x44_translationFriction[3] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[4] */ - x44_translationFriction[4] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[5] */ - x44_translationFriction[5] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[6] */ - x44_translationFriction[6] = __dna_docin.readFloat("x44_translationFriction"); - /* x44_translationFriction[7] */ - x44_translationFriction[7] = __dna_docin.readFloat("x44_translationFriction"); - } - /* x64_rotationFriction */ - size_t __x64_Count; - if (auto v = __dna_docin.enterSubVector("x64_rotationFriction", __x64_Count)) { - /* x64_rotationFriction[0] */ - x64_rotationFriction[0] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[1] */ - x64_rotationFriction[1] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[2] */ - x64_rotationFriction[2] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[3] */ - x64_rotationFriction[3] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[4] */ - x64_rotationFriction[4] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[5] */ - x64_rotationFriction[5] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[6] */ - x64_rotationFriction[6] = __dna_docin.readFloat("x64_rotationFriction"); - /* x64_rotationFriction[7] */ - x64_rotationFriction[7] = __dna_docin.readFloat("x64_rotationFriction"); - } - /* x84_rotationMaxSpeed */ - size_t __x84_Count; - if (auto v = __dna_docin.enterSubVector("x84_rotationMaxSpeed", __x84_Count)) { - /* x84_rotationMaxSpeed[0] */ - x84_rotationMaxSpeed[0] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[1] */ - x84_rotationMaxSpeed[1] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[2] */ - x84_rotationMaxSpeed[2] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[3] */ - x84_rotationMaxSpeed[3] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[4] */ - x84_rotationMaxSpeed[4] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[5] */ - x84_rotationMaxSpeed[5] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[6] */ - x84_rotationMaxSpeed[6] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - /* x84_rotationMaxSpeed[7] */ - x84_rotationMaxSpeed[7] = __dna_docin.readFloat("x84_rotationMaxSpeed"); - } - /* xa4_translationMaxSpeed */ - size_t __xa4_Count; - if (auto v = __dna_docin.enterSubVector("xa4_translationMaxSpeed", __xa4_Count)) { - /* xa4_translationMaxSpeed[0] */ - xa4_translationMaxSpeed[0] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[1] */ - xa4_translationMaxSpeed[1] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[2] */ - xa4_translationMaxSpeed[2] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[3] */ - xa4_translationMaxSpeed[3] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[4] */ - xa4_translationMaxSpeed[4] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[5] */ - xa4_translationMaxSpeed[5] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[6] */ - xa4_translationMaxSpeed[6] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - /* xa4_translationMaxSpeed[7] */ - xa4_translationMaxSpeed[7] = __dna_docin.readFloat("xa4_translationMaxSpeed"); - } - /* xc4_normalGravAccel */ - xc4_normalGravAccel = __dna_docin.readFloat("xc4_normalGravAccel"); - /* xc8_fluidGravAccel */ - xc8_fluidGravAccel = __dna_docin.readFloat("xc8_fluidGravAccel"); - /* xcc_verticalJumpAccel */ - xcc_verticalJumpAccel = __dna_docin.readFloat("xcc_verticalJumpAccel"); - /* xd0_horizontalJumpAccel */ - xd0_horizontalJumpAccel = __dna_docin.readFloat("xd0_horizontalJumpAccel"); - /* xd4_verticalDoubleJumpAccel */ - xd4_verticalDoubleJumpAccel = __dna_docin.readFloat("xd4_verticalDoubleJumpAccel"); - /* xd8_horizontalDoubleJumpAccel */ - xd8_horizontalDoubleJumpAccel = __dna_docin.readFloat("xd8_horizontalDoubleJumpAccel"); - /* xdc_waterJumpFactor */ - xdc_waterJumpFactor = __dna_docin.readFloat("xdc_waterJumpFactor"); - /* xe0_waterBallJumpFactor */ - xe0_waterBallJumpFactor = __dna_docin.readFloat("xe0_waterBallJumpFactor"); - /* xe4_lavaJumpFactor */ - xe4_lavaJumpFactor = __dna_docin.readFloat("xe4_lavaJumpFactor"); - /* xe8_lavaBallJumpFactor */ - xe8_lavaBallJumpFactor = __dna_docin.readFloat("xe8_lavaBallJumpFactor"); - /* xec_phazonJumpFactor */ - xec_phazonJumpFactor = __dna_docin.readFloat("xec_phazonJumpFactor"); - /* xf0_phazonBallJumpFactor */ - xf0_phazonBallJumpFactor = __dna_docin.readFloat("xf0_phazonBallJumpFactor"); - /* xf4_allowedJumpTime */ - xf4_allowedJumpTime = __dna_docin.readFloat("xf4_allowedJumpTime"); - /* xf8_allowedDoubleJumpTime */ - xf8_allowedDoubleJumpTime = __dna_docin.readFloat("xf8_allowedDoubleJumpTime"); - /* xfc_minDoubleJumpWindow */ - xfc_minDoubleJumpWindow = __dna_docin.readFloat("xfc_minDoubleJumpWindow"); - /* x100_maxDoubleJumpWindow */ - x100_maxDoubleJumpWindow = __dna_docin.readFloat("x100_maxDoubleJumpWindow"); - /* x104_ */ - x104_ = __dna_docin.readFloat("x104_"); - /* x108_minJumpTime */ - x108_minJumpTime = __dna_docin.readFloat("x108_minJumpTime"); - /* x10c_minDoubleJumpTime */ - x10c_minDoubleJumpTime = __dna_docin.readFloat("x10c_minDoubleJumpTime"); - /* x110_allowedLedgeTime */ - x110_allowedLedgeTime = __dna_docin.readFloat("x110_allowedLedgeTime"); - /* x114_doubleJumpImpulse */ - x114_doubleJumpImpulse = __dna_docin.readFloat("x114_doubleJumpImpulse"); - /* x118_backwardsForceMultiplier */ - x118_backwardsForceMultiplier = __dna_docin.readFloat("x118_backwardsForceMultiplier"); - /* x11c_bombJumpRadius */ - x11c_bombJumpRadius = __dna_docin.readFloat("x11c_bombJumpRadius"); - /* x120_bombJumpHeight */ - x120_bombJumpHeight = __dna_docin.readFloat("x120_bombJumpHeight"); - /* x124_eyeOffset */ - x124_eyeOffset = __dna_docin.readFloat("x124_eyeOffset"); - /* x128_turnSpeedMultiplier */ - x128_turnSpeedMultiplier = __dna_docin.readFloat("x128_turnSpeedMultiplier"); - /* x12c_freeLookTurnSpeedMultiplier */ - x12c_freeLookTurnSpeedMultiplier = __dna_docin.readFloat("x12c_freeLookTurnSpeedMultiplier"); - /* x130_horizontalFreeLookAngleVel */ - x130_horizontalFreeLookAngleVel = __dna_docin.readFloat("x130_horizontalFreeLookAngleVel"); - /* x134_verticalFreeLookAngleVel */ - x134_verticalFreeLookAngleVel = __dna_docin.readFloat("x134_verticalFreeLookAngleVel"); - /* x138_freeLookSpeed */ - x138_freeLookSpeed = __dna_docin.readFloat("x138_freeLookSpeed"); - /* x13c_freeLookSnapSpeed */ - x13c_freeLookSnapSpeed = __dna_docin.readFloat("x13c_freeLookSnapSpeed"); - /* x140_ */ - x140_ = __dna_docin.readFloat("x140_"); - /* x144_freeLookCenteredThresholdAngle */ - x144_freeLookCenteredThresholdAngle = __dna_docin.readFloat("x144_freeLookCenteredThresholdAngle"); - /* x148_freeLookCenteredTime */ - x148_freeLookCenteredTime = __dna_docin.readFloat("x148_freeLookCenteredTime"); - /* x14c_freeLookDampenFactor */ - x14c_freeLookDampenFactor = __dna_docin.readFloat("x14c_freeLookDampenFactor"); - /* x150_leftDiv */ - x150_leftDiv = __dna_docin.readFloat("x150_leftDiv"); - /* x154_rightDiv */ - x154_rightDiv = __dna_docin.readFloat("x154_rightDiv"); - /* x228_24_freelookTurnsPlayer */ - x228_24_freelookTurnsPlayer = __dna_docin.readBool("x228_24_freelookTurnsPlayer"); - /* x228_25_ */ - x228_25_ = __dna_docin.readBool("x228_25_"); - /* x228_26_ */ - x228_26_ = __dna_docin.readBool("x228_26_"); - /* x228_27_moveDuringFreeLook */ - x228_27_moveDuringFreeLook = __dna_docin.readBool("x228_27_moveDuringFreeLook"); - /* x228_28_holdButtonsForFreeLook */ - x228_28_holdButtonsForFreeLook = __dna_docin.readBool("x228_28_holdButtonsForFreeLook"); - /* x228_29_twoButtonsForFreeLook */ - x228_29_twoButtonsForFreeLook = __dna_docin.readBool("x228_29_twoButtonsForFreeLook"); - /* x228_30_ */ - x228_30_ = __dna_docin.readBool("x228_30_"); - /* x228_31_ */ - x228_31_ = __dna_docin.readBool("x228_31_"); - /* x229_24_ */ - x229_24_ = __dna_docin.readBool("x229_24_"); - /* x229_25_aimWhenOrbitingPoint */ - x229_25_aimWhenOrbitingPoint = __dna_docin.readBool("x229_25_aimWhenOrbitingPoint"); - /* x229_26_stayInFreeLookWhileFiring */ - x229_26_stayInFreeLookWhileFiring = __dna_docin.readBool("x229_26_stayInFreeLookWhileFiring"); - /* x229_27_ */ - x229_27_ = __dna_docin.readBool("x229_27_"); - /* x229_28_ */ - x229_28_ = __dna_docin.readBool("x229_28_"); - /* x229_29_orbitFixedOffset */ - x229_29_orbitFixedOffset = __dna_docin.readBool("x229_29_orbitFixedOffset"); - /* x229_30_gunButtonTogglesHolster */ - x229_30_gunButtonTogglesHolster = __dna_docin.readBool("x229_30_gunButtonTogglesHolster"); - /* x229_31_gunNotFiringHolstersGun */ - x229_31_gunNotFiringHolstersGun = __dna_docin.readBool("x229_31_gunNotFiringHolstersGun"); - /* x22a_24_fallingDoubleJump */ - x22a_24_fallingDoubleJump = __dna_docin.readBool("x22a_24_fallingDoubleJump"); - /* x22a_25_impulseDoubleJump */ - x22a_25_impulseDoubleJump = __dna_docin.readBool("x22a_25_impulseDoubleJump"); - /* x22a_26_firingCancelsCameraPitch */ - x22a_26_firingCancelsCameraPitch = __dna_docin.readBool("x22a_26_firingCancelsCameraPitch"); - /* x22a_27_assistedAimingIgnoreHorizontal */ - x22a_27_assistedAimingIgnoreHorizontal = __dna_docin.readBool("x22a_27_assistedAimingIgnoreHorizontal"); - /* x22a_28_assistedAimingIgnoreVertical */ - x22a_28_assistedAimingIgnoreVertical = __dna_docin.readBool("x22a_28_assistedAimingIgnoreVertical"); - /* x22c_ */ - x22c_ = __dna_docin.readFloat("x22c_"); - /* x230_ */ - x230_ = __dna_docin.readFloat("x230_"); - /* x234_aimMaxDistance */ - x234_aimMaxDistance = __dna_docin.readFloat("x234_aimMaxDistance"); - /* x238_ */ - x238_ = __dna_docin.readFloat("x238_"); - /* x23c_ */ - x23c_ = __dna_docin.readFloat("x23c_"); - /* x240_ */ - x240_ = __dna_docin.readFloat("x240_"); - /* x244_ */ - x244_ = __dna_docin.readFloat("x244_"); - /* x248_ */ - x248_ = __dna_docin.readFloat("x248_"); - /* x24c_aimThresholdDistance */ - x24c_aimThresholdDistance = __dna_docin.readFloat("x24c_aimThresholdDistance"); - /* x250_ */ - x250_ = __dna_docin.readFloat("x250_"); - /* x254_ */ - x254_ = __dna_docin.readFloat("x254_"); - /* x258_aimBoxWidth */ - x258_aimBoxWidth = __dna_docin.readFloat("x258_aimBoxWidth"); - /* x25c_aimBoxHeight */ - x25c_aimBoxHeight = __dna_docin.readFloat("x25c_aimBoxHeight"); - /* x260_aimTargetTimer */ - x260_aimTargetTimer = __dna_docin.readFloat("x260_aimTargetTimer"); - /* x264_aimAssistHorizontalAngle */ - x264_aimAssistHorizontalAngle = __dna_docin.readFloat("x264_aimAssistHorizontalAngle"); - /* x268_aimAssistVerticalAngle */ - x268_aimAssistVerticalAngle = __dna_docin.readFloat("x268_aimAssistVerticalAngle"); - /* x158_orbitMinDistance */ - size_t __x158_Count; - if (auto v = __dna_docin.enterSubVector("x158_orbitMinDistance", __x158_Count)) { - /* x158_orbitMinDistance[0] */ - x158_orbitMinDistance[0] = __dna_docin.readFloat("x158_orbitMinDistance"); - /* x158_orbitMinDistance[1] */ - x158_orbitMinDistance[1] = __dna_docin.readFloat("x158_orbitMinDistance"); - /* x158_orbitMinDistance[2] */ - x158_orbitMinDistance[2] = __dna_docin.readFloat("x158_orbitMinDistance"); - } - /* x164_orbitNormalDistance */ - size_t __x164_Count; - if (auto v = __dna_docin.enterSubVector("x164_orbitNormalDistance", __x164_Count)) { - /* x164_orbitNormalDistance[0] */ - x164_orbitNormalDistance[0] = __dna_docin.readFloat("x164_orbitNormalDistance"); - /* x164_orbitNormalDistance[1] */ - x164_orbitNormalDistance[1] = __dna_docin.readFloat("x164_orbitNormalDistance"); - /* x164_orbitNormalDistance[2] */ - x164_orbitNormalDistance[2] = __dna_docin.readFloat("x164_orbitNormalDistance"); - } - /* x170_orbitMaxDistance */ - size_t __x170_Count; - if (auto v = __dna_docin.enterSubVector("x170_orbitMaxDistance", __x170_Count)) { - /* x170_orbitMaxDistance[0] */ - x170_orbitMaxDistance[0] = __dna_docin.readFloat("x170_orbitMaxDistance"); - /* x170_orbitMaxDistance[1] */ - x170_orbitMaxDistance[1] = __dna_docin.readFloat("x170_orbitMaxDistance"); - /* x170_orbitMaxDistance[2] */ - x170_orbitMaxDistance[2] = __dna_docin.readFloat("x170_orbitMaxDistance"); - } - /* x17c_ */ - x17c_ = __dna_docin.readFloat("x17c_"); - /* x180_orbitModeTimer */ - x180_orbitModeTimer = __dna_docin.readFloat("x180_orbitModeTimer"); - /* x184_orbitCameraSpeed */ - x184_orbitCameraSpeed = __dna_docin.readFloat("x184_orbitCameraSpeed"); - /* x188_orbitUpperAngle */ - x188_orbitUpperAngle = __dna_docin.readFloat("x188_orbitUpperAngle"); - /* x18c_orbitLowerAngle */ - x18c_orbitLowerAngle = __dna_docin.readFloat("x18c_orbitLowerAngle"); - /* x190_orbitHorizAngle */ - x190_orbitHorizAngle = __dna_docin.readFloat("x190_orbitHorizAngle"); - /* x194_ */ - x194_ = __dna_docin.readFloat("x194_"); - /* x198_ */ - x198_ = __dna_docin.readFloat("x198_"); - /* x19c_orbitMaxTargetDistance */ - x19c_orbitMaxTargetDistance = __dna_docin.readFloat("x19c_orbitMaxTargetDistance"); - /* x1a0_orbitMaxLockDistance */ - x1a0_orbitMaxLockDistance = __dna_docin.readFloat("x1a0_orbitMaxLockDistance"); - /* x1a4_orbitDistanceThreshold */ - x1a4_orbitDistanceThreshold = __dna_docin.readFloat("x1a4_orbitDistanceThreshold"); - /* x1a8_orbitScreenBoxHalfExtentX */ - size_t __x1a8_Count; - if (auto v = __dna_docin.enterSubVector("x1a8_orbitScreenBoxHalfExtentX", __x1a8_Count)) { - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - x1a8_orbitScreenBoxHalfExtentX[0] = __dna_docin.readUint32("x1a8_orbitScreenBoxHalfExtentX"); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - x1a8_orbitScreenBoxHalfExtentX[1] = __dna_docin.readUint32("x1a8_orbitScreenBoxHalfExtentX"); - } - /* x1b0_orbitScreenBoxHalfExtentY */ - size_t __x1b0_Count; - if (auto v = __dna_docin.enterSubVector("x1b0_orbitScreenBoxHalfExtentY", __x1b0_Count)) { - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - x1b0_orbitScreenBoxHalfExtentY[0] = __dna_docin.readUint32("x1b0_orbitScreenBoxHalfExtentY"); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - x1b0_orbitScreenBoxHalfExtentY[1] = __dna_docin.readUint32("x1b0_orbitScreenBoxHalfExtentY"); - } - /* x1b8_orbitScreenBoxCenterX */ - size_t __x1b8_Count; - if (auto v = __dna_docin.enterSubVector("x1b8_orbitScreenBoxCenterX", __x1b8_Count)) { - /* x1b8_orbitScreenBoxCenterX[0] */ - x1b8_orbitScreenBoxCenterX[0] = __dna_docin.readUint32("x1b8_orbitScreenBoxCenterX"); - /* x1b8_orbitScreenBoxCenterX[1] */ - x1b8_orbitScreenBoxCenterX[1] = __dna_docin.readUint32("x1b8_orbitScreenBoxCenterX"); - } - /* x1c0_orbitScreenBoxCenterY */ - size_t __x1c0_Count; - if (auto v = __dna_docin.enterSubVector("x1c0_orbitScreenBoxCenterY", __x1c0_Count)) { - /* x1c0_orbitScreenBoxCenterY[0] */ - x1c0_orbitScreenBoxCenterY[0] = __dna_docin.readUint32("x1c0_orbitScreenBoxCenterY"); - /* x1c0_orbitScreenBoxCenterY[1] */ - x1c0_orbitScreenBoxCenterY[1] = __dna_docin.readUint32("x1c0_orbitScreenBoxCenterY"); - } - /* x1c8_orbitZoneIdealX */ - size_t __x1c8_Count; - if (auto v = __dna_docin.enterSubVector("x1c8_orbitZoneIdealX", __x1c8_Count)) { - /* x1c8_orbitZoneIdealX[0] */ - x1c8_orbitZoneIdealX[0] = __dna_docin.readUint32("x1c8_orbitZoneIdealX"); - /* x1c8_orbitZoneIdealX[1] */ - x1c8_orbitZoneIdealX[1] = __dna_docin.readUint32("x1c8_orbitZoneIdealX"); - } - /* x1d0_orbitZoneIdealY */ - size_t __x1d0_Count; - if (auto v = __dna_docin.enterSubVector("x1d0_orbitZoneIdealY", __x1d0_Count)) { - /* x1d0_orbitZoneIdealY[0] */ - x1d0_orbitZoneIdealY[0] = __dna_docin.readUint32("x1d0_orbitZoneIdealY"); - /* x1d0_orbitZoneIdealY[1] */ - x1d0_orbitZoneIdealY[1] = __dna_docin.readUint32("x1d0_orbitZoneIdealY"); - } - /* x1d8_orbitNearX */ - x1d8_orbitNearX = __dna_docin.readFloat("x1d8_orbitNearX"); - /* x1dc_orbitNearZ */ - x1dc_orbitNearZ = __dna_docin.readFloat("x1dc_orbitNearZ"); - /* x1e0_ */ - x1e0_ = __dna_docin.readFloat("x1e0_"); - /* x1e4_ */ - x1e4_ = __dna_docin.readFloat("x1e4_"); - /* x1e8_orbitFixedOffsetZDiff */ - x1e8_orbitFixedOffsetZDiff = __dna_docin.readFloat("x1e8_orbitFixedOffsetZDiff"); - /* x1ec_orbitZRange */ - x1ec_orbitZRange = __dna_docin.readFloat("x1ec_orbitZRange"); - /* x1f0_ */ - x1f0_ = __dna_docin.readFloat("x1f0_"); - /* x1f4_ */ - x1f4_ = __dna_docin.readFloat("x1f4_"); - /* x1f8_ */ - x1f8_ = __dna_docin.readFloat("x1f8_"); - /* x1fc_orbitPreventionTime */ - x1fc_orbitPreventionTime = __dna_docin.readFloat("x1fc_orbitPreventionTime"); - /* x200_24_dashEnabled */ - x200_24_dashEnabled = __dna_docin.readBool("x200_24_dashEnabled"); - /* x200_25_dashOnButtonRelease */ - x200_25_dashOnButtonRelease = __dna_docin.readBool("x200_25_dashOnButtonRelease"); - /* x204_dashButtonHoldCancelTime */ - x204_dashButtonHoldCancelTime = __dna_docin.readFloat("x204_dashButtonHoldCancelTime"); - /* x208_dashStrafeInputThreshold */ - x208_dashStrafeInputThreshold = __dna_docin.readFloat("x208_dashStrafeInputThreshold"); - /* x20c_sidewaysDoubleJumpImpulse */ - x20c_sidewaysDoubleJumpImpulse = __dna_docin.readFloat("x20c_sidewaysDoubleJumpImpulse"); - /* x210_sidewaysVerticalDoubleJumpAccel */ - x210_sidewaysVerticalDoubleJumpAccel = __dna_docin.readFloat("x210_sidewaysVerticalDoubleJumpAccel"); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - x214_sidewaysHorizontalDoubleJumpAccel = __dna_docin.readFloat("x214_sidewaysHorizontalDoubleJumpAccel"); - /* x218_scanningRange */ - x218_scanningRange = __dna_docin.readFloat("x218_scanningRange"); - /* x21c_24_scanRetention */ - x21c_24_scanRetention = __dna_docin.readBool("x21c_24_scanRetention"); - /* x21c_25_scanFreezesGame */ - x21c_25_scanFreezesGame = __dna_docin.readBool("x21c_25_scanFreezesGame"); - /* x21c_26_orbitWhileScanning */ - x21c_26_orbitWhileScanning = __dna_docin.readBool("x21c_26_orbitWhileScanning"); - /* x220_scanMaxTargetDistance */ - x220_scanMaxTargetDistance = __dna_docin.readFloat("x220_scanMaxTargetDistance"); - /* x224_scanMaxLockDistance */ - x224_scanMaxLockDistance = __dna_docin.readFloat("x224_scanMaxLockDistance"); - /* x2a0_orbitDistanceMax */ - x2a0_orbitDistanceMax = __dna_docin.readFloat("x2a0_orbitDistanceMax"); - /* x2a4_grappleSwingLength */ - x2a4_grappleSwingLength = __dna_docin.readFloat("x2a4_grappleSwingLength"); - /* x2a8_grappleSwingPeriod */ - x2a8_grappleSwingPeriod = __dna_docin.readFloat("x2a8_grappleSwingPeriod"); - /* x2ac_grapplePullSpeedMin */ - x2ac_grapplePullSpeedMin = __dna_docin.readFloat("x2ac_grapplePullSpeedMin"); - /* x2b0_grappleCameraSpeed */ - x2b0_grappleCameraSpeed = __dna_docin.readFloat("x2b0_grappleCameraSpeed"); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - x2b4_maxGrappleLockedTurnAlignDistance = __dna_docin.readFloat("x2b4_maxGrappleLockedTurnAlignDistance"); - /* x2b8_grapplePullSpeedProportion */ - x2b8_grapplePullSpeedProportion = __dna_docin.readFloat("x2b8_grapplePullSpeedProportion"); - /* x2bc_grapplePullSpeedMax */ - x2bc_grapplePullSpeedMax = __dna_docin.readFloat("x2bc_grapplePullSpeedMax"); - /* x2c0_grappleLookCenterSpeed */ - x2c0_grappleLookCenterSpeed = __dna_docin.readFloat("x2c0_grappleLookCenterSpeed"); - /* x2c4_maxGrappleTurnSpeed */ - x2c4_maxGrappleTurnSpeed = __dna_docin.readFloat("x2c4_maxGrappleTurnSpeed"); - /* x2c8_grappleJumpForce */ - x2c8_grappleJumpForce = __dna_docin.readFloat("x2c8_grappleJumpForce"); - /* x2cc_grappleReleaseTime */ - x2cc_grappleReleaseTime = __dna_docin.readFloat("x2cc_grappleReleaseTime"); - /* x2d0_grappleJumpMode */ - x2d0_grappleJumpMode = __dna_docin.readUint32("x2d0_grappleJumpMode"); - /* x2d4_orbitReleaseBreaksGrapple */ - x2d4_orbitReleaseBreaksGrapple = __dna_docin.readBool("x2d4_orbitReleaseBreaksGrapple"); - /* x2d5_invertGrappleTurn */ - x2d5_invertGrappleTurn = __dna_docin.readBool("x2d5_invertGrappleTurn"); - /* x2d8_grappleBeamSpeed */ - x2d8_grappleBeamSpeed = __dna_docin.readFloat("x2d8_grappleBeamSpeed"); - /* x2dc_grappleBeamXWaveAmplitude */ - x2dc_grappleBeamXWaveAmplitude = __dna_docin.readFloat("x2dc_grappleBeamXWaveAmplitude"); - /* x2e0_grappleBeamZWaveAmplitude */ - x2e0_grappleBeamZWaveAmplitude = __dna_docin.readFloat("x2e0_grappleBeamZWaveAmplitude"); - /* x2e4_grappleBeamAnglePhaseDelta */ - x2e4_grappleBeamAnglePhaseDelta = __dna_docin.readFloat("x2e4_grappleBeamAnglePhaseDelta"); - /* x26c_playerHeight */ - x26c_playerHeight = __dna_docin.readFloat("x26c_playerHeight"); - /* x270_playerXYHalfExtent */ - x270_playerXYHalfExtent = __dna_docin.readFloat("x270_playerXYHalfExtent"); - /* x274_stepUpHeight */ - x274_stepUpHeight = __dna_docin.readFloat("x274_stepUpHeight"); - /* x278_stepDownHeight */ - x278_stepDownHeight = __dna_docin.readFloat("x278_stepDownHeight"); - /* x27c_playerBallHalfExtent */ - x27c_playerBallHalfExtent = __dna_docin.readFloat("x27c_playerBallHalfExtent"); - /* x280_ */ - x280_firstPersonCameraSpeed = __dna_docin.readFloat("x280_"); - /* x284_ */ - x284_ = __dna_docin.readFloat("x284_"); - /* x288_jumpCameraPitchDownStart */ - x288_jumpCameraPitchDownStart = __dna_docin.readFloat("x288_jumpCameraPitchDownStart"); - /* x28c_jumpCameraPitchDownFull */ - x28c_jumpCameraPitchDownFull = __dna_docin.readFloat("x28c_jumpCameraPitchDownFull"); - /* x290_jumpCameraPitchDownAngle */ - x290_jumpCameraPitchDownAngle = __dna_docin.readFloat("x290_jumpCameraPitchDownAngle"); - /* x294_fallCameraPitchDownStart */ - x294_fallCameraPitchDownStart = __dna_docin.readFloat("x294_fallCameraPitchDownStart"); - /* x298_fallCameraPitchDownFull */ - x298_fallCameraPitchDownFull = __dna_docin.readFloat("x298_fallCameraPitchDownFull"); - /* x29c_fallCameraPitchDownAngle */ - x29c_fallCameraPitchDownAngle = __dna_docin.readFloat("x29c_fallCameraPitchDownAngle"); - /* x2e8_ */ - x2e8_ = __dna_docin.readFloat("x2e8_"); - /* x2ec_ */ - x2ec_ = __dna_docin.readFloat("x2ec_"); - /* x2f0_ */ - x2f0_ = __dna_docin.readFloat("x2f0_"); - /* x2f4_ */ - x2f4_ = __dna_docin.readBool("x2f4_"); - /* x2f8_frozenTimeout */ - x2f8_frozenTimeout = __dna_docin.readFloat("x2f8_frozenTimeout"); - /* x2fc_iceBreakJumpCount */ - x2fc_iceBreakJumpCount = __dna_docin.readUint32("x2fc_iceBreakJumpCount"); - /* x300_variaDamageReduction */ - x300_variaDamageReduction = __dna_docin.readFloat("x300_variaDamageReduction"); - /* x304_gravityDamageReduction */ - x304_gravityDamageReduction = __dna_docin.readFloat("x304_gravityDamageReduction"); - /* x308_phazonDamageReduction */ - x308_phazonDamageReduction = __dna_docin.readFloat("x308_phazonDamageReduction"); -} - -template <> -void CTweakPlayer::Enumerate(athena::io::YAMLDocWriter& __dna_docout) { - /* x4_maxTranslationalAcceleration */ - if (auto v = __dna_docout.enterSubVector("x4_maxTranslationalAcceleration")) { - /* x4_maxTranslationalAcceleration[0] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[0]); - /* x4_maxTranslationalAcceleration[1] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[1]); - /* x4_maxTranslationalAcceleration[2] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[2]); - /* x4_maxTranslationalAcceleration[3] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[3]); - /* x4_maxTranslationalAcceleration[4] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[4]); - /* x4_maxTranslationalAcceleration[5] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[5]); - /* x4_maxTranslationalAcceleration[6] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[6]); - /* x4_maxTranslationalAcceleration[7] */ - __dna_docout.writeFloat("x4_maxTranslationalAcceleration", x4_maxTranslationalAcceleration[7]); - } - /* x24_maxRotationalAcceleration */ - if (auto v = __dna_docout.enterSubVector("x24_maxRotationalAcceleration")) { - /* x24_maxRotationalAcceleration[0] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[0]); - /* x24_maxRotationalAcceleration[1] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[1]); - /* x24_maxRotationalAcceleration[2] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[2]); - /* x24_maxRotationalAcceleration[3] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[3]); - /* x24_maxRotationalAcceleration[4] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[4]); - /* x24_maxRotationalAcceleration[5] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[5]); - /* x24_maxRotationalAcceleration[6] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[6]); - /* x24_maxRotationalAcceleration[7] */ - __dna_docout.writeFloat("x24_maxRotationalAcceleration", x24_maxRotationalAcceleration[7]); - } - /* x44_translationFriction */ - if (auto v = __dna_docout.enterSubVector("x44_translationFriction")) { - /* x44_translationFriction[0] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[0]); - /* x44_translationFriction[1] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[1]); - /* x44_translationFriction[2] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[2]); - /* x44_translationFriction[3] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[3]); - /* x44_translationFriction[4] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[4]); - /* x44_translationFriction[5] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[5]); - /* x44_translationFriction[6] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[6]); - /* x44_translationFriction[7] */ - __dna_docout.writeFloat("x44_translationFriction", x44_translationFriction[7]); - } - /* x64_rotationFriction */ - if (auto v = __dna_docout.enterSubVector("x64_rotationFriction")) { - /* x64_rotationFriction[0] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[0]); - /* x64_rotationFriction[1] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[1]); - /* x64_rotationFriction[2] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[2]); - /* x64_rotationFriction[3] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[3]); - /* x64_rotationFriction[4] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[4]); - /* x64_rotationFriction[5] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[5]); - /* x64_rotationFriction[6] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[6]); - /* x64_rotationFriction[7] */ - __dna_docout.writeFloat("x64_rotationFriction", x64_rotationFriction[7]); - } - /* x84_rotationMaxSpeed */ - if (auto v = __dna_docout.enterSubVector("x84_rotationMaxSpeed")) { - /* x84_rotationMaxSpeed[0] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[0]); - /* x84_rotationMaxSpeed[1] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[1]); - /* x84_rotationMaxSpeed[2] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[2]); - /* x84_rotationMaxSpeed[3] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[3]); - /* x84_rotationMaxSpeed[4] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[4]); - /* x84_rotationMaxSpeed[5] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[5]); - /* x84_rotationMaxSpeed[6] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[6]); - /* x84_rotationMaxSpeed[7] */ - __dna_docout.writeFloat("x84_rotationMaxSpeed", x84_rotationMaxSpeed[7]); - } - /* xa4_translationMaxSpeed */ - if (auto v = __dna_docout.enterSubVector("xa4_translationMaxSpeed")) { - /* xa4_translationMaxSpeed[0] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[0]); - /* xa4_translationMaxSpeed[1] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[1]); - /* xa4_translationMaxSpeed[2] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[2]); - /* xa4_translationMaxSpeed[3] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[3]); - /* xa4_translationMaxSpeed[4] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[4]); - /* xa4_translationMaxSpeed[5] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[5]); - /* xa4_translationMaxSpeed[6] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[6]); - /* xa4_translationMaxSpeed[7] */ - __dna_docout.writeFloat("xa4_translationMaxSpeed", xa4_translationMaxSpeed[7]); - } - /* xc4_normalGravAccel */ - __dna_docout.writeFloat("xc4_normalGravAccel", xc4_normalGravAccel); - /* xc8_fluidGravAccel */ - __dna_docout.writeFloat("xc8_fluidGravAccel", xc8_fluidGravAccel); - /* xcc_verticalJumpAccel */ - __dna_docout.writeFloat("xcc_verticalJumpAccel", xcc_verticalJumpAccel); - /* xd0_horizontalJumpAccel */ - __dna_docout.writeFloat("xd0_horizontalJumpAccel", xd0_horizontalJumpAccel); - /* xd4_verticalDoubleJumpAccel */ - __dna_docout.writeFloat("xd4_verticalDoubleJumpAccel", xd4_verticalDoubleJumpAccel); - /* xd8_horizontalDoubleJumpAccel */ - __dna_docout.writeFloat("xd8_horizontalDoubleJumpAccel", xd8_horizontalDoubleJumpAccel); - /* xdc_waterJumpFactor */ - __dna_docout.writeFloat("xdc_waterJumpFactor", xdc_waterJumpFactor); - /* xe0_waterBallJumpFactor */ - __dna_docout.writeFloat("xe0_waterBallJumpFactor", xe0_waterBallJumpFactor); - /* xe4_lavaJumpFactor */ - __dna_docout.writeFloat("xe4_lavaJumpFactor", xe4_lavaJumpFactor); - /* xe8_lavaBallJumpFactor */ - __dna_docout.writeFloat("xe8_lavaBallJumpFactor", xe8_lavaBallJumpFactor); - /* xec_phazonJumpFactor */ - __dna_docout.writeFloat("xec_phazonJumpFactor", xec_phazonJumpFactor); - /* xf0_phazonBallJumpFactor */ - __dna_docout.writeFloat("xf0_phazonBallJumpFactor", xf0_phazonBallJumpFactor); - /* xf4_allowedJumpTime */ - __dna_docout.writeFloat("xf4_allowedJumpTime", xf4_allowedJumpTime); - /* xf8_allowedDoubleJumpTime */ - __dna_docout.writeFloat("xf8_allowedDoubleJumpTime", xf8_allowedDoubleJumpTime); - /* xfc_minDoubleJumpWindow */ - __dna_docout.writeFloat("xfc_minDoubleJumpWindow", xfc_minDoubleJumpWindow); - /* x100_maxDoubleJumpWindow */ - __dna_docout.writeFloat("x100_maxDoubleJumpWindow", x100_maxDoubleJumpWindow); - /* x104_ */ - __dna_docout.writeFloat("x104_", x104_); - /* x108_minJumpTime */ - __dna_docout.writeFloat("x108_minJumpTime", x108_minJumpTime); - /* x10c_minDoubleJumpTime */ - __dna_docout.writeFloat("x10c_minDoubleJumpTime", x10c_minDoubleJumpTime); - /* x110_allowedLedgeTime */ - __dna_docout.writeFloat("x110_allowedLedgeTime", x110_allowedLedgeTime); - /* x114_doubleJumpImpulse */ - __dna_docout.writeFloat("x114_doubleJumpImpulse", x114_doubleJumpImpulse); - /* x118_backwardsForceMultiplier */ - __dna_docout.writeFloat("x118_backwardsForceMultiplier", x118_backwardsForceMultiplier); - /* x11c_bombJumpRadius */ - __dna_docout.writeFloat("x11c_bombJumpRadius", x11c_bombJumpRadius); - /* x120_bombJumpHeight */ - __dna_docout.writeFloat("x120_bombJumpHeight", x120_bombJumpHeight); - /* x124_eyeOffset */ - __dna_docout.writeFloat("x124_eyeOffset", x124_eyeOffset); - /* x128_turnSpeedMultiplier */ - __dna_docout.writeFloat("x128_turnSpeedMultiplier", x128_turnSpeedMultiplier); - /* x12c_freeLookTurnSpeedMultiplier */ - __dna_docout.writeFloat("x12c_freeLookTurnSpeedMultiplier", x12c_freeLookTurnSpeedMultiplier); - /* x130_horizontalFreeLookAngleVel */ - __dna_docout.writeFloat("x130_horizontalFreeLookAngleVel", x130_horizontalFreeLookAngleVel); - /* x134_verticalFreeLookAngleVel */ - __dna_docout.writeFloat("x134_verticalFreeLookAngleVel", x134_verticalFreeLookAngleVel); - /* x138_freeLookSpeed */ - __dna_docout.writeFloat("x138_freeLookSpeed", x138_freeLookSpeed); - /* x13c_freeLookSnapSpeed */ - __dna_docout.writeFloat("x13c_freeLookSnapSpeed", x13c_freeLookSnapSpeed); - /* x140_ */ - __dna_docout.writeFloat("x140_", x140_); - /* x144_freeLookCenteredThresholdAngle */ - __dna_docout.writeFloat("x144_freeLookCenteredThresholdAngle", x144_freeLookCenteredThresholdAngle); - /* x148_freeLookCenteredTime */ - __dna_docout.writeFloat("x148_freeLookCenteredTime", x148_freeLookCenteredTime); - /* x14c_freeLookDampenFactor */ - __dna_docout.writeFloat("x14c_freeLookDampenFactor", x14c_freeLookDampenFactor); - /* x150_leftDiv */ - __dna_docout.writeFloat("x150_leftDiv", x150_leftDiv); - /* x154_rightDiv */ - __dna_docout.writeFloat("x154_rightDiv", x154_rightDiv); - /* x228_24_freelookTurnsPlayer */ - __dna_docout.writeBool("x228_24_freelookTurnsPlayer", x228_24_freelookTurnsPlayer); - /* x228_25_ */ - __dna_docout.writeBool("x228_25_", x228_25_); - /* x228_26_ */ - __dna_docout.writeBool("x228_26_", x228_26_); - /* x228_27_moveDuringFreeLook */ - __dna_docout.writeBool("x228_27_moveDuringFreeLook", x228_27_moveDuringFreeLook); - /* x228_28_holdButtonsForFreeLook */ - __dna_docout.writeBool("x228_28_holdButtonsForFreeLook", x228_28_holdButtonsForFreeLook); - /* x228_29_twoButtonsForFreeLook */ - __dna_docout.writeBool("x228_29_twoButtonsForFreeLook", x228_29_twoButtonsForFreeLook); - /* x228_30_ */ - __dna_docout.writeBool("x228_30_", x228_30_); - /* x228_31_ */ - __dna_docout.writeBool("x228_31_", x228_31_); - /* x229_24_ */ - __dna_docout.writeBool("x229_24_", x229_24_); - /* x229_25_aimWhenOrbitingPoint */ - __dna_docout.writeBool("x229_25_aimWhenOrbitingPoint", x229_25_aimWhenOrbitingPoint); - /* x229_26_stayInFreeLookWhileFiring */ - __dna_docout.writeBool("x229_26_stayInFreeLookWhileFiring", x229_26_stayInFreeLookWhileFiring); - /* x229_27_ */ - __dna_docout.writeBool("x229_27_", x229_27_); - /* x229_28_ */ - __dna_docout.writeBool("x229_28_", x229_28_); - /* x229_29_orbitFixedOffset */ - __dna_docout.writeBool("x229_29_orbitFixedOffset", x229_29_orbitFixedOffset); - /* x229_30_gunButtonTogglesHolster */ - __dna_docout.writeBool("x229_30_gunButtonTogglesHolster", x229_30_gunButtonTogglesHolster); - /* x229_31_gunNotFiringHolstersGun */ - __dna_docout.writeBool("x229_31_gunNotFiringHolstersGun", x229_31_gunNotFiringHolstersGun); - /* x22a_24_fallingDoubleJump */ - __dna_docout.writeBool("x22a_24_fallingDoubleJump", x22a_24_fallingDoubleJump); - /* x22a_25_impulseDoubleJump */ - __dna_docout.writeBool("x22a_25_impulseDoubleJump", x22a_25_impulseDoubleJump); - /* x22a_26_firingCancelsCameraPitch */ - __dna_docout.writeBool("x22a_26_firingCancelsCameraPitch", x22a_26_firingCancelsCameraPitch); - /* x22a_27_assistedAimingIgnoreHorizontal */ - __dna_docout.writeBool("x22a_27_assistedAimingIgnoreHorizontal", x22a_27_assistedAimingIgnoreHorizontal); - /* x22a_28_assistedAimingIgnoreVertical */ - __dna_docout.writeBool("x22a_28_assistedAimingIgnoreVertical", x22a_28_assistedAimingIgnoreVertical); - /* x22c_ */ - __dna_docout.writeFloat("x22c_", x22c_); - /* x230_ */ - __dna_docout.writeFloat("x230_", x230_); - /* x234_aimMaxDistance */ - __dna_docout.writeFloat("x234_aimMaxDistance", x234_aimMaxDistance); - /* x238_ */ - __dna_docout.writeFloat("x238_", x238_); - /* x23c_ */ - __dna_docout.writeFloat("x23c_", x23c_); - /* x240_ */ - __dna_docout.writeFloat("x240_", x240_); - /* x244_ */ - __dna_docout.writeFloat("x244_", x244_); - /* x248_ */ - __dna_docout.writeFloat("x248_", x248_); - /* x24c_aimThresholdDistance */ - __dna_docout.writeFloat("x24c_aimThresholdDistance", x24c_aimThresholdDistance); - /* x250_ */ - __dna_docout.writeFloat("x250_", x250_); - /* x254_ */ - __dna_docout.writeFloat("x254_", x254_); - /* x258_aimBoxWidth */ - __dna_docout.writeFloat("x258_aimBoxWidth", x258_aimBoxWidth); - /* x25c_aimBoxHeight */ - __dna_docout.writeFloat("x25c_aimBoxHeight", x25c_aimBoxHeight); - /* x260_aimTargetTimer */ - __dna_docout.writeFloat("x260_aimTargetTimer", x260_aimTargetTimer); - /* x264_aimAssistHorizontalAngle */ - __dna_docout.writeFloat("x264_aimAssistHorizontalAngle", x264_aimAssistHorizontalAngle); - /* x268_aimAssistVerticalAngle */ - __dna_docout.writeFloat("x268_aimAssistVerticalAngle", x268_aimAssistVerticalAngle); - /* x158_orbitMinDistance */ - if (auto v = __dna_docout.enterSubVector("x158_orbitMinDistance")) { - /* x158_orbitMinDistance[0] */ - __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[0]); - /* x158_orbitMinDistance[1] */ - __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[1]); - /* x158_orbitMinDistance[2] */ - __dna_docout.writeFloat("x158_orbitMinDistance", x158_orbitMinDistance[2]); - } - /* x164_orbitNormalDistance */ - if (auto v = __dna_docout.enterSubVector("x164_orbitNormalDistance")) { - /* x164_orbitNormalDistance[0] */ - __dna_docout.writeFloat("x164_orbitNormalDistance", x164_orbitNormalDistance[0]); - /* x164_orbitNormalDistance[1] */ - __dna_docout.writeFloat("x164_orbitNormalDistance", x164_orbitNormalDistance[1]); - /* x164_orbitNormalDistance[2] */ - __dna_docout.writeFloat("x164_orbitNormalDistance", x164_orbitNormalDistance[2]); - } - /* x170_orbitMaxDistance */ - if (auto v = __dna_docout.enterSubVector("x170_orbitMaxDistance")) { - /* x170_orbitMaxDistance[0] */ - __dna_docout.writeFloat("x170_orbitMaxDistance", x170_orbitMaxDistance[0]); - /* x170_orbitMaxDistance[1] */ - __dna_docout.writeFloat("x170_orbitMaxDistance", x170_orbitMaxDistance[1]); - /* x170_orbitMaxDistance[2] */ - __dna_docout.writeFloat("x170_orbitMaxDistance", x170_orbitMaxDistance[2]); - } - /* x17c_ */ - __dna_docout.writeFloat("x17c_", x17c_); - /* x180_orbitModeTimer */ - __dna_docout.writeFloat("x180_orbitModeTimer", x180_orbitModeTimer); - /* x184_orbitCameraSpeed */ - __dna_docout.writeFloat("x184_orbitCameraSpeed", x184_orbitCameraSpeed); - /* x188_orbitUpperAngle */ - __dna_docout.writeFloat("x188_orbitUpperAngle", x188_orbitUpperAngle); - /* x18c_orbitLowerAngle */ - __dna_docout.writeFloat("x18c_orbitLowerAngle", x18c_orbitLowerAngle); - /* x190_orbitHorizAngle */ - __dna_docout.writeFloat("x190_orbitHorizAngle", x190_orbitHorizAngle); - /* x194_ */ - __dna_docout.writeFloat("x194_", x194_); - /* x198_ */ - __dna_docout.writeFloat("x198_", x198_); - /* x19c_orbitMaxTargetDistance */ - __dna_docout.writeFloat("x19c_orbitMaxTargetDistance", x19c_orbitMaxTargetDistance); - /* x1a0_orbitMaxLockDistance */ - __dna_docout.writeFloat("x1a0_orbitMaxLockDistance", x1a0_orbitMaxLockDistance); - /* x1a4_orbitDistanceThreshold */ - __dna_docout.writeFloat("x1a4_orbitDistanceThreshold", x1a4_orbitDistanceThreshold); - /* x1a8_orbitScreenBoxHalfExtentX */ - if (auto v = __dna_docout.enterSubVector("x1a8_orbitScreenBoxHalfExtentX")) { - /* x1a8_orbitScreenBoxHalfExtentX[0] */ - __dna_docout.writeUint32("x1a8_orbitScreenBoxHalfExtentX", x1a8_orbitScreenBoxHalfExtentX[0]); - /* x1a8_orbitScreenBoxHalfExtentX[1] */ - __dna_docout.writeUint32("x1a8_orbitScreenBoxHalfExtentX", x1a8_orbitScreenBoxHalfExtentX[1]); - } - /* x1b0_orbitScreenBoxHalfExtentY */ - if (auto v = __dna_docout.enterSubVector("x1b0_orbitScreenBoxHalfExtentY")) { - /* x1b0_orbitScreenBoxHalfExtentY[0] */ - __dna_docout.writeUint32("x1b0_orbitScreenBoxHalfExtentY", x1b0_orbitScreenBoxHalfExtentY[0]); - /* x1b0_orbitScreenBoxHalfExtentY[1] */ - __dna_docout.writeUint32("x1b0_orbitScreenBoxHalfExtentY", x1b0_orbitScreenBoxHalfExtentY[1]); - } - /* x1b8_orbitScreenBoxCenterX */ - if (auto v = __dna_docout.enterSubVector("x1b8_orbitScreenBoxCenterX")) { - /* x1b8_orbitScreenBoxCenterX[0] */ - __dna_docout.writeUint32("x1b8_orbitScreenBoxCenterX", x1b8_orbitScreenBoxCenterX[0]); - /* x1b8_orbitScreenBoxCenterX[1] */ - __dna_docout.writeUint32("x1b8_orbitScreenBoxCenterX", x1b8_orbitScreenBoxCenterX[1]); - } - /* x1c0_orbitScreenBoxCenterY */ - if (auto v = __dna_docout.enterSubVector("x1c0_orbitScreenBoxCenterY")) { - /* x1c0_orbitScreenBoxCenterY[0] */ - __dna_docout.writeUint32("x1c0_orbitScreenBoxCenterY", x1c0_orbitScreenBoxCenterY[0]); - /* x1c0_orbitScreenBoxCenterY[1] */ - __dna_docout.writeUint32("x1c0_orbitScreenBoxCenterY", x1c0_orbitScreenBoxCenterY[1]); - } - /* x1c8_orbitZoneIdealX */ - if (auto v = __dna_docout.enterSubVector("x1c8_orbitZoneIdealX")) { - /* x1c8_orbitZoneIdealX[0] */ - __dna_docout.writeUint32("x1c8_orbitZoneIdealX", x1c8_orbitZoneIdealX[0]); - /* x1c8_orbitZoneIdealX[1] */ - __dna_docout.writeUint32("x1c8_orbitZoneIdealX", x1c8_orbitZoneIdealX[1]); - } - /* x1d0_orbitZoneIdealY */ - if (auto v = __dna_docout.enterSubVector("x1d0_orbitZoneIdealY")) { - /* x1d0_orbitZoneIdealY[0] */ - __dna_docout.writeUint32("x1d0_orbitZoneIdealY", x1d0_orbitZoneIdealY[0]); - /* x1d0_orbitZoneIdealY[1] */ - __dna_docout.writeUint32("x1d0_orbitZoneIdealY", x1d0_orbitZoneIdealY[1]); - } - /* x1d8_orbitNearX */ - __dna_docout.writeFloat("x1d8_orbitNearX", x1d8_orbitNearX); - /* x1dc_orbitNearZ */ - __dna_docout.writeFloat("x1dc_orbitNearZ", x1dc_orbitNearZ); - /* x1e0_ */ - __dna_docout.writeFloat("x1e0_", x1e0_); - /* x1e4_ */ - __dna_docout.writeFloat("x1e4_", x1e4_); - /* x1e8_orbitFixedOffsetZDiff */ - __dna_docout.writeFloat("x1e8_orbitFixedOffsetZDiff", x1e8_orbitFixedOffsetZDiff); - /* x1ec_orbitZRange */ - __dna_docout.writeFloat("x1ec_orbitZRange", x1ec_orbitZRange); - /* x1f0_ */ - __dna_docout.writeFloat("x1f0_", x1f0_); - /* x1f4_ */ - __dna_docout.writeFloat("x1f4_", x1f4_); - /* x1f8_ */ - __dna_docout.writeFloat("x1f8_", x1f8_); - /* x1fc_orbitPreventionTime */ - __dna_docout.writeFloat("x1fc_orbitPreventionTime", x1fc_orbitPreventionTime); - /* x200_24_dashEnabled */ - __dna_docout.writeBool("x200_24_dashEnabled", x200_24_dashEnabled); - /* x200_25_dashOnButtonRelease */ - __dna_docout.writeBool("x200_25_dashOnButtonRelease", x200_25_dashOnButtonRelease); - /* x204_dashButtonHoldCancelTime */ - __dna_docout.writeFloat("x204_dashButtonHoldCancelTime", x204_dashButtonHoldCancelTime); - /* x208_dashStrafeInputThreshold */ - __dna_docout.writeFloat("x208_dashStrafeInputThreshold", x208_dashStrafeInputThreshold); - /* x20c_sidewaysDoubleJumpImpulse */ - __dna_docout.writeFloat("x20c_sidewaysDoubleJumpImpulse", x20c_sidewaysDoubleJumpImpulse); - /* x210_sidewaysVerticalDoubleJumpAccel */ - __dna_docout.writeFloat("x210_sidewaysVerticalDoubleJumpAccel", x210_sidewaysVerticalDoubleJumpAccel); - /* x214_sidewaysHorizontalDoubleJumpAccel */ - __dna_docout.writeFloat("x214_sidewaysHorizontalDoubleJumpAccel", x214_sidewaysHorizontalDoubleJumpAccel); - /* x218_scanningRange */ - __dna_docout.writeFloat("x218_scanningRange", x218_scanningRange); - /* x21c_24_scanRetention */ - __dna_docout.writeBool("x21c_24_scanRetention", x21c_24_scanRetention); - /* x21c_25_scanFreezesGame */ - __dna_docout.writeBool("x21c_25_scanFreezesGame", x21c_25_scanFreezesGame); - /* x21c_26_orbitWhileScanning */ - __dna_docout.writeBool("x21c_26_orbitWhileScanning", x21c_26_orbitWhileScanning); - /* x220_scanMaxTargetDistance */ - __dna_docout.writeFloat("x220_scanMaxTargetDistance", x220_scanMaxTargetDistance); - /* x224_scanMaxLockDistance */ - __dna_docout.writeFloat("x224_scanMaxLockDistance", x224_scanMaxLockDistance); - /* x2a0_orbitDistanceMax */ - __dna_docout.writeFloat("x2a0_orbitDistanceMax", x2a0_orbitDistanceMax); - /* x2a4_grappleSwingLength */ - __dna_docout.writeFloat("x2a4_grappleSwingLength", x2a4_grappleSwingLength); - /* x2a8_grappleSwingPeriod */ - __dna_docout.writeFloat("x2a8_grappleSwingPeriod", x2a8_grappleSwingPeriod); - /* x2ac_grapplePullSpeedMin */ - __dna_docout.writeFloat("x2ac_grapplePullSpeedMin", x2ac_grapplePullSpeedMin); - /* x2b0_grappleCameraSpeed */ - __dna_docout.writeFloat("x2b0_grappleCameraSpeed", x2b0_grappleCameraSpeed); - /* x2b4_maxGrappleLockedTurnAlignDistance */ - __dna_docout.writeFloat("x2b4_maxGrappleLockedTurnAlignDistance", x2b4_maxGrappleLockedTurnAlignDistance); - /* x2b8_grapplePullSpeedProportion */ - __dna_docout.writeFloat("x2b8_grapplePullSpeedProportion", x2b8_grapplePullSpeedProportion); - /* x2bc_grapplePullSpeedMax */ - __dna_docout.writeFloat("x2bc_grapplePullSpeedMax", x2bc_grapplePullSpeedMax); - /* x2c0_grappleLookCenterSpeed */ - __dna_docout.writeFloat("x2c0_grappleLookCenterSpeed", x2c0_grappleLookCenterSpeed); - /* x2c4_maxGrappleTurnSpeed */ - __dna_docout.writeFloat("x2c4_maxGrappleTurnSpeed", x2c4_maxGrappleTurnSpeed); - /* x2c8_grappleJumpForce */ - __dna_docout.writeFloat("x2c8_grappleJumpForce", x2c8_grappleJumpForce); - /* x2cc_grappleReleaseTime */ - __dna_docout.writeFloat("x2cc_grappleReleaseTime", x2cc_grappleReleaseTime); - /* x2d0_grappleJumpMode */ - __dna_docout.writeUint32("x2d0_grappleJumpMode", x2d0_grappleJumpMode); - /* x2d4_orbitReleaseBreaksGrapple */ - __dna_docout.writeBool("x2d4_orbitReleaseBreaksGrapple", x2d4_orbitReleaseBreaksGrapple); - /* x2d5_invertGrappleTurn */ - __dna_docout.writeBool("x2d5_invertGrappleTurn", x2d5_invertGrappleTurn); - /* x2d8_grappleBeamSpeed */ - __dna_docout.writeFloat("x2d8_grappleBeamSpeed", x2d8_grappleBeamSpeed); - /* x2dc_grappleBeamXWaveAmplitude */ - __dna_docout.writeFloat("x2dc_grappleBeamXWaveAmplitude", x2dc_grappleBeamXWaveAmplitude); - /* x2e0_grappleBeamZWaveAmplitude */ - __dna_docout.writeFloat("x2e0_grappleBeamZWaveAmplitude", x2e0_grappleBeamZWaveAmplitude); - /* x2e4_grappleBeamAnglePhaseDelta */ - __dna_docout.writeFloat("x2e4_grappleBeamAnglePhaseDelta", x2e4_grappleBeamAnglePhaseDelta); - /* x26c_playerHeight */ - __dna_docout.writeFloat("x26c_playerHeight", x26c_playerHeight); - /* x270_playerXYHalfExtent */ - __dna_docout.writeFloat("x270_playerXYHalfExtent", x270_playerXYHalfExtent); - /* x274_stepUpHeight */ - __dna_docout.writeFloat("x274_stepUpHeight", x274_stepUpHeight); - /* x278_stepDownHeight */ - __dna_docout.writeFloat("x278_stepDownHeight", x278_stepDownHeight); - /* x27c_playerBallHalfExtent */ - __dna_docout.writeFloat("x27c_playerBallHalfExtent", x27c_playerBallHalfExtent); - /* x280_ */ - __dna_docout.writeFloat("x280_", x280_firstPersonCameraSpeed); - /* x284_ */ - __dna_docout.writeFloat("x284_", x284_); - /* x288_jumpCameraPitchDownStart */ - __dna_docout.writeFloat("x288_jumpCameraPitchDownStart", x288_jumpCameraPitchDownStart); - /* x28c_jumpCameraPitchDownFull */ - __dna_docout.writeFloat("x28c_jumpCameraPitchDownFull", x28c_jumpCameraPitchDownFull); - /* x290_jumpCameraPitchDownAngle */ - __dna_docout.writeFloat("x290_jumpCameraPitchDownAngle", x290_jumpCameraPitchDownAngle); - /* x294_fallCameraPitchDownStart */ - __dna_docout.writeFloat("x294_fallCameraPitchDownStart", x294_fallCameraPitchDownStart); - /* x298_fallCameraPitchDownFull */ - __dna_docout.writeFloat("x298_fallCameraPitchDownFull", x298_fallCameraPitchDownFull); - /* x29c_fallCameraPitchDownAngle */ - __dna_docout.writeFloat("x29c_fallCameraPitchDownAngle", x29c_fallCameraPitchDownAngle); - /* x2e8_ */ - __dna_docout.writeFloat("x2e8_", x2e8_); - /* x2ec_ */ - __dna_docout.writeFloat("x2ec_", x2ec_); - /* x2f0_ */ - __dna_docout.writeFloat("x2f0_", x2f0_); - /* x2f4_ */ - __dna_docout.writeBool("x2f4_", x2f4_); - /* x2f8_frozenTimeout */ - __dna_docout.writeFloat("x2f8_frozenTimeout", x2f8_frozenTimeout); - /* x2fc_iceBreakJumpCount */ - __dna_docout.writeUint32("x2fc_iceBreakJumpCount", x2fc_iceBreakJumpCount); - /* x300_variaDamageReduction */ - __dna_docout.writeFloat("x300_variaDamageReduction", x300_variaDamageReduction); - /* x304_gravityDamageReduction */ - __dna_docout.writeFloat("x304_gravityDamageReduction", x304_gravityDamageReduction); - /* x308_phazonDamageReduction */ - __dna_docout.writeFloat("x308_phazonDamageReduction", x308_phazonDamageReduction); -} - -void CTweakPlayer::FixupValues() { - x130_horizontalFreeLookAngleVel = zeus::degToRad(x130_horizontalFreeLookAngleVel); - x134_verticalFreeLookAngleVel = zeus::degToRad(x134_verticalFreeLookAngleVel); - x138_freeLookSpeed = zeus::degToRad(x138_freeLookSpeed); - x13c_freeLookSnapSpeed = zeus::degToRad(x13c_freeLookSnapSpeed); - x140_ = zeus::degToRad(x140_); - x144_freeLookCenteredThresholdAngle = zeus::degToRad(x144_freeLookCenteredThresholdAngle); - x23c_ = zeus::degToRad(x23c_); - x240_ = zeus::degToRad(x240_); - x244_ = zeus::degToRad(x244_); - x248_ = zeus::degToRad(x248_); - x250_ = zeus::degToRad(x250_); - x264_aimAssistHorizontalAngle = zeus::degToRad(x264_aimAssistHorizontalAngle); - x268_aimAssistVerticalAngle = zeus::degToRad(x268_aimAssistVerticalAngle); - x17c_ = zeus::degToRad(x17c_); - x184_orbitCameraSpeed = zeus::degToRad(x184_orbitCameraSpeed); - x188_orbitUpperAngle = zeus::degToRad(x188_orbitUpperAngle); - x18c_orbitLowerAngle = zeus::degToRad(x18c_orbitLowerAngle); - x190_orbitHorizAngle = zeus::degToRad(x190_orbitHorizAngle); - x194_ = zeus::degToRad(x194_); - x198_ = zeus::degToRad(x198_); - x1f0_ = zeus::degToRad(x1f0_); - x1f4_ = zeus::degToRad(x1f4_); - x2b0_grappleCameraSpeed = zeus::degToRad(x2b0_grappleCameraSpeed); - x2c0_grappleLookCenterSpeed = zeus::degToRad(x2c0_grappleLookCenterSpeed); - x280_firstPersonCameraSpeed = zeus::degToRad(x280_firstPersonCameraSpeed); - x284_ = zeus::degToRad(x284_); - x290_jumpCameraPitchDownAngle = zeus::degToRad(x290_jumpCameraPitchDownAngle); - x29c_fallCameraPitchDownAngle = zeus::degToRad(x29c_fallCameraPitchDownAngle); -} - -std::string_view CTweakPlayer::DNAType() { return "DataSpec::DNAMP1::CTweakPlayer"sv; } -template <> -void CTweakPlayer::Enumerate(size_t& __isz) { - __isz += 785; -} - -void CTweakPlayer::_tweakListener(hecl::CVar* cv) { - UPDATE_CVAR(MaxTranslationAccelerationNormal, cv, x4_maxTranslationalAcceleration[0]); - UPDATE_CVAR(MaxTranslationAccelerationAir, cv, x4_maxTranslationalAcceleration[1]); - UPDATE_CVAR(MaxTranslationAccelerationIce, cv, x4_maxTranslationalAcceleration[2]); - UPDATE_CVAR(MaxTranslationAccelerationOrganic, cv, x4_maxTranslationalAcceleration[3]); - UPDATE_CVAR(MaxTranslationAccelerationWater, cv, x4_maxTranslationalAcceleration[4]); - UPDATE_CVAR(MaxTranslationAccelerationLava, cv, x4_maxTranslationalAcceleration[5]); - UPDATE_CVAR(MaxTranslationAccelerationPhazon, cv, x4_maxTranslationalAcceleration[6]); - UPDATE_CVAR(MaxRotationAccelerationShrubbery, cv, x24_maxRotationalAcceleration[7]); - UPDATE_CVAR(MaxRotationAccelerationNormal, cv, x24_maxRotationalAcceleration[0]); - UPDATE_CVAR(MaxRotationAccelerationAir, cv, x24_maxRotationalAcceleration[1]); - UPDATE_CVAR(MaxRotationAccelerationIce, cv, x24_maxRotationalAcceleration[2]); - UPDATE_CVAR(MaxRotationAccelerationOrganic, cv, x24_maxRotationalAcceleration[3]); - UPDATE_CVAR(MaxRotationAccelerationWater, cv, x24_maxRotationalAcceleration[4]); - UPDATE_CVAR(MaxRotationAccelerationLava, cv, x24_maxRotationalAcceleration[5]); - UPDATE_CVAR(MaxRotationAccelerationPhazon, cv, x24_maxRotationalAcceleration[6]); - UPDATE_CVAR(MaxRotationAccelerationShrubbery, cv, x24_maxRotationalAcceleration[7]); - UPDATE_CVAR(TranslationFrictionNormal, cv, x44_translationFriction[0]); - UPDATE_CVAR(TranslationFrictionAir, cv, x44_translationFriction[1]); - UPDATE_CVAR(TranslationFrictionIce, cv, x44_translationFriction[2]); - UPDATE_CVAR(TranslationFrictionOrganic, cv, x44_translationFriction[3]); - UPDATE_CVAR(TranslationFrictionWater, cv, x44_translationFriction[4]); - UPDATE_CVAR(TranslationFrictionLava, cv, x44_translationFriction[5]); - UPDATE_CVAR(TranslationFrictionPhazon, cv, x44_translationFriction[6]); - UPDATE_CVAR(TranslationFrictionShrubbery, cv, x44_translationFriction[7]); - UPDATE_CVAR(RotationFrictionNormal, cv, x44_translationFriction[2]); - UPDATE_CVAR(RotationFrictionIce, cv, x44_translationFriction[2]); - UPDATE_CVAR(RotationFrictionOrganic, cv, x44_translationFriction[3]); - UPDATE_CVAR(RotationFrictionWater, cv, x44_translationFriction[4]); - UPDATE_CVAR(RotationFrictionLava, cv, x44_translationFriction[5]); - UPDATE_CVAR(RotationFrictionPhazon, cv, x44_translationFriction[6]); - UPDATE_CVAR(RotationFrictionShrubbery, cv, x44_translationFriction[7]); - UPDATE_CVAR(RotationMaxSpeedNormal, cv, x84_rotationMaxSpeed[2]); - UPDATE_CVAR(RotationMaxSpeedIce, cv, x84_rotationMaxSpeed[2]); - UPDATE_CVAR(RotationMaxSpeedOrganic, cv, x84_rotationMaxSpeed[3]); - UPDATE_CVAR(RotationMaxSpeedWater, cv, x84_rotationMaxSpeed[4]); - UPDATE_CVAR(RotationMaxSpeedLava, cv, x84_rotationMaxSpeed[5]); - UPDATE_CVAR(RotationMaxSpeedPhazon, cv, x84_rotationMaxSpeed[6]); - UPDATE_CVAR(RotationMaxSpeedShrubbery, cv, x84_rotationMaxSpeed[7]); - UPDATE_CVAR(TranslationMaxSpeedNormal, cv, xa4_translationMaxSpeed[2]); - UPDATE_CVAR(TranslationMaxSpeedIce, cv, xa4_translationMaxSpeed[2]); - UPDATE_CVAR(TranslationMaxSpeedOrganic, cv, xa4_translationMaxSpeed[3]); - UPDATE_CVAR(TranslationMaxSpeedWater, cv, xa4_translationMaxSpeed[4]); - UPDATE_CVAR(TranslationMaxSpeedLava, cv, xa4_translationMaxSpeed[5]); - UPDATE_CVAR(TranslationMaxSpeedPhazon, cv, xa4_translationMaxSpeed[6]); - UPDATE_CVAR(TranslationMaxSpeedShrubbery, cv, xa4_translationMaxSpeed[7]); - UPDATE_CVAR(NormalGravityAcceleration, cv, xc4_normalGravAccel); - UPDATE_CVAR(FluidGravityAcceleration, cv, xc8_fluidGravAccel); - UPDATE_CVAR(VerticalJumpAcceleration, cv, xcc_verticalJumpAccel); - UPDATE_CVAR(HorizontalJumpAcceleration, cv, xd0_horizontalJumpAccel); - UPDATE_CVAR(VerticalDoubleJumpAcceleration, cv, xd4_verticalDoubleJumpAccel); - UPDATE_CVAR(HorizontalDoubleJumpAcceleration, cv, xd8_horizontalDoubleJumpAccel); - UPDATE_CVAR(WaterJumpFactor, cv, xdc_waterJumpFactor); - UPDATE_CVAR(WaterBallJumpFactor, cv, xe0_waterBallJumpFactor); - UPDATE_CVAR(LavaJumpFactor, cv, xe4_lavaJumpFactor); - UPDATE_CVAR(LavaBallJumpFactor, cv, xe8_lavaBallJumpFactor); - UPDATE_CVAR(PhazonJumpFactor, cv, xec_phazonJumpFactor); - UPDATE_CVAR(PhazonBallJumpFactor, cv, xf0_phazonBallJumpFactor); - UPDATE_CVAR(AllowedJumpTime, cv, xf4_allowedJumpTime); - UPDATE_CVAR(AllowedDoubleJumpTime, cv, xf8_allowedDoubleJumpTime); - UPDATE_CVAR(MinDoubleJumpWindow, cv, xfc_minDoubleJumpWindow); - UPDATE_CVAR(MaxDoubleJumpWindow, cv, x100_maxDoubleJumpWindow); - // UPDATE_CVAR(); // x104_ - UPDATE_CVAR(MinJumpTime, cv, x108_minJumpTime); - UPDATE_CVAR(MinDoubleJumpTime, cv, x10c_minDoubleJumpTime); - UPDATE_CVAR(AllowedLedgeTime, cv, x110_allowedLedgeTime); - UPDATE_CVAR(DoubleJumpImpulse, cv, x114_doubleJumpImpulse); - UPDATE_CVAR(BackwardsForceMultiplier, cv, x118_backwardsForceMultiplier); - UPDATE_CVAR(BombJumpRadius, cv, x11c_bombJumpRadius); - UPDATE_CVAR(BombJumpHeight, cv, x120_bombJumpHeight); - UPDATE_CVAR(EyeOffset, cv, x124_eyeOffset); - UPDATE_CVAR(TurnSpeedMultiplier, cv, x128_turnSpeedMultiplier); - UPDATE_CVAR(FreeLookTurnSpeedMultiplier, cv, x12c_freeLookTurnSpeedMultiplier); - UPDATE_CVAR(HorizontalFreeLookAngleVelocity, cv, x130_horizontalFreeLookAngleVel); - UPDATE_CVAR(VerticalFreeLookAngleVelocity, cv, x134_verticalFreeLookAngleVel); - UPDATE_CVAR(FreeLookSpeed, cv, x138_freeLookSpeed); - UPDATE_CVAR(FreeLookSnapSpeed, cv, x13c_freeLookSnapSpeed); - // UPDATE_CVAR(); // x140_ - UPDATE_CVAR(FreeLookCenteredThresholdAngle, cv, x144_freeLookCenteredThresholdAngle); - UPDATE_CVAR(FreeLookCenteredTime, cv, x148_freeLookCenteredTime); - UPDATE_CVAR(FreeLookDampenFactor, cv, x14c_freeLookDampenFactor); - UPDATE_CVAR(LeftDivisor, cv, x150_leftDiv); - UPDATE_CVAR(RightDivisor, cv, x154_rightDiv); - UPDATE_CVAR(OrbitMinDistanceClose, cv, x158_orbitMinDistance[0]); - UPDATE_CVAR(OrbitMinDistanceFar, cv, x158_orbitMinDistance[1]); - UPDATE_CVAR(OrbitMinDistanceDefault, cv, x158_orbitMinDistance[2]); - UPDATE_CVAR(OrbitNormalDistanceClose, cv, x164_orbitNormalDistance[0]); - UPDATE_CVAR(OrbitNormalDistanceFar, cv, x164_orbitNormalDistance[1]); - UPDATE_CVAR(OrbitNormalDistanceDefault, cv, x164_orbitNormalDistance[2]); - UPDATE_CVAR(OrbitMaxDistanceClose, cv, x170_orbitMaxDistance[0]); - UPDATE_CVAR(OrbitMaxDistanceFar, cv, x170_orbitMaxDistance[1]); - UPDATE_CVAR(OrbitMaxDistanceDefault, cv, x170_orbitMaxDistance[2]); - // UPDATE_CVAR(); // x17c_ - UPDATE_CVAR(OrbitmodeTimer, cv, x180_orbitModeTimer); - UPDATE_CVAR(OrbitCameraSpeed, cv, x184_orbitCameraSpeed); - UPDATE_CVAR(OrbitUpperAngle, cv, x188_orbitUpperAngle); - UPDATE_CVAR(OrbitLowerAngle, cv, x18c_orbitLowerAngle); - UPDATE_CVAR(OrbitHorizontalAngle, cv, x190_orbitHorizAngle); - // UPDATE_CVAR(); // x194_ - // UPDATE_CVAR(); // x198_ - UPDATE_CVAR(OrbitMaxTargetDistance, cv, x19c_orbitMaxTargetDistance); - UPDATE_CVAR(OrbitMaxLockDistance, cv, x1a0_orbitMaxLockDistance); - UPDATE_CVAR(OrbitDistanceThreshold, cv, x1a4_orbitDistanceThreshold); - UPDATE_CVAR(OrbitScreenTargetingBoxHalfExtentX, cv, x1a8_orbitScreenBoxHalfExtentX[0]); - UPDATE_CVAR(OrbitScreenScanBoxHalfExtentX, cv, x1a8_orbitScreenBoxHalfExtentX[1]); - UPDATE_CVAR(OrbitScreenTargetingBoxHalfExtentY, cv, x1b0_orbitScreenBoxHalfExtentY[0]); - UPDATE_CVAR(OrbitScreenScanBoxHalfExtentY, cv, x1b0_orbitScreenBoxHalfExtentY[1]); - UPDATE_CVAR(OrbitScreenTargetingBoxCenterX, cv, x1b8_orbitScreenBoxCenterX[0]); - UPDATE_CVAR(OrbitScreenScanBoxCenterX, cv, x1b8_orbitScreenBoxCenterX[1]); - UPDATE_CVAR(OrbitScreenTargetingBoxCenterY, cv, x1c0_orbitScreenBoxCenterY[0]); - UPDATE_CVAR(OrbitScreenScanBoxCenterY, cv, x1c0_orbitScreenBoxCenterY[1]); - UPDATE_CVAR(OrbitZoneTargetingIdealX, cv, x1c8_orbitZoneIdealX[0]); - UPDATE_CVAR(OrbitZoneScanIdealX, cv, x1c8_orbitZoneIdealX[1]); - UPDATE_CVAR(OrbitZoneTargetingIdealY, cv, x1d0_orbitZoneIdealY[0]); - UPDATE_CVAR(OrbitZoneScanIdealY, cv, x1d0_orbitZoneIdealY[1]); - UPDATE_CVAR(OrbitNearX, cv, x1d8_orbitNearX); - UPDATE_CVAR(OrbitNearZ, cv, x1dc_orbitNearZ); - // UPDATE_CVAR(); // x1e0_ - // UPDATE_CVAR(); // x1e4_ - UPDATE_CVAR(OrbitFixedOffsetZDiff, cv, x1e8_orbitFixedOffsetZDiff); - UPDATE_CVAR(OrbitZRange, cv, x1ec_orbitZRange); - // UPDATE_CVAR(); // x1f0_ - // UPDATE_CVAR(); // x1f4_ - // UPDATE_CVAR(); // x1f8_ - UPDATE_CVAR(OrbitPreventionTime, cv, x1fc_orbitPreventionTime); - UPDATE_CVAR_BITFIELD(DashEnabled, cv, x200_24_dashEnabled); - UPDATE_CVAR_BITFIELD(DashOnButtonRelease, cv, x200_25_dashOnButtonRelease); - UPDATE_CVAR(DashButtonHoldCancelTime, cv, x204_dashButtonHoldCancelTime); - UPDATE_CVAR(DashStrafeInputThreshold, cv, x208_dashStrafeInputThreshold); - UPDATE_CVAR(SidewaysDoubleJumpImpulse, cv, x20c_sidewaysDoubleJumpImpulse); - UPDATE_CVAR(SidewaysVerticalDoubleJumpAccel, cv, x210_sidewaysVerticalDoubleJumpAccel); - UPDATE_CVAR(SidewaysHorizontalDoubleJumpAccel, cv, x214_sidewaysHorizontalDoubleJumpAccel); - UPDATE_CVAR(ScanningRange, cv, x218_scanningRange); - UPDATE_CVAR_BITFIELD(ScanRetention, cv, x21c_24_scanRetention); - UPDATE_CVAR_BITFIELD(ScanFreezesGame, cv, x21c_25_scanFreezesGame); - UPDATE_CVAR_BITFIELD(OrbitWhileScanning, cv, x21c_26_orbitWhileScanning); - UPDATE_CVAR(ScanMaxTargetDistance, cv, x220_scanMaxTargetDistance); - UPDATE_CVAR(ScanMaxLockDistance, cv, x224_scanMaxLockDistance); - UPDATE_CVAR_BITFIELD(FreeLookTurnsPlayer, cv, x228_24_freelookTurnsPlayer); - // UPDATE_CVAR_BITFIELD(); // x228_25_ - // UPDATE_CVAR_BITFIELD(); // x228_26_ - UPDATE_CVAR_BITFIELD(MoveDuringFreelook, cv, x228_27_moveDuringFreeLook); - UPDATE_CVAR_BITFIELD(HoldButtonsForFreeLook, cv, x228_28_holdButtonsForFreeLook); - // UPDATE_CVAR_BITFIELD(); // x228_30_ - // UPDATE_CVAR_BITFIELD(); // x228_31_ - // UPDATE_CVAR_BITFIELD(); // x229_24_ - UPDATE_CVAR_BITFIELD(AimWhenOrbitingPoint, cv, x229_25_aimWhenOrbitingPoint); - UPDATE_CVAR_BITFIELD(StayInFreeLookWhileFiring, cv, x229_26_stayInFreeLookWhileFiring); - // UPDATE_CVAR_BITFIELD(); // x229_27_ - // UPDATE_CVAR_BITFIELD(); // x229_28_ - UPDATE_CVAR_BITFIELD(OrbitFixedOffset, cv, x229_29_orbitFixedOffset); - UPDATE_CVAR_BITFIELD(GunButtonTogglesHolster, cv, x229_30_gunButtonTogglesHolster); - UPDATE_CVAR_BITFIELD(GunNotFiringHolstersGun, cv, x229_31_gunNotFiringHolstersGun); - UPDATE_CVAR_BITFIELD(FallingDoubleJump, cv, x22a_24_fallingDoubleJump); - UPDATE_CVAR_BITFIELD(ImpulseDoubleJump, cv, x22a_25_impulseDoubleJump); - UPDATE_CVAR_BITFIELD(FiringCancelsCameraPitch, cv, x22a_26_firingCancelsCameraPitch); - UPDATE_CVAR_BITFIELD(AssistedAimingIgnoreHorizontal, cv, x22a_27_assistedAimingIgnoreHorizontal); - UPDATE_CVAR_BITFIELD(AssistedAimingIgnoreVertical, cv, x22a_28_assistedAimingIgnoreVertical); - // UPDATE_CVAR(); // x22c - // UPDATE_CVAR(); // x230_ - UPDATE_CVAR(AimMaxDistance, cv, x234_aimMaxDistance); - // UPDATE_CVAR(); // x238_ - // UPDATE_CVAR(); // x23c_ - // UPDATE_CVAR(); // x240_ - // UPDATE_CVAR(); // x244_ - // UPDATE_CVAR(); // x248_ - UPDATE_CVAR(AimThresholdDistance, cv, x24c_aimThresholdDistance); - // UPDATE_CVAR(); // x250_ - // UPDATE_CVAR(); // x254_ - UPDATE_CVAR(AimBoxWidth, cv, x258_aimBoxWidth); - UPDATE_CVAR(AimBoxHeight, cv, x25c_aimBoxHeight); - UPDATE_CVAR(AimTargetTimer, cv, x260_aimTargetTimer); - UPDATE_CVAR(AimAssistHorizontalAngle, cv, x264_aimAssistHorizontalAngle); - UPDATE_CVAR(AimAssistVerticalAngle, cv, x268_aimAssistVerticalAngle); - UPDATE_CVAR(PlayerHeight, cv, x26c_playerHeight); - UPDATE_CVAR(PlayerXYHalfExtent, cv, x270_playerXYHalfExtent); - UPDATE_CVAR(StepUpHeight, cv, x274_stepUpHeight); - UPDATE_CVAR(StepDownHeight, cv, x278_stepDownHeight); - UPDATE_CVAR(PlayerBallHalfExtent, cv, x27c_playerBallHalfExtent); - UPDATE_CVAR(FirstPersonCameraSpeed, cv, x280_firstPersonCameraSpeed); - // UPDATE_CVAR(); // x284_ - UPDATE_CVAR(JumpCameraPitchDownStart, cv, x288_jumpCameraPitchDownStart); - UPDATE_CVAR(JumpCameraPitchDownFull, cv, x28c_jumpCameraPitchDownFull); - UPDATE_CVAR(JumpCameraPitchDownAngle, cv, x290_jumpCameraPitchDownAngle); - UPDATE_CVAR(FallCameraPitchDownStart, cv, x294_fallCameraPitchDownStart); - UPDATE_CVAR(FallCameraPitchDownFull, cv, x298_fallCameraPitchDownFull); - UPDATE_CVAR(FallCameraPitchDownAngle, cv, x29c_fallCameraPitchDownAngle); - UPDATE_CVAR(OrbitDistanceMax, cv, x2a0_orbitDistanceMax); - UPDATE_CVAR(GrappleSwingLength, cv, x2a4_grappleSwingLength); - UPDATE_CVAR(GrappleSwingPeriod, cv, x2a8_grappleSwingPeriod); - UPDATE_CVAR(GrapplePullSpeedMin, cv, x2ac_grapplePullSpeedMin); - UPDATE_CVAR(GrappleCameraSpeed, cv, x2b0_grappleCameraSpeed); - UPDATE_CVAR(MaxGrappleLockedTurnAlignDistance, cv, x2b4_maxGrappleLockedTurnAlignDistance); - UPDATE_CVAR(GrapplePullSpeedProportion, cv, x2b8_grapplePullSpeedProportion); - UPDATE_CVAR(GrapplePullSpeedMax, cv, x2bc_grapplePullSpeedMax); - UPDATE_CVAR(GrappleLookCenterSpeed, cv, x2c0_grappleLookCenterSpeed); - UPDATE_CVAR(MaxGrappleTurnSpeed, cv, x2c4_maxGrappleTurnSpeed); - UPDATE_CVAR(GrappleJumpForce, cv, x2c8_grappleJumpForce); - UPDATE_CVAR(GrappleReleaseTime, cv, x2cc_grappleReleaseTime); - UPDATE_CVAR(GrappleJumpMode, cv, x2d0_grappleJumpMode); - UPDATE_CVAR(OrbitReleaseBreaksGrapple, cv, x2d4_orbitReleaseBreaksGrapple); - UPDATE_CVAR(InvertGrappleTurn, cv, x2d5_invertGrappleTurn); - UPDATE_CVAR(GrappleBeamSpeed, cv, x2d8_grappleBeamSpeed); - UPDATE_CVAR(GrappleBeamXWaveAmplitude, cv, x2dc_grappleBeamXWaveAmplitude); - UPDATE_CVAR(GrappleBeamZWaveAmplitude, cv, x2e0_grappleBeamZWaveAmplitude); - UPDATE_CVAR(GrappleBeamAnglePhaseDelta, cv, x2e4_grappleBeamAnglePhaseDelta); - // UPDATE_CVAR(); // x2e8_ - // UPDATE_CVAR(); // x2ec_ - // UPDATE_CVAR(); // x2f0_ - // UPDATE_CVAR(); // x2f4_ - UPDATE_CVAR(FrozenTimeout, cv, x2f8_frozenTimeout); - UPDATE_CVAR(IceBreakJumpCount, cv, x2fc_iceBreakJumpCount); - UPDATE_CVAR(VariaDamageReduction, cv, x300_variaDamageReduction); - UPDATE_CVAR(GravityDamageReduction, cv, x304_gravityDamageReduction); - UPDATE_CVAR(PhazonDamageReduction, cv, x308_phazonDamageReduction); -} - -void CTweakPlayer::initCVars(hecl::CVarManager* mgr) { - CREATE_CVAR(MaxTranslationAccelerationNormal, - "Max translation acceleration allowed to the player under normal circumstances", - x4_maxTranslationalAcceleration[0], skDefaultFlags); - CREATE_CVAR(MaxTranslationAccelerationAir, "Max translation acceleration allowed to the player while in air", - x4_maxTranslationalAcceleration[1], skDefaultFlags); - CREATE_CVAR(MaxTranslationAccelerationIce, "Max translation acceleration allowed to the player while on ice surfaces", - x4_maxTranslationalAcceleration[2], skDefaultFlags); - CREATE_CVAR(MaxTranslationAccelerationOrganic, - "Max translation acceleration allowed to the player while on organic surfaces", - x4_maxTranslationalAcceleration[3], skDefaultFlags); - CREATE_CVAR(MaxTranslationAccelerationWater, "Max translation acceleration allowed to the player while in water", - x4_maxTranslationalAcceleration[4], skDefaultFlags); - CREATE_CVAR(MaxTranslationAccelerationLava, "Max translation acceleration allowed to the player while in lava", - x4_maxTranslationalAcceleration[5], skDefaultFlags); - CREATE_CVAR(MaxTranslationAccelerationPhazon, "Max translation acceleration allowed to the player while in phazon", - x4_maxTranslationalAcceleration[6], skDefaultFlags); - CREATE_CVAR(MaxTranslationAccelerationShrubbery, - "Max translation acceleration allowed to the player while in shrubbery", - x4_maxTranslationalAcceleration[7], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationNormal, - "Max rotation acceleration allowed to the player under normal circumstances", - x24_maxRotationalAcceleration[0], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationAir, "Max rotation acceleration allowed to the player while in air", - x24_maxRotationalAcceleration[1], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationIce, "Max rotation acceleration allowed to the player while on ice surfaces", - x24_maxRotationalAcceleration[2], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationOrganic, - "Max rotation acceleration allowed to the player while on organic surfaces", - x24_maxRotationalAcceleration[3], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationWater, "Max rotation acceleration allowed to the player while in water", - x24_maxRotationalAcceleration[4], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationLava, "Max rotation acceleration allowed to the player while in lava", - x24_maxRotationalAcceleration[5], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationPhazon, "Max rotation acceleration allowed to the player while in phazon", - x24_maxRotationalAcceleration[6], skDefaultFlags); - CREATE_CVAR(MaxRotationAccelerationShrubbery, "Max rotation acceleration allowed to the player while in shrubbery", - x24_maxRotationalAcceleration[7], skDefaultFlags); - CREATE_CVAR(TranslationFrictionNormal, "Translation friction allowed to the player under normal circumstances", - x44_translationFriction[0], skDefaultFlags); - CREATE_CVAR(TranslationFrictionAir, "Translation friction allowed to the player while in air", - x44_translationFriction[1], skDefaultFlags); - CREATE_CVAR(TranslationFrictionIce, "Translation friction allowed to the player while on ice surfaces", - x44_translationFriction[2], skDefaultFlags); - CREATE_CVAR(TranslationFrictionOrganic, "Translation friction allowed to the player while on organic surfaces", - x44_translationFriction[3], skDefaultFlags); - CREATE_CVAR(TranslationFrictionWater, "Translation friction allowed to the player while in water", - x44_translationFriction[4], skDefaultFlags); - CREATE_CVAR(TranslationFrictionLava, "Translation friction allowed to the player while in lava", - x44_translationFriction[5], skDefaultFlags); - CREATE_CVAR(TranslationFrictionPhazon, "Translation friction allowed to the player while in phazon", - x44_translationFriction[6], skDefaultFlags); - CREATE_CVAR(TranslationFrictionShrubbery, "Translation friction allowed to the player while in shrubbery", - x44_translationFriction[7], skDefaultFlags); - CREATE_CVAR(RotationFrictionNormal, "Rotation friction allowed to the player under normal circumstances", - x44_translationFriction[0], skDefaultFlags); - CREATE_CVAR(RotationFrictionAir, "Rotation friction allowed to the player while in air", x44_translationFriction[1], - skDefaultFlags); - CREATE_CVAR(RotationFrictionIce, "Rotation friction allowed to the player while on ice surfaces", - x44_translationFriction[2], skDefaultFlags); - CREATE_CVAR(RotationFrictionOrganic, "Rotation friction allowed to the player while on organic surfaces", - x44_translationFriction[3], skDefaultFlags); - CREATE_CVAR(RotationFrictionWater, "Rotation friction allowed to the player while in water", - x44_translationFriction[4], skDefaultFlags); - CREATE_CVAR(RotationFrictionLava, "Rotation friction allowed to the player while in lava", x44_translationFriction[5], - skDefaultFlags); - CREATE_CVAR(RotationFrictionPhazon, "Rotation friction allowed to the player while in phazon", - x44_translationFriction[6], skDefaultFlags); - CREATE_CVAR(RotationFrictionShrubbery, "Rotation friction allowed to the player while in shrubbery", - x44_translationFriction[7], skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedNormal, "Rotation max speed allowed to the player under normal circumstances", - x84_rotationMaxSpeed[0], skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedAir, "Rotation max speed allowed to the player while in air", x84_rotationMaxSpeed[1], - skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedIce, "Rotation max speed allowed to the player while on ice surfaces", - x84_rotationMaxSpeed[2], skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedOrganic, "Rotation max speed allowed to the player while on organic surfaces", - x84_rotationMaxSpeed[3], skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedWater, "Rotation max speed allowed to the player while in water", x84_rotationMaxSpeed[4], - skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedLava, "Rotation max speed allowed to the player while in lava", x84_rotationMaxSpeed[5], - skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedPhazon, "Rotation max speed allowed to the player while in phazon", - x84_rotationMaxSpeed[6], skDefaultFlags); - CREATE_CVAR(RotationMaxSpeedShrubbery, "Rotation max speed allowed to the player while in shrubbery", - x84_rotationMaxSpeed[7], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedNormal, "Translation max speed allowed to the player under normal circumstances", - xa4_translationMaxSpeed[0], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedNormal, "Translation max speed allowed to the player under normal circumstances", - xa4_translationMaxSpeed[1], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedIce, "Translation max speed allowed to the player while on ice surfaces", - xa4_translationMaxSpeed[2], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedOrganic, "Translation max speed allowed to the player while on organic surfaces", - xa4_translationMaxSpeed[3], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedWater, "Translation max speed allowed to the player while in water", - xa4_translationMaxSpeed[4], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedLava, "Translation max speed allowed to the player while in lava", - xa4_translationMaxSpeed[5], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedPhazon, "Translation max speed allowed to the player while in phazon", - xa4_translationMaxSpeed[6], skDefaultFlags); - CREATE_CVAR(TranslationMaxSpeedShrubbery, "Translation max speed allowed to the player while in shrubbery", - xa4_translationMaxSpeed[7], skDefaultFlags); - CREATE_CVAR(NormalGravityAcceleration, "Gravity applied to the player under normal circumstances", - xc4_normalGravAccel, skDefaultFlags); - CREATE_CVAR(FluidGravityAcceleration, "Gravity applied to the player while in water", xc8_fluidGravAccel, - skDefaultFlags); - CREATE_CVAR(VerticalJumpAcceleration, "Vertical acceleration applied while jumping", xcc_verticalJumpAccel, - skDefaultFlags); - CREATE_CVAR(HorizontalJumpAcceleration, "Horizontal acceleration while jumping", xd0_horizontalJumpAccel, - skDefaultFlags); - CREATE_CVAR(VerticalDoubleJumpAcceleration, "Vertical acceleration while double jumping", xd4_verticalDoubleJumpAccel, - skDefaultFlags); - CREATE_CVAR(HorizontalDoubleJumpAcceleration, "Horizontal acceleration while double jumping", - xd8_horizontalDoubleJumpAccel, skDefaultFlags); - CREATE_CVAR(WaterJumpFactor, "Jump Factor while in water", xdc_waterJumpFactor, skDefaultFlags); - CREATE_CVAR(WaterBallJumpFactor, "Jump Factor while morphed in water", xe0_waterBallJumpFactor, skDefaultFlags); - CREATE_CVAR(LavaJumpFactor, "Jump Factor while in lava", xe4_lavaJumpFactor, skDefaultFlags); - CREATE_CVAR(LavaBallJumpFactor, "Jump Factor while morphed in lava", xe8_lavaBallJumpFactor, skDefaultFlags); - CREATE_CVAR(PhazonJumpFactor, "Jump Factor while in phazon", xec_phazonJumpFactor, skDefaultFlags); - CREATE_CVAR(PhazonBallJumpFactor, "Jump Factor while morphed in phazon", xf0_phazonBallJumpFactor, skDefaultFlags); - CREATE_CVAR(AllowedJumpTime, "", xf4_allowedJumpTime, skDefaultFlags); - CREATE_CVAR(AllowedDoubleJumpTime, "", xf8_allowedDoubleJumpTime, skDefaultFlags); - CREATE_CVAR(MinDoubleJumpWindow, "", xfc_minDoubleJumpWindow, skDefaultFlags); - CREATE_CVAR(MaxDoubleJumpWindow, "", x100_maxDoubleJumpWindow, skDefaultFlags); - // CREATE_CVAR(); // x104_ - CREATE_CVAR(MinJumpTime, "", x108_minJumpTime, skDefaultFlags); - CREATE_CVAR(MinDoubleJumpTime, "", x10c_minDoubleJumpTime, skDefaultFlags); - CREATE_CVAR(AllowedLedgeTime, "", x110_allowedLedgeTime, skDefaultFlags); - CREATE_CVAR(DoubleJumpImpulse, "", x114_doubleJumpImpulse, skDefaultFlags); - CREATE_CVAR(BackwardsForceMultiplier, "", x118_backwardsForceMultiplier, skDefaultFlags); - CREATE_CVAR(BombJumpRadius, "", x11c_bombJumpRadius, skDefaultFlags); - CREATE_CVAR(BombJumpHeight, "", x120_bombJumpHeight, skDefaultFlags); - CREATE_CVAR(EyeOffset, "", x124_eyeOffset, skDefaultFlags); - CREATE_CVAR(TurnSpeedMultiplier, "", x128_turnSpeedMultiplier, skDefaultFlags); - CREATE_CVAR(FreeLookTurnSpeedMultiplier, "", x12c_freeLookTurnSpeedMultiplier, skDefaultFlags); - CREATE_CVAR(HorizontalFreeLookAngleVelocity, "", x130_horizontalFreeLookAngleVel, skDefaultFlags); - CREATE_CVAR(VerticalFreeLookAngleVelocity, "", x134_verticalFreeLookAngleVel, skDefaultFlags); - CREATE_CVAR(FreeLookSpeed, "", x138_freeLookSpeed, skDefaultFlags); - CREATE_CVAR(FreeLookSnapSpeed, "", x13c_freeLookSnapSpeed, skDefaultFlags); - // CREATE_CVAR(); // x140_ - CREATE_CVAR(FreeLookCenteredThresholdAngle, "", x144_freeLookCenteredThresholdAngle, skDefaultFlags); - CREATE_CVAR(FreeLookCenteredTime, "", x148_freeLookCenteredTime, skDefaultFlags); - CREATE_CVAR(FreeLookDampenFactor, "", x14c_freeLookDampenFactor, skDefaultFlags); - CREATE_CVAR(LeftDivisor, "", x150_leftDiv, skDefaultFlags); - CREATE_CVAR(RightDivisor, "", x154_rightDiv, skDefaultFlags); - CREATE_CVAR(OrbitMinDistanceClose, "", x158_orbitMinDistance[0], skDefaultFlags); - CREATE_CVAR(OrbitMinDistanceFar, "", x158_orbitMinDistance[1], skDefaultFlags); - CREATE_CVAR(OrbitMinDistanceDefault, "", x158_orbitMinDistance[2], skDefaultFlags); - CREATE_CVAR(OrbitNormalDistanceClose, "", x164_orbitNormalDistance[0], skDefaultFlags); - CREATE_CVAR(OrbitNormalDistanceFar, "", x164_orbitNormalDistance[1], skDefaultFlags); - CREATE_CVAR(OrbitNormalDistanceDefault, "", x164_orbitNormalDistance[2], skDefaultFlags); - CREATE_CVAR(OrbitMaxDistanceClose, "", x170_orbitMaxDistance[0], skDefaultFlags); - CREATE_CVAR(OrbitMaxDistanceFar, "", x170_orbitMaxDistance[1], skDefaultFlags); - CREATE_CVAR(OrbitMaxDistanceDefault, "", x170_orbitMaxDistance[2], skDefaultFlags); - // CREATE_CVAR(); // x17c_ - CREATE_CVAR(OrbitmodeTimer, "", x180_orbitModeTimer, skDefaultFlags); - CREATE_CVAR(OrbitCameraSpeed, "", x184_orbitCameraSpeed, skDefaultFlags); - CREATE_CVAR(OrbitUpperAngle, "", x184_orbitCameraSpeed, skDefaultFlags); - CREATE_CVAR(OrbitLowerAngle, "", x184_orbitCameraSpeed, skDefaultFlags); - CREATE_CVAR(OrbitHorizontalAngle, "", x184_orbitCameraSpeed, skDefaultFlags); - // CREATE_CVAR(); // x194_ - // CREATE_CVAR(); // x198_ - CREATE_CVAR(OrbitMaxTargetDistance, "", x19c_orbitMaxTargetDistance, skDefaultFlags); - CREATE_CVAR(OrbitMaxLockDistance, "", x1a0_orbitMaxLockDistance, skDefaultFlags); - CREATE_CVAR(OrbitDistanceThreshold, "", x1a4_orbitDistanceThreshold, skDefaultFlags); - CREATE_CVAR(OrbitScreenTargetingBoxHalfExtentX, "", x1a8_orbitScreenBoxHalfExtentX[0], skDefaultFlags); - CREATE_CVAR(OrbitScreenScanBoxHalfExtentX, "", x1a8_orbitScreenBoxHalfExtentX[1], skDefaultFlags); - CREATE_CVAR(OrbitScreenTargetingBoxHalfExtentY, "", x1b0_orbitScreenBoxHalfExtentY[0], skDefaultFlags); - CREATE_CVAR(OrbitScreenScanBoxHalfExtentY, "", x1b0_orbitScreenBoxHalfExtentY[1], skDefaultFlags); - CREATE_CVAR(OrbitScreenTargetingBoxCenterX, "", x1b8_orbitScreenBoxCenterX[0], skDefaultFlags); - CREATE_CVAR(OrbitScreenScanBoxCenterX, "", x1b8_orbitScreenBoxCenterX[1], skDefaultFlags); - CREATE_CVAR(OrbitScreenTargetingBoxCenterY, "", x1c0_orbitScreenBoxCenterY[0], skDefaultFlags); - CREATE_CVAR(OrbitScreenScanBoxCenterY, "", x1c0_orbitScreenBoxCenterY[1], skDefaultFlags); - CREATE_CVAR(OrbitZoneTargetingIdealX, "", x1c8_orbitZoneIdealX[0], skDefaultFlags); - CREATE_CVAR(OrbitZoneScanIdealX, "", x1c8_orbitZoneIdealX[1], skDefaultFlags); - CREATE_CVAR(OrbitZoneTargetingIdealY, "", x1d0_orbitZoneIdealY[0], skDefaultFlags); - CREATE_CVAR(OrbitZoneScanIdealY, "", x1d0_orbitZoneIdealY[1], skDefaultFlags); - CREATE_CVAR(OrbitNearX, "", x1d8_orbitNearX, skDefaultFlags); - CREATE_CVAR(OrbitNearZ, "", x1dc_orbitNearZ, skDefaultFlags); - // CREATE_CVAR(); // x1e0_ - // CREATE_CVAR(); // x1e4_ - CREATE_CVAR(OrbitFixedOffsetZDiff, "", x1e8_orbitFixedOffsetZDiff, skDefaultFlags); - CREATE_CVAR(OrbitZRange, "", x1ec_orbitZRange, skDefaultFlags); - // CREATE_CVAR(); // x1f0_ - // CREATE_CVAR(); // x1f4_ - // CREATE_CVAR(); // x1f8_ - CREATE_CVAR(OrbitPreventionTime, "", x1fc_orbitPreventionTime, skDefaultFlags); - CREATE_CVAR_BITFIELD(DashEnabled, "", x200_24_dashEnabled, skDefaultFlags); - CREATE_CVAR_BITFIELD(DashOnButtonRelease, "", x200_25_dashOnButtonRelease, skDefaultFlags); - CREATE_CVAR(DashButtonHoldCancelTime, "", x204_dashButtonHoldCancelTime, skDefaultFlags); - CREATE_CVAR(DashStrafeInputThreshold, "", x208_dashStrafeInputThreshold, skDefaultFlags); - CREATE_CVAR(SidewaysDoubleJumpImpulse, "", x20c_sidewaysDoubleJumpImpulse, skDefaultFlags); - CREATE_CVAR(SidewaysVerticalDoubleJumpAccel, "", x210_sidewaysVerticalDoubleJumpAccel, skDefaultFlags); - CREATE_CVAR(SidewaysHorizontalDoubleJumpAccel, "", x214_sidewaysHorizontalDoubleJumpAccel, skDefaultFlags); - CREATE_CVAR(ScanningRange, "", x218_scanningRange, skDefaultFlags); - CREATE_CVAR_BITFIELD(ScanRetention, "", x21c_24_scanRetention, skDefaultFlags); - CREATE_CVAR_BITFIELD(ScanFreezesGame, "", x21c_25_scanFreezesGame, skDefaultFlags); - CREATE_CVAR_BITFIELD(OrbitWhileScanning, "", x21c_26_orbitWhileScanning, skDefaultFlags); - CREATE_CVAR(ScanMaxTargetDistance, "", x220_scanMaxTargetDistance, skDefaultFlags); - CREATE_CVAR(ScanMaxLockDistance, "", x224_scanMaxLockDistance, skDefaultFlags); - CREATE_CVAR_BITFIELD(FreeLookTurnsPlayer, "", x228_24_freelookTurnsPlayer, skDefaultFlags); - // CREATE_CVAR_BITFIELD(); // x228_25_ - // CREATE_CVAR_BITFIELD(); // x228_26_ - CREATE_CVAR_BITFIELD(MoveDuringFreelook, "", x228_27_moveDuringFreeLook, skDefaultFlags); - CREATE_CVAR_BITFIELD(HoldButtonsForFreeLook, "", x228_28_holdButtonsForFreeLook, skDefaultFlags); - // CREATE_CVAR_BITFIELD(); // x228_30_ - // CREATE_CVAR_BITFIELD(); // x228_31_ - // CREATE_CVAR(); // x229_24_ - CREATE_CVAR_BITFIELD(AimWhenOrbitingPoint, "", x229_25_aimWhenOrbitingPoint, skDefaultFlags); - CREATE_CVAR_BITFIELD(StayInFreeLookWhileFiring, "", x229_26_stayInFreeLookWhileFiring, skDefaultFlags); - // CREATE_CVAR_BITFIELD(); // x229_27_ - // CREATE_CVAR_BITFIELD(); // x229_28_ - CREATE_CVAR_BITFIELD(OrbitFixedOffset, "", x229_29_orbitFixedOffset, skDefaultFlags); - CREATE_CVAR_BITFIELD(GunButtonTogglesHolster, "", x229_30_gunButtonTogglesHolster, skDefaultFlags); - CREATE_CVAR_BITFIELD(GunNotFiringHolstersGun, "", x229_31_gunNotFiringHolstersGun, skDefaultFlags); - CREATE_CVAR_BITFIELD(FallingDoubleJump, "", x22a_24_fallingDoubleJump, skDefaultFlags); - CREATE_CVAR_BITFIELD(ImpulseDoubleJump, "", x22a_25_impulseDoubleJump, skDefaultFlags); - CREATE_CVAR_BITFIELD(FiringCancelsCameraPitch, "", x22a_26_firingCancelsCameraPitch, skDefaultFlags); - CREATE_CVAR_BITFIELD(AssistedAimingIgnoreHorizontal, "", x22a_27_assistedAimingIgnoreHorizontal, skDefaultFlags); - CREATE_CVAR_BITFIELD(AssistedAimingIgnoreVertical, "", x22a_28_assistedAimingIgnoreVertical, skDefaultFlags); - // CREATE_CVAR(); // x22c - // CREATE_CVAR(); // x230_ - CREATE_CVAR(AimMaxDistance, "", x234_aimMaxDistance, skDefaultFlags); - // CREATE_CVAR(); // x238_ - // CREATE_CVAR(); // x23c_ - // CREATE_CVAR(); // x240_ - // CREATE_CVAR(); // x244_ - // CREATE_CVAR(); // x248_ - CREATE_CVAR(AimThresholdDistance, "", x24c_aimThresholdDistance, skDefaultFlags); - // CREATE_CVAR(); // x250_ - // CREATE_CVAR(); // x254_ - CREATE_CVAR(AimBoxWidth, "", x258_aimBoxWidth, skDefaultFlags); - CREATE_CVAR(AimBoxHeight, "", x25c_aimBoxHeight, skDefaultFlags); - CREATE_CVAR(AimTargetTimer, "", x260_aimTargetTimer, skDefaultFlags); - CREATE_CVAR(AimAssistHorizontalAngle, "", x264_aimAssistHorizontalAngle, skDefaultFlags); - CREATE_CVAR(AimAssistVerticalAngle, "", x268_aimAssistVerticalAngle, skDefaultFlags); - CREATE_CVAR(PlayerHeight, "", x26c_playerHeight, skDefaultFlags); - CREATE_CVAR(PlayerXYHalfExtent, "", x270_playerXYHalfExtent, skDefaultFlags); - CREATE_CVAR(StepUpHeight, "", x274_stepUpHeight, skDefaultFlags); - CREATE_CVAR(StepDownHeight, "", x278_stepDownHeight, skDefaultFlags); - CREATE_CVAR(PlayerBallHalfExtent, "", x27c_playerBallHalfExtent, skDefaultFlags); - CREATE_CVAR(FirstPersonCameraSpeed, "", x280_firstPersonCameraSpeed, skDefaultFlags); - // CREATE_CVAR(); // x284_ - CREATE_CVAR(JumpCameraPitchDownStart, "", x288_jumpCameraPitchDownStart, skDefaultFlags); - CREATE_CVAR(JumpCameraPitchDownFull, "", x28c_jumpCameraPitchDownFull, skDefaultFlags); - CREATE_CVAR(JumpCameraPitchDownAngle, "", x290_jumpCameraPitchDownAngle, skDefaultFlags); - CREATE_CVAR(FallCameraPitchDownStart, "", x294_fallCameraPitchDownStart, skDefaultFlags); - CREATE_CVAR(FallCameraPitchDownFull, "", x298_fallCameraPitchDownFull, skDefaultFlags); - CREATE_CVAR(FallCameraPitchDownAngle, "", x29c_fallCameraPitchDownAngle, skDefaultFlags); - CREATE_CVAR(OrbitDistanceMax, "", x2a0_orbitDistanceMax, skDefaultFlags); - CREATE_CVAR(GrappleSwingLength, "", x2a4_grappleSwingLength, skDefaultFlags); - CREATE_CVAR(GrappleSwingPeriod, "", x2a8_grappleSwingPeriod, skDefaultFlags); - CREATE_CVAR(GrapplePullSpeedMin, "", x2ac_grapplePullSpeedMin, skDefaultFlags); - CREATE_CVAR(GrappleCameraSpeed, "", x2b0_grappleCameraSpeed, skDefaultFlags); - CREATE_CVAR(MaxGrappleLockedTurnAlignDistance, "", x2b4_maxGrappleLockedTurnAlignDistance, skDefaultFlags); - CREATE_CVAR(GrapplePullSpeedProportion, "", x2b8_grapplePullSpeedProportion, skDefaultFlags); - CREATE_CVAR(GrapplePullSpeedMax, "", x2bc_grapplePullSpeedMax, skDefaultFlags); - CREATE_CVAR(GrappleLookCenterSpeed, "", x2c0_grappleLookCenterSpeed, skDefaultFlags); - CREATE_CVAR(MaxGrappleTurnSpeed, "", x2c4_maxGrappleTurnSpeed, skDefaultFlags); - CREATE_CVAR(GrappleJumpForce, "", x2c8_grappleJumpForce, skDefaultFlags); - CREATE_CVAR(GrappleReleaseTime, "", x2cc_grappleReleaseTime, skDefaultFlags); - CREATE_CVAR(GrappleJumpMode, "", x2d0_grappleJumpMode, skDefaultFlags); - CREATE_CVAR(OrbitReleaseBreaksGrapple, "", x2d4_orbitReleaseBreaksGrapple, skDefaultFlags); - CREATE_CVAR(InvertGrappleTurn, "", x2d5_invertGrappleTurn, skDefaultFlags); - CREATE_CVAR(GrappleBeamSpeed, "", x2d8_grappleBeamSpeed, skDefaultFlags); - CREATE_CVAR(GrappleBeamXWaveAmplitude, "", x2dc_grappleBeamXWaveAmplitude, skDefaultFlags); - CREATE_CVAR(GrappleBeamZWaveAmplitude, "", x2e0_grappleBeamZWaveAmplitude, skDefaultFlags); - CREATE_CVAR(GrappleBeamAnglePhaseDelta, "", x2e4_grappleBeamAnglePhaseDelta, skDefaultFlags); - // CREATE_CVAR(); // x2e8_ - // CREATE_CVAR(); // x2ec_ - // CREATE_CVAR(); // x2f0_ - // CREATE_CVAR(); // x2f4_ - CREATE_CVAR(FrozenTimeout, "", x2f8_frozenTimeout, skDefaultFlags); - CREATE_CVAR(IceBreakJumpCount, "", x2fc_iceBreakJumpCount, skDefaultFlags); - CREATE_CVAR(VariaDamageReduction, "", x300_variaDamageReduction, skDefaultFlags); - CREATE_CVAR(GravityDamageReduction, "", x304_gravityDamageReduction, skDefaultFlags); - CREATE_CVAR(PhazonDamageReduction, "", x308_phazonDamageReduction, skDefaultFlags); -} -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp b/DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp deleted file mode 100644 index 8488bcaaf..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakPlayerControl.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakPlayerControl final : ITweakPlayerControl { - AT_DECL_DNA_YAML - Vector m_mappings; - atUint32 GetMapping(atUint32 command) const override { return m_mappings[command]; } - CTweakPlayerControl() = default; - CTweakPlayerControl(athena::io::IStreamReader& reader) { this->read(reader); } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakSlideShow.hpp b/DataSpec/DNAMP1/Tweaks/CTweakSlideShow.hpp deleted file mode 100644 index 40fa76a98..000000000 --- a/DataSpec/DNAMP1/Tweaks/CTweakSlideShow.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include "../../DNACommon/Tweaks/ITweakSlideShow.hpp" -#include "zeus/CColor.hpp" - -namespace DataSpec::DNAMP1 { - -struct CTweakSlideShow final : ITweakSlideShow { - AT_DECL_DNA_YAML - - String<-1> x4_pakName; - String<-1> x14_fontAssetName; - DNAColor x24_fontColor; - DNAColor x28_outlineColor; - Value x2c_scanPercentInterval; - Value x30_; - Value x34_; - Value x38_; - Value x3c_; - DNAColor x40_; - Value x44_; - Value x48_; - Value x4c_; - Value x50_; - Value x54_; - Value x58_; - - CTweakSlideShow() = default; - CTweakSlideShow(athena::io::IStreamReader& in) { read(in); } - - std::string_view GetFont() const override { return x14_fontAssetName; } - const zeus::CColor& GetFontColor() const override { return x24_fontColor; } - const zeus::CColor& GetOutlineColor() const override { return x28_outlineColor; } - float GetScanPercentInterval() const override { return x2c_scanPercentInterval; } - float GetX54() const override { return x54_; } -}; - -} // namespace DataSpec::DNAMP1 diff --git a/DataSpec/DNAMP1/Tweaks/CTweakTargeting.cpp b/DataSpec/DNAMP1/Tweaks/CTweakTargeting.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/DataSpec/DNAMP2/AFSM.hpp b/DataSpec/DNAMP2/AFSM.hpp deleted file mode 100644 index 174b89611..000000000 --- a/DataSpec/DNAMP2/AFSM.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "../DNAMP1/AFSM.hpp" - -namespace DataSpec::DNAMP2 { -using AFSM = DNAMP1::AFSM; -} diff --git a/DataSpec/DNAMP2/AGSC.cpp b/DataSpec/DNAMP2/AGSC.cpp deleted file mode 100644 index a0c6496b6..000000000 --- a/DataSpec/DNAMP2/AGSC.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include "AGSC.hpp" -#include "amuse/AudioGroup.hpp" -#include "amuse/AudioGroupData.hpp" - -namespace DataSpec::DNAMP2 { - -bool AGSC::Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& dir) { - dir.makeDirChain(true); - - Header head; - head.read(rs); - - auto pool = rs.readUBytes(head.poolSz); - auto proj = rs.readUBytes(head.projSz); - auto sdir = rs.readUBytes(head.sdirSz); - auto samp = rs.readUBytes(head.sampSz); - - amuse::AudioGroupData data(proj.get(), head.projSz, pool.get(), head.poolSz, sdir.get(), head.sdirSz, samp.get(), - head.sampSz, amuse::GCNDataTag{}); - - /* Load into amuse representation */ - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - amuse::AudioGroupDatabase group(data); - group.setGroupPath(dir.getAbsolutePath()); - - /* Extract samples */ - group.getSdir().extractAllCompressed(dir.getAbsolutePath(), data.getSamp()); - - /* Write out project/pool */ - { - auto projd = group.getProj().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!project.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(projd.data(), projd.size()); - } - - { - auto poold = group.getPool().toYAML(); - athena::io::FileWriter fo(hecl::ProjectPath(dir, "!pool.yaml").getAbsolutePath()); - if (fo.hasError()) - return false; - fo.writeUBytes(poold.data(), poold.size()); - } - - return true; -} - -bool AGSC::Cook(const hecl::ProjectPath& dir, const hecl::ProjectPath& outPath) { - athena::io::FileWriter w(outPath.getAbsolutePath()); - if (w.hasError()) - return false; - - amuse::ProjectDatabase projDb; - projDb.setIdDatabases(); - amuse::AudioGroupDatabase group(dir.getAbsolutePath()); - - auto proj = group.getProj().toGCNData(group.getPool(), group.getSdir()); - auto pool = group.getPool().toData(); - auto sdirSamp = group.getSdir().toGCNData(group); - - Header head; - head.groupName = dir.getLastComponent(); - for (const auto& p : group.getProj().sfxGroups()) - head.groupId = p.first.id; - head.poolSz = pool.size(); - head.projSz = proj.size(); - head.sdirSz = sdirSamp.first.size(); - head.sampSz = sdirSamp.second.size(); - head.write(w); - - w.writeUBytes(pool.data(), pool.size()); - w.writeUBytes(proj.data(), proj.size()); - w.writeUBytes(sdirSamp.first.data(), sdirSamp.first.size()); - w.writeUBytes(sdirSamp.second.data(), sdirSamp.second.size()); - - return true; -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/AGSC.hpp b/DataSpec/DNAMP2/AGSC.hpp deleted file mode 100644 index 215b44126..000000000 --- a/DataSpec/DNAMP2/AGSC.hpp +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -class AGSC { -public: - struct Header : BigDNA { - AT_DECL_DNA - Value unk; - String<-1> groupName; - Value groupId = -1; - Value poolSz = 0; - Value projSz = 0; - Value sdirSz = 0; - Value sampSz = 0; - }; - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath); - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANCS.cpp b/DataSpec/DNAMP2/ANCS.cpp deleted file mode 100644 index b03a7ec70..000000000 --- a/DataSpec/DNAMP2/ANCS.cpp +++ /dev/null @@ -1,545 +0,0 @@ -#include "ANCS.hpp" - -namespace DataSpec::DNAMP2 { - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename Read::StreamT& reader) { - idx = reader.readUint32Big(); - atUint16 sectionCount = reader.readUint16Big(); - name = reader.readString(); - cmdl.read(reader); - cskr.read(reader); - cinf.read(reader); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - pasDatabase.read(reader); - - atUint32 partCount = reader.readUint32Big(); - reader.enumerate(partResData.part, partCount); - - atUint32 swhcCount = reader.readUint32Big(); - reader.enumerate(partResData.swhc, swhcCount); - - atUint32 unkCount = reader.readUint32Big(); - reader.enumerate(partResData.unk, unkCount); - - atUint32 elscCount = reader.readUint32Big(); - reader.enumerate(partResData.elsc, elscCount); - - atUint32 spscCount = reader.readUint32Big(); - reader.enumerate(partResData.spsc, spscCount); - - atUint32 unkCount2 = reader.readUint32Big(); - if (unkCount2) - abort(); - reader.enumerate(partResData.unk2, unkCount2); - - unk1 = reader.readUint32Big(); - - animAABBs.clear(); - if (sectionCount > 1) { - atUint32 aabbCount = reader.readUint32Big(); - reader.enumerate(animAABBs, aabbCount); - } - - effects.clear(); - if (sectionCount > 2) { - atUint32 effectCount = reader.readUint32Big(); - reader.enumerate(effects, effectCount); - } - - if (sectionCount > 3) { - cmdlIce.read(reader); - cskrIce.read(reader); - } - - animIdxs.clear(); - if (sectionCount > 4) { - atUint32 aidxCount = reader.readUint32Big(); - reader.enumerateBig(animIdxs, aidxCount); - } - - extents.clear(); - if (sectionCount > 9) { - unk4 = reader.readUint32Big(); - unk5 = reader.readUByte(); - atUint32 extentsCount = reader.readUint32Big(); - reader.enumerate(extents, extentsCount); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(idx); - - atUint16 sectionCount; - if (unk4 || unk5 || extents.size()) - sectionCount = 10; - else if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16Big(sectionCount); - - writer.writeString(name); - cmdl.write(writer); - cskr.write(writer); - cinf.write(writer); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - pasDatabase.write(writer); - - writer.writeUint32Big(partResData.part.size()); - writer.enumerate(partResData.part); - - writer.writeUint32Big(partResData.swhc.size()); - writer.enumerate(partResData.swhc); - - writer.writeUint32Big(partResData.unk.size()); - writer.enumerate(partResData.unk); - - writer.writeUint32Big(partResData.elsc.size()); - writer.enumerate(partResData.elsc); - - writer.writeUint32Big(partResData.spsc.size()); - writer.enumerate(partResData.spsc); - - writer.writeUint32Big(partResData.unk2.size()); - writer.enumerate(partResData.unk2); - - writer.writeUint32Big(unk1); - - if (sectionCount > 1) { - writer.writeUint32Big(animAABBs.size()); - writer.enumerate(animAABBs); - } - - if (sectionCount > 2) { - writer.writeUint32Big(effects.size()); - writer.enumerate(effects); - } - - if (sectionCount > 3) { - cmdlIce.write(writer); - cskrIce.write(writer); - } - - if (sectionCount > 4) { - writer.writeUint32Big(animIdxs.size()); - for (atUint32 idx : animIdxs) - writer.writeUint32Big(idx); - } - - if (sectionCount > 9) { - writer.writeUint32Big(unk4); - writer.writeUByte(unk5); - writer.writeUint32Big(extents.size()); - writer.enumerate(extents); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename BinarySize::StreamT& s) { - atUint16 sectionCount; - if (unk4 || unk5 || extents.size()) - sectionCount = 10; - else if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - - s += 6; - - s += name.size() + 1; - s += 12; - - s += 4; - for (const Animation& anim : animations) - anim.binarySize(s); - - pasDatabase.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.part) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.swhc) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.unk) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.elsc) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.spsc) - id.binarySize(s); - - s += 4; - for (const UniqueID32& id : partResData.unk2) - id.binarySize(s); - - s += 4; - - if (sectionCount > 1) { - s += 4; - for (const MP1CharacterInfo::ActionAABB& aabb : animAABBs) - aabb.binarySize(s); - } - - if (sectionCount > 2) { - s += 4; - for (const Effect& e : effects) - e.binarySize(s); - } - - if (sectionCount > 3) - s += 8; - - if (sectionCount > 4) - s += 4 + animIdxs.size() * 4; - - if (sectionCount > 9) { - s += 9; - for (const Extents& e : extents) - e.binarySize(s); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename ReadYaml::StreamT& reader) { - idx = reader.readUint32("idx"); - atUint16 sectionCount = reader.readUint16("sectionCount"); - name = reader.readString("name"); - - reader.enumerate("animations", animations); - - reader.enumerate("pasDatabase", pasDatabase); - - reader.enumerate("part", partResData.part); - - reader.enumerate("swhc", partResData.swhc); - - reader.enumerate("unk", partResData.unk); - - reader.enumerate("elsc", partResData.elsc); - - reader.enumerate("spsc", partResData.spsc); - - reader.enumerate("unk2", partResData.unk2); - - unk1 = reader.readUint32("unk1"); - - animAABBs.clear(); - if (sectionCount > 1) { - reader.enumerate("part", animAABBs); - } - - effects.clear(); - if (sectionCount > 2) { - reader.enumerate("effects", effects); - } - - if (sectionCount > 3) { - reader.enumerate("cmdlIce", cmdlIce); - } - - animIdxs.clear(); - if (sectionCount > 4) { - reader.enumerate("animIdxs", animIdxs); - } - - extents.clear(); - if (sectionCount > 9) { - unk4 = reader.readUint32("unk4"); - unk5 = reader.readUByte("unk5"); - reader.enumerate("extents", extents); - } -} - -template <> -void ANCS::CharacterSet::CharacterInfo::Enumerate(typename WriteYaml::StreamT& writer) { - writer.writeUint32("idx", idx); - - atUint16 sectionCount; - if (unk4 || unk5 || extents.size()) - sectionCount = 10; - else if (partResData.elsc.size()) - sectionCount = 6; - else if (animIdxs.size()) - sectionCount = 5; - else if (cmdlIce.isValid()) - sectionCount = 4; - else if (effects.size()) - sectionCount = 3; - else if (animAABBs.size()) - sectionCount = 2; - else - sectionCount = 1; - writer.writeUint16("sectionCount", sectionCount); - - writer.writeString("name", name); - writer.enumerate("cmdl", cmdl); - - writer.enumerate("animations", animations); - - writer.enumerate("pasDatabase", pasDatabase); - - writer.enumerate("part", partResData.part); - - writer.enumerate("swhc", partResData.swhc); - - writer.enumerate("unk", partResData.unk); - - writer.enumerate("elsc", partResData.elsc); - - writer.enumerate("spsc", partResData.spsc); - - writer.enumerate("unk2", partResData.unk2); - - writer.writeUint32("unk1", unk1); - - if (sectionCount > 1) { - writer.enumerate("animAABBs", animAABBs); - } - - if (sectionCount > 2) { - writer.enumerate("effects", effects); - } - - if (sectionCount > 3) { - writer.enumerate("cmdlIce", cmdlIce); - } - - if (sectionCount > 4) { - writer.enumerate("animIdxs", animIdxs); - } - - if (sectionCount > 9) { - writer.writeUint32("unk4", unk4); - writer.writeUByte("unk5", unk5); - writer.enumerate("extents", extents); - } -} - -std::string_view ANCS::CharacterSet::CharacterInfo::DNAType() { return "DNAMP2::ANCS::CharacterSet::CharacterInfo"sv; } - -template <> -void ANCS::AnimationSet::Enumerate(typename Read::StreamT& reader) { - atUint16 sectionCount = reader.readUint16Big(); - - atUint32 animationCount = reader.readUint32Big(); - reader.enumerate(animations, animationCount); - - atUint32 transitionCount = reader.readUint32Big(); - reader.enumerate(transitions, transitionCount); - defaultTransition.read(reader); - - additiveAnims.clear(); - if (sectionCount > 1) { - atUint32 additiveAnimCount = reader.readUint32Big(); - reader.enumerate(additiveAnims, additiveAnimCount); - additiveDefaultFadeInDur = reader.readFloatBig(); - additiveDefaultFadeOutDur = reader.readFloatBig(); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - atUint32 halfTransitionCount = reader.readUint32Big(); - reader.enumerate(halfTransitions, halfTransitionCount); - } - - evnts.clear(); - if (sectionCount > 3) { - atUint32 evntsCount = reader.readUint32Big(); - reader.enumerate(evnts, evntsCount); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename Write::StreamT& writer) { - atUint16 sectionCount; - if (evnts.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16Big(sectionCount); - - writer.writeUint32Big(animations.size()); - writer.enumerate(animations); - - writer.writeUint32Big(transitions.size()); - writer.enumerate(transitions); - defaultTransition.write(writer); - - if (sectionCount > 1) { - writer.writeUint32Big(additiveAnims.size()); - writer.enumerate(additiveAnims); - writer.writeFloatBig(additiveDefaultFadeInDur); - writer.writeFloatBig(additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.writeUint32Big(halfTransitions.size()); - writer.enumerate(halfTransitions); - } - - if (sectionCount > 3) { - writer.writeUint32Big(evnts.size()); - writer.enumerate(evnts); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename BinarySize::StreamT& s) { - atUint16 sectionCount; - if (evnts.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - s += 6; - for (const MP1AnimationSet::Animation& anim : animations) - anim.binarySize(s); - - s += 4; - for (const MP1AnimationSet::Transition& trans : transitions) - trans.binarySize(s); - defaultTransition.binarySize(s); - - if (sectionCount > 1) { - s += 4; - for (const MP1AnimationSet::AdditiveAnimationInfo& aaInfo : additiveAnims) - aaInfo.binarySize(s); - s += 8; - } - - if (sectionCount > 2) { - s += 4; - for (const MP1AnimationSet::HalfTransition& ht : halfTransitions) - ht.binarySize(s); - } - - if (sectionCount > 3) { - s += 4; - for (const EVNT& evnt : evnts) - evnt.binarySize(s); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename ReadYaml::StreamT& reader) { - atUint16 sectionCount = reader.readUint16("sectionCount"); - - reader.enumerate("animations", animations); - - reader.enumerate("transitions", transitions); - reader.enumerate("defaultTransition", defaultTransition); - - additiveAnims.clear(); - if (sectionCount > 1) { - reader.enumerate("additiveAnims", additiveAnims); - additiveDefaultFadeInDur = reader.readFloat("additiveDefaultFadeInDur"); - additiveDefaultFadeOutDur = reader.readFloat("additiveDefaultFadeOutDur"); - } - - halfTransitions.clear(); - if (sectionCount > 2) { - reader.enumerate("halfTransitions", halfTransitions); - } - - evnts.clear(); - if (sectionCount > 3) { - reader.enumerate("evnts", evnts); - } -} - -template <> -void ANCS::AnimationSet::Enumerate(typename WriteYaml::StreamT& writer) { - atUint16 sectionCount; - if (evnts.size()) - sectionCount = 4; - else if (halfTransitions.size()) - sectionCount = 3; - else if (additiveAnims.size()) - sectionCount = 2; - else - sectionCount = 1; - - writer.writeUint16("sectionCount", sectionCount); - - writer.enumerate("animations", animations); - - writer.enumerate("transitions", transitions); - writer.enumerate("defaultTransition", defaultTransition); - - if (sectionCount > 1) { - writer.enumerate("additiveAnims", additiveAnims); - writer.writeFloat("additiveDefaultFadeInDur", additiveDefaultFadeInDur); - writer.writeFloat("additiveDefaultFadeOutDur", additiveDefaultFadeOutDur); - } - - if (sectionCount > 2) { - writer.enumerate("halfTransitions", halfTransitions); - } - - if (sectionCount > 3) { - writer.enumerate("evnts", evnts); - } -} - -std::string_view ANCS::AnimationSet::DNAType() { return "DNAMP2::ANCS::AnimationSet"sv; } - -template -void ANCS::AnimationSet::EVNT::Enumerate(typename Op::StreamT& s) { - Do(athena::io::PropId{"version"}, version, s); - DoSize(athena::io::PropId{"loopEventCount"}, loopEventCount, s); - Do(athena::io::PropId{"loopEvents"}, loopEvents, loopEventCount, s); - if (version == 2) { - DoSize(athena::io::PropId{"uevtEventCount"}, uevtEventCount, s); - Do(athena::io::PropId{"uevtEvents"}, uevtEvents, uevtEventCount, s); - } - DoSize(athena::io::PropId{"effectEventCount"}, effectEventCount, s); - Do(athena::io::PropId{"effectEvents"}, effectEvents, effectEventCount, s); - DoSize(athena::io::PropId{"sfxEventCount"}, sfxEventCount, s); - Do(athena::io::PropId{"sfxEvents"}, sfxEvents, sfxEventCount, s); -} - -AT_SPECIALIZE_DNA(ANCS::AnimationSet::EVNT) - -std::string_view ANCS::AnimationSet::EVNT::DNAType() { return "DNAMP2::ANCS::AnimationSet::EVNT"sv; } - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANCS.hpp b/DataSpec/DNAMP2/ANCS.hpp deleted file mode 100644 index 35c15309f..000000000 --- a/DataSpec/DNAMP2/ANCS.hpp +++ /dev/null @@ -1,227 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" -#include "CMDLMaterials.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" -#include "ANIM.hpp" -#include "../DNAMP1/ANCS.hpp" - -namespace DataSpec::DNAMP2 { - -struct ANCS : BigDNA { - using CINFType = CINF; - using CSKRType = CSKR; - using ANIMType = ANIM; - - AT_DECL_DNA_YAML - Value version; - - struct CharacterSet : BigDNA { - AT_DECL_DNA_YAML - Value version; - Value characterCount; - struct CharacterInfo : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo; - - atUint32 idx; - std::string name; - UniqueID32 cmdl; - UniqueID32 cskr; - UniqueID32 cinf; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - String<-1> strA; - }; - std::vector animations; - - MP1CharacterInfo::PASDatabase pasDatabase; - struct ParticleResData { - std::vector part; - std::vector swhc; - std::vector unk; - std::vector elsc; - std::vector spsc; - std::vector unk2; - } partResData; - - atUint32 unk1 = 0; - - std::vector animAABBs; - - struct Effect : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value compCount; - struct EffectComponent : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - DNAFourCC type; - UniqueID32 id; - Value unkMP2; - Value unk1; - Value unk2; - Value unk3; - }; - Vector comps; - }; - std::vector effects; - - UniqueID32 cmdlIce; - UniqueID32 cskrIce; - - std::vector animIdxs; - - atUint32 unk4; - atUint8 unk5; - - struct Extents : BigDNA { - AT_DECL_DNA_YAML - Value animIdx; - Value aabb[2]; - }; - std::vector extents; - }; - Vector characters; - } characterSet; - - struct AnimationSet : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - - using MP1AnimationSet = DNAMP1::ANCS::AnimationSet; - - std::vector animations; - - std::vector transitions; - MP1AnimationSet::MetaTransFactory defaultTransition; - - std::vector additiveAnims; - - float additiveDefaultFadeInDur = 0.0; - float additiveDefaultFadeOutDur = 0.0; - - std::vector halfTransitions; - - struct EVNT : BigDNA { - AT_DECL_EXPLICIT_DNA_YAML - atUint32 version; - - struct EventBase : BigDNA { - AT_DECL_DNA_YAML - Value unk0; - String<-1> name; - Value type; - Value startTime; - Value unk1; - Value idx; - Value unk2; - Value unk3; - Value unk4; - Value unk5; - }; - - struct LoopEvent : EventBase { - AT_DECL_DNA_YAML - Value flag; - }; - Value loopEventCount; - Vector loopEvents; - - struct UEVTEvent : EventBase { - AT_DECL_DNA_YAML - Value uevtType; - String<-1> boneName; - }; - Value uevtEventCount; - Vector uevtEvents; - - struct EffectEvent : EventBase { - AT_DECL_DNA_YAML - Value frameCount; - DNAFourCC effectType; - UniqueID32 effectId; - Value boneId; - Value scale; - Value parentMode; - }; - Value effectEventCount; - Vector effectEvents; - - struct SFXEvent : EventBase { - AT_DECL_DNA_YAML - Value soundId; - Value smallNum; - Value bigNum; - Value sfxUnk1; - Value sfxUnk2; - Value sfxUnk3; - Value sfxUnk4; - }; - Value sfxEventCount; - Vector sfxEvents; - }; - std::vector evnts; - } animationSet; - - void getCharacterResInfo(std::vector>& out) const { - out.clear(); - out.reserve(characterSet.characters.size()); - for (const CharacterSet::CharacterInfo& ci : characterSet.characters) { - out.emplace_back(); - DNAANCS::CharacterResInfo& chOut = out.back(); - chOut.name = ci.name; - chOut.cmdl = ci.cmdl; - chOut.cskr = ci.cskr; - chOut.cinf = ci.cinf; - - if (ci.cmdlIce.isValid()) - chOut.overlays.emplace_back("ICE", std::make_pair(ci.cmdlIce, ci.cskrIce)); - } - } - - void getAnimationResInfo(PAKRouter* pakRouter, - std::map>& out) const { - out.clear(); - for (const DNAMP1::ANCS::AnimationSet::Animation& ai : animationSet.animations) - ai.metaAnim.m_anim->gatherPrimitives(nullptr, out); - for (const DNAMP1::ANCS::AnimationSet::Transition& ti : animationSet.transitions) - if (ti.metaTrans.m_trans) - ti.metaTrans.m_trans->gatherPrimitives(nullptr, out); - if (animationSet.defaultTransition.m_trans) - animationSet.defaultTransition.m_trans->gatherPrimitives(nullptr, out); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - hecl::ProjectPath::Type blendType = blendPath.getPathType(); - - if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { - ANCS ancs; - ancs.read(rs); - - if (force || yamlType == hecl::ProjectPath::Type::None) { - athena::io::FileWriter writer(yamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(ancs, writer); - } - - if (force || blendType == hecl::ProjectPath::Type::None) { - DNAANCS::ReadANCSToBlender, ANCS, MaterialSet, DNACMDL::SurfaceHeader_2, 4>( - btok, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force); - } - } - - return true; - } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANIM.cpp b/DataSpec/DNAMP2/ANIM.cpp deleted file mode 100644 index e1aeda1cf..000000000 --- a/DataSpec/DNAMP2/ANIM.cpp +++ /dev/null @@ -1,577 +0,0 @@ -#include "ANIM.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -using ANIMOutStream = hecl::blender::ANIMOutStream; - -void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig) const { - os.format(FMT_STRING("act.hecl_fps = round({})\n" - "act.hecl_looping = {}\n"), - (1.0f / mainInterval), looping ? "True" : "False"); - - auto kit = chanKeys.begin(); - - std::vector fixedRotKeys; - std::vector fixedTransKeys; - - for (const std::pair>& bone : bones) { - const std::string* bName = rig.getCINF().getBoneNameFromId(bone.first); - if (!bName) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - continue; - } - - os.format(FMT_STRING("bone_string = '{}'\n"), *bName); - os << "action_group = act.groups.new(bone_string)\n" - "\n"; - - if (std::get<0>(bone.second)) - os << "rotCurves = []\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<1>(bone.second)) - os << "transCurves = []\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<2>(bone.second)) - os << "scaleCurves = []\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=0, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=1, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=2, " - "action_group=bone_string))\n" - "\n"; - - ANIMOutStream ao = os.beginANIMCurve(); - if (std::get<0>(bone.second)) { - const std::vector& rotKeys = *kit++; - fixedRotKeys.clear(); - fixedRotKeys.resize(rotKeys.size()); - - for (int c = 0; c < 4; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : rotKeys) - fixedRotKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CQuaternion& rot : fixedRotKeys) - rot = rig.invertRotation(bone.first, rot); - - for (int c = 0; c < 4; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Rotate, c, rotKeys.size()); - for (const zeus::CQuaternion& val : fixedRotKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<1>(bone.second)) { - const std::vector& transKeys = *kit++; - fixedTransKeys.clear(); - fixedTransKeys.resize(transKeys.size()); - - for (int c = 0; c < 3; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : transKeys) - fixedTransKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CVector3f& t : fixedTransKeys) - t = rig.invertPosition(bone.first, t, true); - - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Translate, c, fixedTransKeys.size()); - for (const zeus::CVector3f& val : fixedTransKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<2>(bone.second)) { - const std::vector& scaleKeys = *kit++; - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Scale, c, scaleKeys.size()); - for (const DNAANIM::Value& val : scaleKeys) - ao.write(*frameit++, val.simd[c]); - } - } - } -} - -template <> -void ANIM::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case 2: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("unrecognized ANIM version")); - break; - } -} - -template <> -void ANIM::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_anim->m_version); - m_anim->write(writer); -} - -template <> -void ANIM::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - m_anim->binarySize(s); -} - -std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; } - -template <> -void ANIM::ANIM0::Enumerate(typename Read::StreamT& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - - frames.clear(); - frames.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - frames.push_back(k); - - std::map boneMap; - for (size_t b = 0; b < head.boneSlotCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx == 0xff) - continue; - boneMap[idx] = b; - } - - atUint32 boneCount = reader.readUint32Big(); - bones.clear(); - bones.reserve(boneCount); - for (size_t b = 0; b < boneCount; ++b) { - bones.emplace_back(boneMap[b], std::make_tuple(false, false, false)); - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<0>(bones.back().second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<1>(bones[b].second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<2>(bones[b].second) = true; - } - - channels.clear(); - chanKeys.clear(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chanKeys.emplace_back(); - } - if (std::get<1>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chanKeys.emplace_back(); - } - if (std::get<2>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chanKeys.emplace_back(); - } - } - - reader.readUint32Big(); - auto kit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - } - - reader.readUint32Big(); - kit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec4fBig()); - } - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - } - - reader.readUint32Big(); - kit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - if (std::get<2>(bone.second)) - ++kit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(typename Write::StreamT& writer) { - Header head; - head.unk0 = 0; - head.unk1 = 0; - head.unk2 = 0; - head.keyCount = frames.size(); - head.duration = head.keyCount * mainInterval; - head.interval = mainInterval; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - head.boneSlotCount = maxId + 1; - head.write(writer); - - for (size_t s = 0; s < head.boneSlotCount; ++s) { - size_t boneIdx = 0; - bool found = false; - for (const std::pair>& bone : bones) { - if (s == bone.first) { - writer.writeUByte(boneIdx); - found = true; - break; - } - ++boneIdx; - } - if (!found) - writer.writeUByte(0xff); - } - - writer.writeUint32Big(bones.size()); - size_t boneIdx = 0; - size_t rotKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - writer.writeUByte(boneIdx); - ++rotKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t transKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<1>(bone.second)) { - writer.writeUByte(boneIdx); - ++transKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t scaleKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<2>(bone.second)) { - writer.writeUByte(boneIdx); - ++scaleKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(scaleKeyCount * head.keyCount); - auto cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - } - - writer.writeUint32Big(rotKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec4fBig(atVec4f{(*kit++).simd}); - } - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) - ++cit; - } - - writer.writeUint32Big(transKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - if (std::get<2>(bone.second)) - ++cit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(typename BinarySize::StreamT& s) { - Header head; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - - head.binarySize(s); - s += maxId + 1; - s += bones.size() * 3 + 12; - - s += 12; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - s += head.keyCount * 16; - if (std::get<1>(bone.second)) - s += head.keyCount * 12; - if (std::get<2>(bone.second)) - s += head.keyCount * 12; - } -} - -std::string_view ANIM::ANIM2::DNAType() { return "ANIM2"sv; } - -template <> -void ANIM::ANIM2::Enumerate(typename Read::StreamT& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - looping = bool(head.looping); - - WordBitmap keyBmp; - keyBmp.read(reader, head.keyBitmapBitCount); - frames.clear(); - atUint32 frameAccum = 0; - for (bool bit : keyBmp) { - if (bit) - frames.push_back(frameAccum); - ++frameAccum; - } - reader.seek(4); - - bones.clear(); - bones.reserve(head.boneChannelCount); - channels.clear(); - channels.reserve(head.boneChannelCount); - atUint16 keyframeCount = 0; - for (size_t b = 0; b < head.boneChannelCount; ++b) { - ChannelDesc desc; - desc.read(reader); - bones.emplace_back(desc.id, std::make_tuple(desc.keyCount1 != 0, desc.keyCount2 != 0, desc.keyCount3 != 0)); - - if (desc.keyCount1) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chan.i[0] = desc.initRX; - chan.q[0] = desc.qRX; - chan.i[1] = desc.initRY; - chan.q[1] = desc.qRY; - chan.i[2] = desc.initRZ; - chan.q[2] = desc.qRZ; - } - keyframeCount = std::max(keyframeCount, desc.keyCount1); - - if (desc.keyCount2) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.i[0] = desc.initTX; - chan.q[0] = desc.qTX; - chan.i[1] = desc.initTY; - chan.q[1] = desc.qTY; - chan.i[2] = desc.initTZ; - chan.q[2] = desc.qTZ; - } - keyframeCount = std::max(keyframeCount, desc.keyCount2); - - if (desc.keyCount3) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chan.i[0] = desc.initSX; - chan.q[0] = desc.qSX; - chan.i[1] = desc.initSY; - chan.q[1] = desc.qSY; - chan.i[2] = desc.initSZ; - chan.q[2] = desc.qSZ; - } - keyframeCount = std::max(keyframeCount, desc.keyCount3); - } - - size_t bsSize = DNAANIM::ComputeBitstreamSize(keyframeCount, channels); - std::unique_ptr bsData = reader.readUBytes(bsSize); - DNAANIM::BitstreamReader bsReader; - chanKeys = bsReader.read(bsData.get(), keyframeCount, channels, head.rotDiv, head.translationMult, head.scaleMult); -} - -template <> -void ANIM::ANIM2::Enumerate(typename Write::StreamT& writer) { - /* TODO: conform to MP1 ANIM3 */ - Header head; - head.unk1 = 1; - head.looping = looping; - head.interval = mainInterval; - head.rootBoneId = 0; - head.scaleMult = 0.f; - - WordBitmap keyBmp; - size_t frameCount = 0; - for (atUint32 frame : frames) { - while (keyBmp.getBit(frame)) - ++frame; - keyBmp.setBit(frame); - frameCount = frame + 1; - } - head.keyBitmapBitCount = keyBmp.getBitCount(); - head.duration = frameCount * mainInterval; - head.boneChannelCount = bones.size(); - - size_t keyframeCount = frames.size(); - std::vector qChannels = channels; - DNAANIM::BitstreamWriter bsWriter; - size_t bsSize; - std::unique_ptr bsData = - bsWriter.write(chanKeys, keyframeCount, qChannels, m_version == 3 ? 0x7fffff : 0x7fff, head.rotDiv, - head.translationMult, head.scaleMult, bsSize); - - /* TODO: Figure out proper scratch size computation */ - head.scratchSize = keyframeCount * channels.size() * 16; - - head.write(writer); - keyBmp.write(writer); - writer.writeUint32Big(head.boneChannelCount); - auto cit = qChannels.begin(); - for (const std::pair>& bone : bones) { - ChannelDesc desc; - if (std::get<0>(bone.second)) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount1 = keyframeCount; - desc.initRX = chan.i[0]; - desc.qRX = chan.q[0]; - desc.initRY = chan.i[1]; - desc.qRY = chan.q[1]; - desc.initRZ = chan.i[2]; - desc.qRZ = chan.q[2]; - } - if (std::get<1>(bone.second)) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount2 = keyframeCount; - desc.initTX = chan.i[0]; - desc.qTX = chan.q[0]; - desc.initTY = chan.i[1]; - desc.qTY = chan.q[1]; - desc.initTZ = chan.i[2]; - desc.qTZ = chan.q[2]; - } - if (std::get<2>(bone.second)) { - DNAANIM::Channel& chan = *cit++; - desc.keyCount3 = keyframeCount; - desc.initSX = chan.i[0]; - desc.qSX = chan.q[0]; - desc.initSY = chan.i[1]; - desc.qSY = chan.q[1]; - desc.initSZ = chan.i[2]; - desc.qSZ = chan.q[2]; - } - } - - writer.writeUBytes(bsData.get(), bsSize); -} - -template <> -void ANIM::ANIM2::Enumerate(typename BinarySize::StreamT& s) { - Header head; - - WordBitmap keyBmp; - for (atUint32 frame : frames) { - while (keyBmp.getBit(frame)) - ++frame; - keyBmp.setBit(frame); - } - - head.binarySize(s); - keyBmp.binarySize(s); - s += 4; - for (const std::pair>& bone : bones) { - s += 7; - if (std::get<0>(bone.second)) - s += 9; - if (std::get<1>(bone.second)) - s += 9; - if (std::get<2>(bone.second)) - s += 9; - } - - s += DNAANIM::ComputeBitstreamSize(frames.size(), channels); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ANIM.hpp b/DataSpec/DNAMP2/ANIM.hpp deleted file mode 100644 index df52dd46b..000000000 --- a/DataSpec/DNAMP2/ANIM.hpp +++ /dev/null @@ -1,173 +0,0 @@ -#pragma once - -#include "DNAMP2.hpp" -#include "DataSpec/DNACommon/ANIM.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "CINF.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" - -namespace DataSpec::DNAMP2 { - -struct ANIM : BigDNA { - AT_DECL_EXPLICIT_DNA - - struct IANIM : BigDNAV { - Delete expl; - atUint32 m_version; - IANIM(atUint32 version) : m_version(version) {} - - std::vector>> bones; - std::vector frames; - std::vector channels; - std::vector> chanKeys; - float mainInterval = 0.0; - bool looping = false; - - void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter& rig) const; - }; - - struct ANIM0 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM0() : IANIM(0) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value duration; - Value unk0; - Value interval; - Value unk1; - Value keyCount; - Value unk2; - Value boneSlotCount; - }; - }; - - struct ANIM2 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM2() : IANIM(2) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value scratchSize; - Value unk1; - Value duration; - Value interval; - Value rootBoneId = 3; - Value looping = 0; - Value rotDiv; - Value translationMult; - Value scaleMult; - Value boneChannelCount; - Value unk3 = 1; - Value keyBitmapBitCount; - }; - - struct ChannelDesc : BigDNA { - Delete expl; - Value id = 0; - Value keyCount1 = 0; - Value initRX = 0; - Value qRX = 0; - Value initRY = 0; - Value qRY = 0; - Value initRZ = 0; - Value qRZ = 0; - Value keyCount2 = 0; - Value initTX = 0; - Value qTX = 0; - Value initTY = 0; - Value qTY = 0; - Value initTZ = 0; - Value qTZ = 0; - Value keyCount3 = 0; - Value initSX = 0; - Value qSX = 0; - Value initSY = 0; - Value qSY = 0; - Value initSZ = 0; - Value qSZ = 0; - - void read(athena::io::IStreamReader& reader) { - id = reader.readUByte(); - keyCount1 = reader.readUint16Big(); - if (keyCount1) { - initRX = reader.readInt16Big(); - qRX = reader.readUByte(); - initRY = reader.readInt16Big(); - qRY = reader.readUByte(); - initRZ = reader.readInt16Big(); - qRZ = reader.readUByte(); - } - keyCount2 = reader.readUint16Big(); - if (keyCount2) { - initTX = reader.readInt16Big(); - qTX = reader.readUByte(); - initTY = reader.readInt16Big(); - qTY = reader.readUByte(); - initTZ = reader.readInt16Big(); - qTZ = reader.readUByte(); - } - keyCount3 = reader.readUint16Big(); - if (keyCount3) { - initSX = reader.readInt16Big(); - qSX = reader.readUByte(); - initSY = reader.readInt16Big(); - qSY = reader.readUByte(); - initSZ = reader.readInt16Big(); - qSZ = reader.readUByte(); - } - } - void write(athena::io::IStreamWriter& writer) const { - writer.writeUByte(id); - writer.writeUint16Big(keyCount1); - if (keyCount1) { - writer.writeInt16Big(initRX); - writer.writeUByte(qRX); - writer.writeInt16Big(initRY); - writer.writeUByte(qRY); - writer.writeInt16Big(initRZ); - writer.writeUByte(qRZ); - } - writer.writeUint16Big(keyCount2); - if (keyCount2) { - writer.writeInt16Big(initTX); - writer.writeUByte(qTX); - writer.writeInt16Big(initTY); - writer.writeUByte(qTY); - writer.writeInt16Big(initTZ); - writer.writeUByte(qTZ); - } - writer.writeUint16Big(keyCount3); - if (keyCount3) { - writer.writeInt16Big(initSX); - writer.writeUByte(qSX); - writer.writeInt16Big(initSY); - writer.writeUByte(qSY); - writer.writeInt16Big(initSZ); - writer.writeUByte(qSZ); - } - } - size_t binarySize(size_t __isz) const { - __isz += 7; - if (keyCount1) - __isz += 9; - if (keyCount2) - __isz += 9; - if (keyCount3) - __isz += 9; - return __isz; - } - }; - }; - - std::unique_ptr m_anim; - - void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, bool) const { - m_anim->sendANIMToBlender(os, rig); - } - - void extractEVNT(const DNAANCS::AnimationResInfo& animInfo, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, bool force) const {} -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CINF.cpp b/DataSpec/DNAMP2/CINF.cpp deleted file mode 100644 index da6af3935..000000000 --- a/DataSpec/DNAMP2/CINF.cpp +++ /dev/null @@ -1,227 +0,0 @@ -#include "CINF.hpp" -#include "hecl/Blender/Connection.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -namespace DataSpec::DNAMP2 { - -atUint32 CINF::getInternalBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (const Bone& b : bones) { - if (b.id == id) - return idx; - ++idx; - } - return -1; -} - -atUint32 CINF::getBoneIdxFromId(atUint32 id) const { - atUint32 idx = 0; - for (atUint32 bid : boneIds) { - if (bid == id) - return idx; - ++idx; - } - return 0; -} - -const std::string* CINF::getBoneNameFromId(atUint32 id) const { - for (const Name& name : names) - if (id == name.boneId) - return &name.name; - return nullptr; -} - -void CINF::sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const { - for (atUint32 bid : boneIds) { - for (const Name& name : names) { - if (name.boneId == bid) { - os.format(FMT_STRING("obj.vertex_groups.new(name='{}')\n"), name.name); - break; - } - } - } -} - -template -void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const typename PAKBridge::PAKType::IDType& cinfId) const { - DNAANIM::RigInverter inverter(*this); - - os.format(FMT_STRING("arm = bpy.data.armatures.new('CINF_{}')\n" - "arm_obj = bpy.data.objects.new(arm.name, arm)\n" - "bpy.context.scene.collection.objects.link(arm_obj)\n" - "bpy.context.view_layer.objects.active = arm_obj\n" - "bpy.ops.object.mode_set(mode='EDIT')\n" - "arm_bone_table = {{}}\n"), - cinfId); - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) { - zeus::simd_floats originF(bone.m_origBone.origin.simd); - zeus::simd_floats tailF(bone.m_tail.mSimd); - os.format(FMT_STRING("bone = arm.edit_bones.new('{}')\n" - "bone.head = ({},{},{})\n" - "bone.tail = ({},{},{})\n" - "bone.use_inherit_scale = False\n" - "arm_bone_table[{}] = bone\n"), - *getBoneNameFromId(bone.m_origBone.id), originF[0], originF[1], originF[2], tailF[0], tailF[1], tailF[2], - bone.m_origBone.id); - } - - if constexpr (std::is_same_v) { - if (bones.size()) { - atUint32 nullId = bones[0].parentId; - for (const Bone& bone : bones) - if (bone.parentId != nullId) - os.format(FMT_STRING("arm_bone_table[{}].parent = arm_bone_table[{}]\n"), bone.id, bone.parentId); - } - } else { - for (const Bone& bone : bones) - if (bone.parentId != 97) - os.format(FMT_STRING("arm_bone_table[{}].parent = arm_bone_table[{}]\n"), bone.id, bone.parentId); - } - - os << "bpy.ops.object.mode_set(mode='OBJECT')\n"; - - for (const DNAANIM::RigInverter::Bone& bone : inverter.getBones()) - os.format(FMT_STRING("arm_obj.pose.bones['{}'].rotation_mode = 'QUATERNION'\n"), - *getBoneNameFromId(bone.m_origBone.id)); -} -template void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, const UniqueID32& cinfId) const; -template void CINF::sendCINFToBlender(hecl::blender::PyOutStream& os, - const UniqueID64& cinfId) const; - -template -std::string CINF::GetCINFArmatureName(const UniqueID& cinfId) { - return fmt::format(FMT_STRING("CINF_{}"), cinfId); -} -template std::string CINF::GetCINFArmatureName(const UniqueID32& cinfId); -template std::string CINF::GetCINFArmatureName(const UniqueID64& cinfId); - -int CINF::RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, - std::map& nameMap) { - int selId; - auto search = idMap.find(bone->name); - if (search == idMap.end()) { - selId = curId++; - idMap.emplace(std::make_pair(bone->name, selId)); - } else - selId = search->second; - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = selId; - boneOut.id = selId; - boneOut.parentId = parent; - boneOut.origin = bone->origin; - boneOut.linkedCount = bone->children.size() + 1; - boneOut.linked.reserve(boneOut.linkedCount); - - const BlenderBone* child; - boneOut.linked.push_back(parent); - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - boneOut.linked.push_back(RecursiveAddArmatureBone(armature, child, boneOut.id, curId, idMap, nameMap)); - - return boneOut.id; -} - -CINF::CINF(const Armature& armature, std::unordered_map& idMap) { - idMap.reserve(armature.bones.size()); - bones.reserve(armature.bones.size()); - - std::map nameMap; - - const BlenderBone* bone = armature.getRoot(); - if (bone) { - if (bone->children.size()) { - int curId = 4; - const BlenderBone* child; - for (size_t i = 0; (child = armature.getChild(bone, i)); ++i) - RecursiveAddArmatureBone(armature, child, 3, curId, idMap, nameMap); - } - - bones.emplace_back(); - Bone& boneOut = bones.back(); - nameMap[bone->name] = 3; - boneOut.id = 3; - boneOut.parentId = 2; - boneOut.origin = bone->origin; - idMap.emplace(std::make_pair(bone->name, 3)); - - if (bone->children.size()) { - boneOut.linkedCount = 2; - boneOut.linked = {2, 4}; - } else { - boneOut.linkedCount = 1; - boneOut.linked = {2}; - } - } - - boneCount = bones.size(); - - names.reserve(nameMap.size()); - nameCount = nameMap.size(); - for (const auto& name : nameMap) { - names.emplace_back(); - Name& nameOut = names.back(); - nameOut.name = name.first; - nameOut.boneId = name.second; - } - - boneIdCount = boneCount; - boneIds.reserve(boneIdCount); - for (auto it = bones.crbegin(); it != bones.crend(); ++it) - boneIds.push_back(it->id); -} - -template -bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - if (!force && outPath.isFile()) - return true; - - auto& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Armature)) - return false; - auto os = conn.beginPythonOut(true); - - os.format(FMT_STRING("import bpy\n" - "from mathutils import Vector\n" - "bpy.context.scene.name = 'CINF_{}'\n" - "bpy.context.scene.hecl_arm_obj = bpy.context.scene.name\n" - "\n" - "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n"), - entry.id); - - CINF cinf; - cinf.read(rs); - cinf.sendCINFToBlender(os, entry.id); - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -template bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, - bool force, hecl::blender::Token& btok, - std::function fileChanged); -template bool CINF::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, - const typename DNAMP3::PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged); - -bool CINF::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature) { - std::unordered_map boneIdMap; - CINF cinf(armature, boneIdMap); - - /* Write out CINF resource */ - athena::io::TransactionalFileWriter w(outPath.getAbsolutePath()); - cinf.write(w); - return true; -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CINF.hpp b/DataSpec/DNAMP2/CINF.hpp deleted file mode 100644 index 6ef77a0f9..000000000 --- a/DataSpec/DNAMP2/CINF.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -struct CINF : BigDNA { - AT_DECL_DNA - Value boneCount; - struct Bone : BigDNA { - AT_DECL_DNA - Value id; - Value parentId; - Value origin; - Value q1; - Value q2; - Value linkedCount; - Vector linked; - }; - Vector bones; - - Value boneIdCount; - Vector boneIds; - - Value nameCount; - struct Name : BigDNA { - AT_DECL_DNA - String<-1> name; - Value boneId; - }; - Vector names; - - atUint32 getInternalBoneIdxFromId(atUint32 id) const; - atUint32 getBoneIdxFromId(atUint32 id) const; - const std::string* getBoneNameFromId(atUint32 id) const; - void sendVertexGroupsToBlender(hecl::blender::PyOutStream& os) const; - template - void sendCINFToBlender(hecl::blender::PyOutStream& os, const typename PAKBridge::PAKType::IDType& cinfId) const; - template - static std::string GetCINFArmatureName(const UniqueID& cinfId); - - CINF() = default; - using Armature = hecl::blender::Armature; - using BlenderBone = hecl::blender::Bone; - - int RecursiveAddArmatureBone(const Armature& armature, const BlenderBone* bone, int parent, int& curId, - std::unordered_map& idMap, std::map& nameMap); - - CINF(const Armature& armature, std::unordered_map& idMap); - - template - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const typename PAKBridge::PAKType::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged); - - static bool Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, - const hecl::blender::Armature& armature); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMDL.cpp b/DataSpec/DNAMP2/CMDL.cpp deleted file mode 100644 index 4243b67ea..000000000 --- a/DataSpec/DNAMP2/CMDL.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "CMDL.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function) { - /* Check for RigPair */ - CINF cinf; - CSKR cskr; - using RigPair = std::pair, std::pair>; - RigPair loadRp = {}; - if (const typename CharacterAssociations::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) { - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - loadRp.first = {rp->cskr, &cskr}; - loadRp.second = {rp->cinf, &cinf}; - } - - /* Do extract */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_2, 4>( - conn, rs, pakRouter, entry, dataSpec, loadRp); - return conn.saveBlend(); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMDL.hpp b/DataSpec/DNAMP2/CMDL.hpp deleted file mode 100644 index a2a0e14fc..000000000 --- a/DataSpec/DNAMP2/CMDL.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "CMDLMaterials.hpp" -#include "DNAMP2.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP2 { - -struct CMDL { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool, - hecl::blender::Token& btok, std::function); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMDLMaterials.hpp b/DataSpec/DNAMP2/CMDLMaterials.hpp deleted file mode 100644 index 503d91761..000000000 --- a/DataSpec/DNAMP2/CMDLMaterials.hpp +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/GX.hpp" -#include "../DNAMP1/CMDLMaterials.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -/* Structurally identical to DNAMP1::MaterialSet except unk0 and unk1 fields */ -struct MaterialSet : BigDNA { - static constexpr bool OneSection() { return false; } - - AT_DECL_DNA - DNAMP1::MaterialSet::MaterialSetHead head; - - struct Material : BigDNA { - AT_DECL_DNA - using Flags = DNAMP1::MaterialSet::Material::Flags; - Flags flags; - const Flags& getFlags() const { return flags; } - - Value textureCount; - Vector textureIdxs; - using VAFlags = DNAMP1::MaterialSet::Material::VAFlags; - DNAMP1::MaterialSet::Material::VAFlags vaFlags; - const VAFlags& getVAFlags() const { return vaFlags; } - Value unk0; /* MP2 only */ - Value unk1; /* MP2 only */ - Value uniqueIdx; - - Vector konstCount; - Vector konstColors; - - using BlendFactor = GX::BlendFactor; - Value blendDstFac; - Value blendSrcFac; - Vector indTexSlot; - - Value colorChannelCount; - Vector colorChannels; - - Value tevStageCount; - Vector tevStages; - Vector tevStageTexInfo; - - Value tcgCount; - Vector tcgs; - - Value uvAnimsSize; - Value uvAnimsCount; - Vector uvAnims; - }; - Vector materials; - - static void RegisterMaterialProps(hecl::blender::PyOutStream& out) { - DNAMP1::MaterialSet::RegisterMaterialProps(out); - } - static void ConstructMaterial(hecl::blender::PyOutStream& out, const MaterialSet::Material& material, - unsigned groupIdx, unsigned matIdx); - - void readToBlender(hecl::blender::PyOutStream& os, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx) { - DNACMDL::ReadMaterialSetToBlender_1_2(os, *this, pakRouter, entry, setIdx); - } - - void ensureTexturesExtracted(PAKRouter& pakRouter) const { head.ensureTexturesExtracted(pakRouter); } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CMakeLists.txt b/DataSpec/DNAMP2/CMakeLists.txt deleted file mode 100644 index aeb467160..000000000 --- a/DataSpec/DNAMP2/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -make_dnalist(MLVL - ANIM - AGSC - ANCS - CMDLMaterials - CINF - CSKR - MREA - PTLA - SAVW - DeafBabe) -set(DNAMP2_SOURCES - DNAMP2.hpp DNAMP2.cpp - DeafBabe.cpp - PAK.cpp - ANIM.cpp - AGSC.cpp - CINF.cpp - CSKR.cpp - CMDL.cpp - ANCS.cpp - CMDL.hpp - MREA.cpp - MAPA.hpp - MAPU.hpp - PATH.hpp - AFSM.hpp - STRG.hpp STRG.cpp) - -dataspec_add_list(DNAMP2 DNAMP2_SOURCES) diff --git a/DataSpec/DNAMP2/CSKR.cpp b/DataSpec/DNAMP2/CSKR.cpp deleted file mode 100644 index 16ab4f450..000000000 --- a/DataSpec/DNAMP2/CSKR.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "CSKR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const { - atUint32 accum = 0; - for (const SkinningRule& rule : skinningRules) { - if (idx >= accum && idx < accum + rule.vertCount) - for (const SkinningRule::Weight& weight : rule.weights) - os.format(FMT_STRING("vert[dvert_lay][{}] = {}\n"), cinf.getBoneIdxFromId(weight.boneId), weight.weight); - accum += rule.vertCount; - } -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/CSKR.hpp b/DataSpec/DNAMP2/CSKR.hpp deleted file mode 100644 index a46ccdda7..000000000 --- a/DataSpec/DNAMP2/CSKR.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CINF.hpp" -#include "../DNAMP1/CSKR.hpp" - -namespace DataSpec::DNAMP2 { - -struct CSKR : DNAMP1::CSKR { - Delete expl; - - const atInt16* getMatrixBank(size_t) const { return nullptr; } - - void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atUint32 idx) const; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DNAMP2.cpp b/DataSpec/DNAMP2/DNAMP2.cpp deleted file mode 100644 index d58c5057b..000000000 --- a/DataSpec/DNAMP2/DNAMP2.cpp +++ /dev/null @@ -1,291 +0,0 @@ -#define NOD_ATHENA 1 -#include "DNAMP2.hpp" -#include "STRG.hpp" -#include "MLVL.hpp" -#include "CMDL.hpp" -#include "ANCS.hpp" -#include "CINF.hpp" -#include "MREA.hpp" -#include "MAPA.hpp" -#include "MAPU.hpp" -#include "PATH.hpp" -#include "AFSM.hpp" -#include "SAVW.hpp" -#include "AGSC.hpp" -#include "../DNAMP1/HINT.hpp" -#include "../DNAMP1/CSNG.hpp" -#include "DataSpec/DNACommon/FSM2.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/FONT.hpp" -#include "DataSpec/DNACommon/DGRP.hpp" -#include "DataSpec/DNACommon/ATBL.hpp" -#include "Runtime/GCNTypes.hpp" - -namespace DataSpec::DNAMP2 { -logvisor::Module Log("DataSpec::DNAMP2"); - -static bool GetNoShare(std::string_view name) { - std::string lowerName(name); - std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); - if (lowerName.compare(0, 7, "metroid") == 0) - return false; - if (lowerName.compare(0, 8, "frontend") == 0) - return false; - return true; -} - -PAKBridge::PAKBridge(const nod::Node& node, bool doExtract) -: m_node(node), m_pak(true, GetNoShare(node.getName())), m_doExtract(doExtract) { - nod::AthenaPartReadStream rs(node.beginReadStream()); - m_pak.read(rs); - - /* Append Level String */ - for (const auto& entry : m_pak.m_entries) { - const DNAMP2::PAK::Entry& e = entry.second; - if (e.type == FOURCC('MLVL')) { - PAKEntryReadStream rs = e.beginReadStream(m_node); - MLVL mlvl; - mlvl.read(rs); - const DNAMP2::PAK::Entry* nameEnt = m_pak.lookupEntry(mlvl.worldNameId); - if (nameEnt) { - PAKEntryReadStream rs = nameEnt->beginReadStream(m_node); - STRG mlvlName; - mlvlName.read(rs); - if (m_levelString.size()) - m_levelString += ", "; - m_levelString += mlvlName.getUTF8(FOURCC('ENGL'), 0); - } - } - } -} - -static std::string LayerName(std::string_view name) { - std::string ret(name); - for (auto& ch : ret) - if (ch == '/' || ch == '\\') - ch = '-'; - return ret; -} - -void PAKBridge::build() { - /* First pass: build per-area/per-layer dependency map */ - for (const auto& entry : m_pak.m_entries) { - const DNAMP2::PAK::Entry& e = entry.second; - if (e.type == FOURCC('MLVL')) { - Level& level = m_levelDeps[e.id]; - - MLVL mlvl; - { - PAKEntryReadStream rs = e.beginReadStream(m_node); - mlvl.read(rs); - } - std::string catalogueName; - level.name = m_pak.bestEntryName(m_node, e, catalogueName); - level.areas.reserve(mlvl.areaCount); - unsigned layerIdx = 0; - - /* Make MAPW available to lookup MAPAs */ - const DNAMP2::PAK::Entry* worldMapEnt = m_pak.lookupEntry(mlvl.worldMap); - std::vector mapw; - if (worldMapEnt) { - PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node); - rs.seek(8, athena::SeekOrigin::Current); - atUint32 areaCount = rs.readUint32Big(); - mapw.reserve(areaCount); - for (atUint32 i = 0; i < areaCount; ++i) - mapw.emplace_back(rs); - } - - /* Index areas */ - unsigned ai = 0; - for (const MLVL::Area& area : mlvl.areas) { - Level::Area& areaDeps = level.areas[area.areaMREAId]; - MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai]; - const DNAMP2::PAK::Entry* areaNameEnt = m_pak.lookupEntry(area.areaNameId); - if (areaNameEnt) { - STRG areaName; - { - PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node); - areaName.read(rs); - } - areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0); - areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); - } - if (areaDeps.name.empty()) { - areaDeps.name = area.internalAreaName; - if (areaDeps.name.empty()) { - areaDeps.name = "MREA_" + area.areaMREAId.toString(); - } - } - std::string num = fmt::format(FMT_STRING("{:02d} "), ai); - areaDeps.name = num + areaDeps.name; - - areaDeps.layers.reserve(area.depLayerCount - 1); - unsigned r = 0; - for (unsigned l = 1; l < area.depLayerCount; ++l) { - areaDeps.layers.emplace_back(); - Level::Area::Layer& layer = areaDeps.layers.back(); - layer.name = LayerName(mlvl.layerNames[layerIdx++]); - layer.active = layerFlags.flags >> (l - 1) & 0x1; - layer.name = hecl::StringUtils::TrimWhitespace(layer.name); - num = fmt::format(FMT_STRING("{:02d} "), l - 1); - layer.name = num + layer.name; - - layer.resources.reserve(area.depLayers[l] - r); - for (; r < area.depLayers[l]; ++r) - layer.resources.emplace(area.deps[r].id); - } - areaDeps.resources.reserve(area.depCount - r + 2); - for (; r < area.depCount; ++r) - areaDeps.resources.emplace(area.deps[r].id); - areaDeps.resources.emplace(area.areaMREAId); - if (mapw.size() > ai) - areaDeps.resources.emplace(mapw[ai]); - ++ai; - } - } - } - - /* Second pass: cross-compare uniqueness */ - for (auto& entry : m_pak.m_entries) { - entry.second.unique.checkEntry(*this, entry.second); - } -} - -void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('ANCS')) { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - ANCS ancs; - ancs.read(rs); - for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) { - charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskr] = - std::make_pair(entry.second.id, fmt::format(FMT_STRING("{}_{}.CSKR"), ci.name, ci.cskr)); - if (ci.cmdlIce.isValid()) { - charAssoc.m_cmdlRigs[ci.cmdlIce] = {ci.cskrIce, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskrIce] = - std::make_pair(entry.second.id, fmt::format(FMT_STRING("{}.ICE_{}.CSKR"), ci.name, ci.cskrIce)); - } - } - } - } -} - -void PAKBridge::addPATHToMREA(PAKRouter& pakRouter, - std::unordered_map& pathToMrea) const { - for (const auto& [id, entry] : m_pak.m_entries) { - if (entry.type == FOURCC('MREA')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - UniqueID32 pathID = MREA::GetPATHId(rs); - if (pathID.isValid()) - pathToMrea[pathID] = id; - } - } -} - -static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; - -void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, - std::unordered_map& addTo, - std::unordered_map& pathOverrides) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('MLVL')) { - MLVL mlvl; - { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - mlvl.read(rs); - } - hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); - - if (mlvl.worldNameId.isValid()) - pathOverrides[mlvl.worldNameId] = - hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId)); - - for (const MLVL::Area& area : mlvl.areas) { - { - /* Get PATH transform */ - const nod::Node* areaNode; - const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode); - PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode); - UniqueID32 pathId = MREA::GetPATHId(rs); - if (pathId.isValid()) - addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow) - .transposed(); - } - hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); - if (area.areaNameId.isValid()) - pathOverrides[area.areaNameId] = - hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId)); - } - - if (mlvl.worldMap.isValid()) { - const nod::Node* mapNode; - const DNAMP2::PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); - if (mapEntry) { - PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); - u32 magic = rs.readUint32Big(); - if (magic == 0xDEADF00D) { - rs.readUint32Big(); - u32 count = rs.readUint32Big(); - for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) { - MLVL::Area& areaData = mlvl.areas[i]; - UniqueID32 mapaId; - mapaId.read(rs); - addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1], - areaData.transformMtx[2], BottomRow) - .transposed(); - } - } - } - } - } - } -} - -ResExtractor PAKBridge::LookupExtractor(const nod::Node& pakNode, const DNAMP2::PAK& pak, - const DNAMP2::PAK::Entry& entry) { - switch (entry.type.toUint32()) { - case SBIG('HINT'): - return {DNAMP1::HINT::Extract, {".yaml"}}; - case SBIG('STRG'): - return {STRG::Extract, {".yaml"}}; - case SBIG('TXTR'): - return {TXTR::Extract, {".png"}}; - case SBIG('AFSM'): - return {AFSM::Extract, {".yaml"}}; - case SBIG('SAVW'): - return {SAVWCommon::ExtractSAVW, {".yaml"}}; - case SBIG('CMDL'): - return {CMDL::Extract, {".blend"}, 1}; - case SBIG('CINF'): - return {CINF::Extract, {".blend"}, 1}; - case SBIG('ANCS'): - return {ANCS::Extract, {".yaml", ".blend"}, 2}; - case SBIG('MLVL'): - return {MLVL::Extract, {".yaml", ".blend"}, 3}; - case SBIG('MREA'): - return {MREA::Extract, {".blend"}, 4}; - case SBIG('MAPA'): - return {MAPA::Extract, {".blend"}, 4}; - case SBIG('MAPU'): - return {MAPU::Extract, {".blend"}, 5}; - case SBIG('PATH'): - return {PATH::Extract, {".blend"}, 5}; - case SBIG('FSM2'): - return {DNAFSM2::ExtractFSM2, {".yaml"}}; - case SBIG('FONT'): - return {DNAFont::ExtractFONT, {".yaml"}}; - case SBIG('DGRP'): - return {DNADGRP::ExtractDGRP, {".yaml"}}; - case SBIG('AGSC'): - return {AGSC::Extract, {}}; - case SBIG('CSNG'): - return {DNAMP1::CSNG::Extract, {".mid", ".yaml"}}; - case SBIG('ATBL'): - return {DNAAudio::ATBL::Extract, {".yaml"}}; - } - return {}; -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DNAMP2.hpp b/DataSpec/DNAMP2/DNAMP2.hpp deleted file mode 100644 index 8958ac5c8..000000000 --- a/DataSpec/DNAMP2/DNAMP2.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" - -namespace DataSpec::DNAMP2 { - -extern logvisor::Module Log; - -/* MP2-specific, one-shot PAK traversal/extraction class */ -class PAKBridge { - const nod::Node& m_node; - DNAMP2::PAK m_pak; - -public: - bool m_doExtract; - using Level = DataSpec::Level; - std::unordered_map m_levelDeps; - std::string m_levelString; - - PAKBridge(const nod::Node& node, bool doExtract = true); - void build(); - static ResExtractor LookupExtractor(const nod::Node& pakNode, const DNAMP2::PAK& pak, - const DNAMP2::PAK::Entry& entry); - std::string_view getName() const { return m_node.getName(); } - std::string_view getLevelString() const { return m_levelString; } - - using PAKType = DNAMP2::PAK; - const PAKType& getPAK() const { return m_pak; } - const nod::Node& getNode() const { return m_node; } - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - - void addPATHToMREA(PAKRouter& pakRouter, std::unordered_map& pathToMrea) const; - - void addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, - std::unordered_map& pathOverrides) const; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DeafBabe.cpp b/DataSpec/DNAMP2/DeafBabe.cpp deleted file mode 100644 index 00d0fd5b1..000000000 --- a/DataSpec/DNAMP2/DeafBabe.cpp +++ /dev/null @@ -1,275 +0,0 @@ -#include "DeafBabe.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP2 { - -void DeafBabe::BlenderInit(hecl::blender::PyOutStream& os) { - os << "TYPE_COLORS = {'NoSFX':(0.0, 0.0, 0.0),\n" - " 'Stone':(1.0, 0.43, 0.15),\n" - " 'Metal':(0.5, 0.5, 0.5),\n" - " 'Grass':(0.0, 0.42, 0.01)," - " 'Ice':(0.0, 0.1, 0.1),\n" - " 'Metal Grating':(0.09, 0.09, 0.09),\n" - " 'Phazon':(0.24, 0.0, 0.21),\n" - " 'Dirt':(0.1, 0.07, 0.05),\n" - " 'Stone':(0.12, 0.12, 0.12),\n" - " 'SP Metal':(0.41, 0.44, 0.5),\n" - " 'Snow':(0.9, 1.0, 1.0),\n" - " 'Fabric':(0.27, 0.34, 0.39),\n" - " 'Moth/Seed Organics':(0.0, 0.02, 0.05),\n" - " 'Glass':(0.27, 0.38, 0.9),\n" - " 'Shield':(1.0, 0.6, 0.0),\n" - " 'Web':(1.0, 1.0, 0.28),\n" - " 'Sand':(0.53, 0.44, 0.21),\n" - " 'Wood':(0.30, 0.15, 0.03),\n" - " 'Organic':(0.19, 0.45, 0.2),\n" - " 'Rubber':(0.09, 0.02, 0.01)}\n" - "\n" - "# Diffuse Color Maker\n" - "from mathutils import Color\n" - "def make_color(index, mat_type, name):\n" - " new_mat = bpy.data.materials.new(name)\n" - " if mat_type in TYPE_COLORS:\n" - " new_mat.diffuse_color = TYPE_COLORS[mat_type] + (1.0,)\n" - " else:\n" - " col = Color()\n" - " col.hsv = ((index / 6.0) % 1.0, 1.0-((index // 6) / 6.0), 1)\n" - " new_mat.diffuse_color = tuple(col) + (1.0,)\n" - " return new_mat\n" - "\n" - "bpy.types.Material.retro_unknown = bpy.props.BoolProperty(description='Retro: Unknown (U)')\n" - "bpy.types.Material.retro_surface_stone = bpy.props.BoolProperty(description='Retro Surface: Stone')\n" - "bpy.types.Material.retro_surface_metal = bpy.props.BoolProperty(description='Retro Surface: Metal')\n" - "bpy.types.Material.retro_surface_grass = bpy.props.BoolProperty(description='Retro Surface: Grass')\n" - "bpy.types.Material.retro_surface_ice = bpy.props.BoolProperty(description='Retro Surface: Ice')\n" - "bpy.types.Material.retro_pillar = bpy.props.BoolProperty(description='Retro Pillar (I)')\n" - "bpy.types.Material.retro_surface_metal_grating = bpy.props.BoolProperty(description='Retro Surface: Metal " - "Grating')\n" - "bpy.types.Material.retro_surface_phazon = bpy.props.BoolProperty(description='Retro Surface: Phazon')\n" - "bpy.types.Material.retro_surface_dirt = bpy.props.BoolProperty(description='Retro Surface: Rock')\n" - "bpy.types.Material.retro_surface_sp_metal = bpy.props.BoolProperty(description='Retro Surface: Lava')\n" - "bpy.types.Material.retro_surface_snow = bpy.props.BoolProperty(description='Retro Surface: Snow')\n" - "bpy.types.Material.retro_surface_fabric = bpy.props.BoolProperty(description='Retro Surface: fabric')\n" - "bpy.types.Material.retro_half_pipe = bpy.props.BoolProperty(description='Retro: Half Pipe (H)')\n" - "bpy.types.Material.retro_unused3 = bpy.props.BoolProperty(description='Retro: Unused 3 (U)')\n" - "bpy.types.Material.retro_unused4 = bpy.props.BoolProperty(description='Retro: Unused 4 (U)')\n" - "bpy.types.Material.retro_surface_mud = bpy.props.BoolProperty(description='Retro Surface: Mud')\n" - "bpy.types.Material.retro_surface_glass = bpy.props.BoolProperty(description='Retro Surface: Glass')\n" - "bpy.types.Material.retro_surface_shield = bpy.props.BoolProperty(description='Retro Surface: Shield')\n" - "bpy.types.Material.retro_surface_sand = bpy.props.BoolProperty(description='Retro Surface: Sand')\n" - "bpy.types.Material.retro_surface_moth_or_seed_organics = bpy.props.BoolProperty(description='Retro Surface: " - "Moth/Seed Organics')\n" - "bpy.types.Material.retro_surface_web = bpy.props.BoolProperty(description='Retro Surface: Web')\n" - "bpy.types.Material.retro_projectile_passthrough = bpy.props.BoolProperty(description='Retro: Projectile " - "Passthrough (P)')\n" - "bpy.types.Material.retro_camera_passthrough = bpy.props.BoolProperty(description='Retro: Camera Passthrough " - "(O)')\n" - "bpy.types.Material.retro_surface_wood = bpy.props.BoolProperty(description='Retro Surface: Wood')\n" - "bpy.types.Material.retro_surface_organic = bpy.props.BoolProperty(description='Retro Surface: Organic')\n" - "bpy.types.Material.retro_surface_rubber = bpy.props.BoolProperty(description='Retro Surface: Rubber')\n" - "bpy.types.Material.retro_see_through = bpy.props.BoolProperty(description='Retro: See Through (T)')\n" - "bpy.types.Material.retro_scan_passthrough = bpy.props.BoolProperty(description='Retro: Scan Passthrough " - "(S)')\n" - "bpy.types.Material.retro_ai_passthrough = bpy.props.BoolProperty(description='Retro: AI Passthrough (A)')\n" - "bpy.types.Material.retro_ceiling = bpy.props.BoolProperty(description='Retro: Ceiling (C)')\n" - "bpy.types.Material.retro_wall = bpy.props.BoolProperty(description='Retro: Wall (W)')\n" - "bpy.types.Material.retro_floor = bpy.props.BoolProperty(description='Retro: Floor (F)')\n" - "bpy.types.Material.retro_ai_block = bpy.props.BoolProperty(description='Retro: AI Block (B)')\n" - "bpy.types.Material.retro_jump_not_allowed = bpy.props.BoolProperty(description='Retro: Jump Not Allowed " - "(J)')\n" - "bpy.types.Material.retro_spider_ball = bpy.props.BoolProperty(description='Retro: Spider Ball (D)')\n" - "bpy.types.Material.retro_screw_attack_wall_jump = bpy.props.BoolProperty(description='Retro: Screw Attack " - "Wall Jump (R)')\n" - "\n" - "material_dict = {}\n" - "material_index = []\n" - "def get_type_id(data):\n" - "\n" - " ret = 0\n" - " for i in range(1, 26):\n" - " if i == 5 or i == 13 or i == 14 or i == 15 or i == 20 or i == 21 or i == 24:\n" - " continue\n" - " if ((data >> i) & 1):\n" - " ret = i\n" - " return ret\n" - "\n" - "def select_material(data):\n" - "\n" - " type_id = get_type_id(data)\n" - " mat_type = str(type_id)\n" - " if type_id == 0:\n" - " mat_type = 'NoSFX'\n" - " if type_id == 1:\n" - " mat_type = 'Stone'\n" - " elif type_id == 2:\n" - " mat_type = 'Metal'\n" - " elif type_id == 3:\n" - " mat_type = 'Grass'\n" - " elif type_id == 4:\n" - " mat_type = 'Ice'\n" - " elif type_id == 6:\n" - " mat_type = 'Metal Grating'\n" - " elif type_id == 7:\n" - " mat_type = 'Phazon'\n" - " elif type_id == 8:\n" - " mat_type = 'Dirt'\n" - " elif type_id == 9:\n" - " mat_type = 'SP Metal'\n" - " elif type_id == 10:\n" - " mat_type = 'Glass'\n" - " elif type_id == 11:\n" - " mat_type = 'Snow'\n" - " elif type_id == 12:\n" - " mat_type = 'Fabric'\n" - " elif type_id == 16:\n" - " mat_type = 'Shield'\n" - " elif type_id == 17:\n" - " mat_type = 'Sand'\n" - " elif type_id == 18:\n" - " mat_type = 'Moth/Seed Organics'\n" - " elif type_id == 19:\n" - " mat_type = 'Web'\n" - " elif type_id == 22:\n" - " mat_type = 'Wood'\n" - " elif type_id == 23:\n" - " mat_type = 'Organic'\n" - " elif type_id == 25:\n" - " mat_type = 'Rubber'\n" - "\n" - " mat_flags = ''\n" - " if ((data >> 0) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 5) & 1):\n" - " mat_flags += 'I'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 13) & 1):\n" - " mat_flags += 'H'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 14) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 15) & 1):\n" - " mat_flags += 'U'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 20) & 1):\n" - " mat_flags += 'P'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 21) & 1):\n" - " mat_flags += 'O'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 26) & 1):\n" - " mat_flags += 'T'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 27) & 1):\n" - " mat_flags += 'S'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 28) & 1):\n" - " mat_flags += 'A'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 29) & 1):\n" - " mat_flags += 'C'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 30) & 1):\n" - " mat_flags += 'W'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 31) & 1):\n" - " mat_flags += 'F'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 48) & 1):\n" - " mat_flags += 'B'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 58) & 1):\n" - " mat_flags += 'J'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 61) & 1):\n" - " mat_flags += 'D'\n" - " else:\n" - " mat_flags += 'x'\n" - " if ((data >> 62) & 1):\n" - " mat_flags += 'R'\n" - " else:\n" - " mat_flags += 'x'\n" - "\n" - " if len(mat_flags) > 0:\n" - " mat_flags = ' ' + mat_flags\n" - "\n" - " mat_name = mat_type + mat_flags\n" - "\n" - " if mat_name in material_index:\n" - " return material_index.index(mat_name)\n" - " elif mat_name in material_dict:\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - " else:\n" - " mat = make_color(len(material_dict), mat_type, mat_name)\n" - " mat.retro_unknown = ((data >> 0) & 1)\n" - " mat.retro_surface_stone = ((data >> 1) & 1)\n" - " mat.retro_surface_metal = ((data >> 2) & 1)\n" - " mat.retro_surface_grass = ((data >> 3) & 1) \n" - " mat.retro_surface_ice = ((data >> 4) & 1)\n" - " mat.retro_pillar = ((data >> 5) & 1)\n" - " mat.retro_surface_metal_grating = ((data >> 6) & 1)\n" - " mat.retro_surface_phazon = ((data >> 7) & 1)\n" - " mat.retro_surface_dirt = ((data >> 8) & 1)\n" - " mat.retro_surface_sp_metal = ((data >> 9) & 1)\n" - " mat.retro_surface_glass = ((data >> 10) & 1)\n" - " mat.retro_surface_snow = ((data >> 11) & 1)\n" - " mat.retro_surface_fabric = ((data >> 12) & 1)\n" - " mat.retro_half_pipe = ((data >> 13) & 1)\n" - " mat.retro_unused3 = ((data >> 14) & 1)\n" - " mat.retro_unused4 = ((data >> 15) & 1)\n" - " mat.retro_surface_shield = ((data >> 16) & 1)\n" - " mat.retro_surface_sand = ((data >> 17) & 1)\n" - " mat.retro_surface_moth_or_seed_organics = ((data >> 18) & 1)\n" - " mat.retro_surface_web = ((data >> 19) & 1)\n" - " mat.retro_projectile_passthrough = ((data >> 20) & 1)\n" - " mat.retro_camera_passthrough = ((data >> 21) & 1)\n" - " mat.retro_surface_wood = ((data >> 22) & 1)\n" - " mat.retro_surface_organic = ((data >> 23) & 1)\n" - " mat.retro_surface_rubber = ((data >> 25) & 1)\n" - " mat.retro_see_through = ((data >> 26) & 1)\n" - " mat.retro_scan_passthrough = ((data >> 27) & 1)\n" - " mat.retro_ai_passthrough = ((data >> 28) & 1)\n" - " mat.retro_ceiling = ((data >> 29) & 1)\n" - " mat.retro_wall= ((data >> 30) & 1)\n" - " mat.retro_floor = ((data >> 31) & 1)\n" - " mat.retro_ai_block = ((data >> 48) & 1)\n" - " mat.retro_jump_not_allowed = ((data >> 58) & 1)\n" - " mat.retro_spider_ball = ((data >> 61) & 1)\n" - " mat.retro_screw_attack_wall_jump = ((data >> 62) & 1)\n" - " material_dict[mat_name] = mat\n" - " material_index.append(mat_name)\n" - " return len(material_index)-1\n" - "\n" - "\n"; -} - -void DeafBabe::insertNoClimb(hecl::blender::PyOutStream& os) const { - for (atInt16 edgeIdx : noClimbEdges) { - if (edgeIdx == -1) - continue; - const Edge& edge = edgeVertConnections[edgeIdx]; - os.format(FMT_STRING("edge = col_bm.edges.get((col_bm.verts[{}], col_bm.verts[{}]))\n" - "if edge:\n" - " edge.seam = True\n"), - edge.verts[0], edge.verts[1]); - } -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/DeafBabe.hpp b/DataSpec/DNAMP2/DeafBabe.hpp deleted file mode 100644 index 5ebbf267a..000000000 --- a/DataSpec/DNAMP2/DeafBabe.hpp +++ /dev/null @@ -1,245 +0,0 @@ -#pragma once - -#include "../DNAMP1/DeafBabe.hpp" - -namespace DataSpec::DNAMP2 { - -struct DeafBabe : BigDNA { - AT_DECL_DNA - using BspNodeType = DataSpec::BspNodeType; - - struct Material : BigDNA { - AT_DECL_DNA - Value material = 0; - bool unknown() const { return material & 1; } - void setUnknown(bool v) { - material &= ~1; - material |= atUint64(v); - } - bool surfaceStone() const { return (material >> 1ull) & 1; } - void setSurfaceStone(bool v) { - material &= ~(1ull << 1ull); - material |= (atUint64(v) << 1ull); - } - bool surfaceMetal() const { return (material >> 2) & 1; } - void setSurfaceMetal(bool v) { - material &= ~(1ull << 2ull); - material |= (atUint64(v) << 2ull); - } - bool surfaceGrass() const { return (material >> 3) & 1; } - void setSurfaceGrass(bool v) { - material &= ~(1ull << 3ull); - material |= (atUint64(v) << 3ull); - } - bool surfaceIce() const { return (material >> 4ull) & 1; } - void setSurfaceIce(bool v) { - material &= ~(1ull << 4ull); - material |= (atUint64(v) << 4ull); - } - bool pillar() const { return (material >> 5ull) & 1; } - void setPillar(bool v) { - material &= ~(1ull << 5ull); - material |= (atUint64(v) << 5ull); - } - bool surfaceMetalGrating() const { return (material >> 6ull) & 1; } - void setSurfaceMetalGrating(bool v) { - material &= ~(1ull << 6ull); - material |= (atUint64(v) << 6ull); - } - bool surfacePhazon() const { return (material >> 7ull) & 1; } - void setSurfacePhazon(bool v) { - material &= ~(1ull << 7ull); - material |= (atUint64(v) << 7ull); - } - bool surfaceDirt() const { return (material >> 8ull) & 1; } - void setSurfaceDirt(bool v) { - material &= ~(1ull << 8); - material |= (atUint64(v) << 8ull); - } - bool surfaceSPMetal() const { return (material >> 9ull) & 1; } - void setSurfaceSPMetal(bool v) { - material &= ~(1ull << 9ull); - material |= (atUint64(v) << 9ull); - } - bool surfaceGlass() const { return (material >> 10ull) & 1; } - void setSurfaceGlass(bool v) { - material &= ~(1ull << 10ull); - material |= (atUint64(v) << 10ull); - } - bool surfaceSnow() const { return (material >> 11ull) & 1; } - void setSurfaceSnow(bool v) { - material &= ~(1ull << 11ull); - material |= (atUint64(v) << 11ull); - } - bool surfaceFabric() const { return (material >> 12ull) & 1; } - void setSurfaceFabric(bool v) { - material &= ~(1ull << 12ull); - material |= (atUint64(v) << 12ull); - } - bool halfPipe() const { return (material >> 13ull) & 1; } - void setHalfPipe(bool v) { - material &= ~(1ull << 13ull); - material |= (atUint64(v) << 13ull); - } - bool unused3() const { return (material >> 14ull) & 1; } - void setUnused3(bool v) { - material &= ~(1ull << 14ull); - material |= (atUint64(v) << 14ull); - } - bool unused4() const { return (material >> 15ull) & 1; } - void setUnused4(bool v) { - material &= ~(1ull << 15ull); - material |= (atUint64(v) << 15ull); - } - bool surfaceShield() const { return (material >> 16ull) & 1; } - void setSurfaceShield(bool v) { - material &= ~(1ull << 16); - material |= (atUint64(v) << 16ull); - } - bool surfaceSand() const { return (material >> 17ull) & 1; } - void setSurfaceSand(bool v) { - material &= ~(1ull << 17ull); - material |= (atUint64(v) << 17ull); - } - bool surfaceMothOrSeedOrganics() const { return (material >> 18) & 1; } - void setSurfaceMothOrSeedOrganics(bool v) { - material &= ~(1ull << 18); - material |= (atUint64(v) << 18ull); - } - bool surfaceWeb() const { return (material >> 19ull) & 1; } - void setSurfaceWeb(bool v) { - material &= ~(1ull << 19ull); - material |= (atUint64(v) << 19ull); - } - bool projectilePassthrough() const { return (material >> 20ull) & 1; } - void setProjectilePassthrough(bool v) { - material &= ~(1ull << 20ull); - material |= (atUint64(v) << 20ull); - } - bool cameraPassthrough() const { return (material >> 21ull) & 1; } - void setCameraPassthrough(bool v) { - material &= ~(1ull << 21ull); - material |= (atUint64(v) << 21ull); - } - bool surfaceWood() const { return (material >> 22ull) & 1; } - void setSurfaceWood(bool v) { - material &= ~(1ull << 22ull); - material |= (atUint64(v) << 22ull); - } - bool surfaceOrganic() const { return (material >> 23ull) & 1; } - void setSurfaceOrganic(bool v) { - material &= ~(1ull << 23ull); - material |= (atUint64(v) << 23ull); - } - bool flipFace() const { return (material >> 24ull) & 1; } - void setFlipFace(bool v) { - material &= ~(1ull << 24ull); - material |= (atUint64(v) << 24ull); - } - bool surfaceRubber() const { return (material >> 25) & 1; } - void setSurfaceRubber(bool v) { - material &= ~(1ull << 25ull); - material |= (atUint64(v) << 25ull); - } - bool seeThrough() const { return (material >> 26ull) & 1; } - void setSeeThrough(bool v) { - material &= ~(1ull << 26ull); - material |= (atUint64(v) << 26ull); - } - bool scanPassthrough() const { return (material >> 27ull) & 1; } - void setScanPassthrough(bool v) { - material &= ~(1ull << 27ull); - material |= (atUint64(v) << 27ull); - } - bool aiPassthrough() const { return (material >> 28) & 1; } - void setAiPassthrough(bool v) { - material &= ~(1ull << 28ull); - material |= (atUint64(v) << 28ull); - } - bool ceiling() const { return (material >> 29ull) & 1; } - void setCeiling(bool v) { - material &= ~(1ull << 29ull); - material |= (atUint64(v) << 29ull); - } - bool wall() const { return (material >> 30ull) & 1; } - void setWall(bool v) { - material &= ~(1ull << 30ull); - material |= (atUint64(v) << 30ull); - } - bool floor() const { return (material >> 31ull) & 1; } - void setFloor(bool v) { - material &= ~(1ull << 31ull); - material |= (atUint64(v) << 31ull); - } - bool aiBlock() const { return (material >> 48ull) & 1; } - void setAiBlock(bool v) { - material &= ~(1ull << 48ull); - material |= (atUint64(v) << 48ull); - } - bool jumpNotAllowed() const { return (material >> 58ull) & 1; } - void setJumpNotAllowed(bool v) { - material &= ~(1ull << 58ull); - material |= (atUint64(v) << 58ull); - } - bool spiderBall() const { return (material >> 61ull) & 1; } - void setSpiderBall(bool v) { - material &= ~(1ull << 61ull); - material |= (atUint64(v) << 61ull); - } - bool screwAttackWallJump() const { return (material >> 62ull) & 1; } - void setScrewAttackWallJump(bool v) { - material &= ~(1ull << 62ull); - material |= (atUint64(v) << 62ull); - } - - /* Dummies for MP1*/ - bool surfaceLava() const { return false; } - void setSurfaceLava(bool v) {} - bool surfaceMudSlow() const { return false; } - void setSurfaceMudSlow(bool v) {} - bool surfaceMud() const { return false; } - void setSurfaceMud(bool v) {} - bool surfaceStoneRock() const { return false; } - void setSurfaceLavaStone(bool v) {} - bool solid() const { return false; } - void setSolid(bool v) {} - bool noPlatformCollision() const { return false; } - void setNoPlatformCollision(bool v) {} - bool noEdgeCollision() const { return false; } - void setNoEdgeCollision(bool v) {} - }; - - using Edge = DNAMP1::DeafBabe::Edge; - using Triangle = DNAMP1::DeafBabe::Triangle; - - Value unk1; - Value length; - Value magic; - Value version; - Value aabb[2]; - Value rootNodeType; - Value bspSize; - Buffer bspTree; - Value materialCount; - Vector materials; - Value vertMatsCount; - Vector vertMats; - Value edgeMatsCount; - Vector edgeMats; - Value triMatsCount; - Vector triMats; - Value edgeVertsCount; - Vector edgeVertConnections; - Value triangleEdgesCount; - Vector triangleEdgeConnections; - Value noClimbEdgeCount; - Vector noClimbEdges; - Value vertCount; - Vector verts; - - static void BlenderInit(hecl::blender::PyOutStream& os); - void insertNoClimb(hecl::blender::PyOutStream& os) const; - void sendToBlender(hecl::blender::PyOutStream& os) const { DeafBabeSendToBlender(os, *this); } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MAPA.hpp b/DataSpec/DNAMP2/MAPA.hpp deleted file mode 100644 index 2805e89b5..000000000 --- a/DataSpec/DNAMP2/MAPA.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPA.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { -struct MAPA : DNAMAPA::MAPA { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - MAPA mapa; - mapa.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); - } - - static bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out) { - return DNAMAPA::Cook(mapa, out); - } - - static uint32_t Version() { return 3; } - using Header = DNAMAPA::MAPA::HeaderMP2; - using MappableObject = DNAMAPA::MAPA::MappableObjectMP1_2; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MAPU.hpp b/DataSpec/DNAMP2/MAPU.hpp deleted file mode 100644 index a68b500ad..000000000 --- a/DataSpec/DNAMP2/MAPU.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPU.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -struct MAPU : DNAMAPU::MAPU { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - MAPU mapu; - mapu.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPU::ReadMAPUToBlender(conn, mapu, outPath, pakRouter, entry, force); - } -}; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MLVL.hpp b/DataSpec/DNAMP2/MLVL.hpp deleted file mode 100644 index 273a5fc84..000000000 --- a/DataSpec/DNAMP2/MLVL.hpp +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MLVL.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -struct MLVL : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - UniqueID32 worldNameId; - UniqueID32 darkWorldNameId; - Value unk; - UniqueID32 saveWorldId; - UniqueID32 worldSkyboxId; - - Value areaCount; - struct Area : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 areaNameId; - Value transformMtx[3]; - Value aabb[2]; - UniqueID32 areaMREAId; - Value areaId; - - Value attachedAreaCount; - Vector attachedAreas; - Value padding; - - Value depCount; - struct Dependency : BigDNA { - AT_DECL_DNA_YAML - UniqueID32 id; - DNAFourCC type; - }; - Vector deps; - - Value depLayerCount; - Vector depLayers; - - Value dockCount; - struct Dock : BigDNA { - AT_DECL_DNA_YAML - Value endpointCount; - struct Endpoint : BigDNA { - AT_DECL_DNA_YAML - Value areaIdx; - Value dockIdx; - }; - Vector endpoints; - - Value planeVertCount; - Vector planeVerts; - }; - Vector docks; - - Value relCount; - Vector, AT_DNA_COUNT(relCount)> relFilenames; - Value relOffsetCount; - Vector relOffsets; - - String<-1> internalAreaName; - }; - Vector areas; - - UniqueID32 worldMap; - Value unknown2; - Value unknown3; - - Value layerFlagCount; - struct LayerFlags : BigDNA { - AT_DECL_DNA_YAML - Value layerCount; - Value flags; - }; - Vector layerFlags; - - Value layerNameCount; - Vector, AT_DNA_COUNT(layerNameCount)> layerNames; - - Value layerNameOffsetCount; - Vector layerNameOffsets; - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function fileChanged) { - MLVL mlvl; - mlvl.read(rs); - athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::ToYAMLStream(mlvl, writer); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); - } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/MREA.cpp b/DataSpec/DNAMP2/MREA.cpp deleted file mode 100644 index 7996f6a4a..000000000 --- a/DataSpec/DNAMP2/MREA.cpp +++ /dev/null @@ -1,347 +0,0 @@ -#include -#include -#include "MREA.hpp" -#include "../DNAMP1/MREA.hpp" -#include "DataSpec/DNACommon/EGMC.hpp" -#include "DeafBabe.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP2ORIG; - -namespace DNAMP2 { - -void MREA::StreamReader::nextBlock() { - if (m_nextBlk >= m_blkCount) - Log.report(logvisor::Fatal, FMT_STRING("MREA stream overrun")); - - BlockInfo& info = m_blockInfos[m_nextBlk++]; - - /* Reallocate read buffer if needed */ - if (info.bufSize > m_compBufSz) { - m_compBufSz = info.bufSize; - m_compBuf.reset(new atUint8[m_compBufSz]); - } - - /* Reallocate decompress buffer if needed */ - if (info.decompSize > m_decompBufSz) { - m_decompBufSz = info.decompSize; - m_decompBuf.reset(new atUint8[m_decompBufSz]); - } - - if (info.compSize == 0) { - /* Read uncompressed block */ - m_source.readUBytesToBuf(m_decompBuf.get(), info.decompSize); - } else { - /* Read compressed segments */ - atUint32 blockStart = ROUND_UP_32(info.compSize) - info.compSize; - m_source.seek(blockStart); - atUint32 rem = info.decompSize; - atUint8* bufCur = m_decompBuf.get(); - while (rem) { - atInt16 chunkSz = m_source.readInt16Big(); - if (chunkSz < 0) { - chunkSz = -chunkSz; - m_source.readUBytesToBuf(bufCur, chunkSz); - bufCur += chunkSz; - rem -= chunkSz; - } else { - m_source.readUBytesToBuf(m_compBuf.get(), chunkSz); - size_t dsz; - lzokay::decompress(m_compBuf.get(), chunkSz, bufCur, rem, dsz); - bufCur += dsz; - rem -= dsz; - } - } - } - - m_posInBlk = 0; - m_blkSz = info.decompSize; -} - -MREA::StreamReader::StreamReader(athena::io::IStreamReader& source, atUint32 blkCount) -: m_compBufSz(0x4120) -, m_compBuf(new atUint8[0x4120]) -, m_decompBufSz(0x4120) -, m_decompBuf(new atUint8[0x4120]) -, m_source(source) -, m_blkCount(blkCount) { - m_blockInfos.reserve(blkCount); - for (atUint32 i = 0; i < blkCount; ++i) { - BlockInfo& info = m_blockInfos.emplace_back(); - info.read(source); - m_totalDecompLen += info.decompSize; - } - source.seekAlign32(); - m_blkBase = source.position(); - nextBlock(); -} - -void MREA::StreamReader::seek(atInt64 diff, athena::SeekOrigin whence) { - atUint64 target = diff; - if (whence == athena::SeekOrigin::Current) { - target = m_pos + diff; - } else if (whence == athena::SeekOrigin::End) { - target = m_totalDecompLen - diff; - } - - if (target >= m_totalDecompLen) - Log.report(logvisor::Fatal, FMT_STRING("MREA stream seek overrun")); - - /* Determine which block contains position */ - atUint32 dAccum = 0; - atUint32 cAccum = 0; - atUint32 bIdx = 0; - for (BlockInfo& info : m_blockInfos) { - atUint32 newAccum = dAccum + info.decompSize; - if (newAccum > target) - break; - dAccum = newAccum; - if (info.compSize) - cAccum += ROUND_UP_32(info.compSize); - else - cAccum += info.decompSize; - ++bIdx; - } - - /* Seek source if needed */ - if (bIdx != m_nextBlk - 1) { - m_source.seek(m_blkBase + cAccum, athena::SeekOrigin::Begin); - m_nextBlk = bIdx; - nextBlock(); - } - - m_pos = target; - m_posInBlk = target - dAccum; -} - -void MREA::StreamReader::seekToSection(atUint32 sec, const std::vector& secSizes) { - /* Determine which block contains section */ - atUint32 sAccum = 0; - atUint32 dAccum = 0; - atUint32 cAccum = 0; - atUint32 bIdx = 0; - for (BlockInfo& info : m_blockInfos) { - atUint32 newSAccum = sAccum + info.secCount; - if (newSAccum > sec) - break; - sAccum = newSAccum; - dAccum += info.decompSize; - if (info.compSize) - cAccum += ROUND_UP_32(info.compSize); - else - cAccum += info.decompSize; - ++bIdx; - } - - /* Seek source if needed */ - if (bIdx != m_nextBlk - 1) { - m_source.seek(m_blkBase + cAccum, athena::SeekOrigin::Begin); - m_nextBlk = bIdx; - nextBlock(); - } - - /* Seek within block */ - atUint32 target = dAccum; - while (sAccum != sec) - target += secSizes[sAccum++]; - - m_pos = target; - m_posInBlk = target - dAccum; -} - -atUint64 MREA::StreamReader::readUBytesToBuf(void* buf, atUint64 len) { - atUint8* bufCur = reinterpret_cast(buf); - atUint64 rem = len; - while (rem) { - atUint64 lRem = rem; - atUint64 blkRem = m_blkSz - m_posInBlk; - if (lRem > blkRem) - lRem = blkRem; - memcpy(bufCur, &m_decompBuf[m_posInBlk], lRem); - bufCur += lRem; - rem -= lRem; - m_posInBlk += lRem; - m_pos += lRem; - if (rem) - nextBlock(); - } - return len; -} - -void MREA::StreamReader::writeDecompInfos(athena::io::IStreamWriter& writer) const { - for (const BlockInfo& info : m_blockInfos) { - BlockInfo modInfo = info; - modInfo.compSize = 0; - modInfo.write(writer); - } -} - -bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool force, - hecl::blender::Token& btok, std::function) { - using RigPair = std::pair, std::pair>; - RigPair dummy = {}; - - if (!force && outPath.isFile()) - return true; - - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount); - hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP2ORIG).getWithExtension(".decomp"); - decompPath.makeDirChain(false); - athena::io::FileWriter mreaDecompOut(decompPath.getAbsolutePath()); - head.write(mreaDecompOut); - mreaDecompOut.seekAlign32(); - drs.writeDecompInfos(mreaDecompOut); - mreaDecompOut.seekAlign32(); - atUint64 decompLen = drs.length(); - mreaDecompOut.writeBytes(drs.readBytes(decompLen).get(), decompLen); - mreaDecompOut.close(); - drs.seek(0, athena::SeekOrigin::Begin); - - /* Start up blender connection */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Area)) - return false; - - /* Calculate offset to EGMC section */ - atUint64 egmcOffset = 0; - for (unsigned i = 0; i < head.egmcSecIdx; i++) - egmcOffset += head.secSizes[i]; - - /* Load EGMC if possible so we can assign meshes to scanIds */ - drs.seek(egmcOffset, athena::SeekOrigin::Begin); - UniqueID32 egmcId(drs); - DNACommon::EGMC egmc; - pakRouter.lookupAndReadDNA(egmcId, egmc); - - drs.seek(0, athena::SeekOrigin::Begin); - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '{}'\n"), - pakRouter.getBestEntryName(entry, false)); - DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n" - "bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n" - "bpy.types.Object.retro_disable_enviro_visor = bpy.props.BoolProperty(name='Retro: Disable in Combat/Scan " - "Visor')\n" - "bpy.types.Object.retro_disable_thermal_visor = bpy.props.BoolProperty(name='Retro: Disable in Thermal " - "Visor')\n" - "bpy.types.Object.retro_disable_xray_visor = bpy.props.BoolProperty(name='Retro: Disable in X-Ray Visor')\n" - "bpy.types.Object.retro_thermal_level = bpy.props.EnumProperty(items=[('COOL', 'Cool', 'Cool Temperature')," - "('HOT', 'Hot', 'Hot Temperature')," - "('WARM', 'Warm', 'Warm Temperature')]," - "name='Retro: Thermal Visor Level')\n" - "\n"; - - /* One shared material set for all meshes */ - os << "# Materials\n" - "materials = []\n" - "\n"; - MaterialSet matSet; - atUint64 secStart = drs.position(); - matSet.read(drs); - matSet.readToBlender(os, pakRouter, entry, 0); - drs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - std::vector vertAttribs; - DNACMDL::GetVertexAttributes(matSet, vertAttribs); - - /* Read meshes */ - atUint32 curSec = 1; - for (atUint32 m = 0; m < head.meshCount; ++m) { - MeshHeader mHeader; - secStart = drs.position(); - mHeader.read(drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - curSec += DNACMDL::ReadGeomSectionsToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_2>( - os, drs, pakRouter, entry, dummy, true, true, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec]); - os.format(FMT_STRING("obj.retro_disable_enviro_visor = {}\n" - "obj.retro_disable_thermal_visor = {}\n" - "obj.retro_disable_xray_visor = {}\n" - "obj.retro_thermal_level = '{}'\n"), - mHeader.visorFlags.disableEnviro() ? "True" : "False", - mHeader.visorFlags.disableThermal() ? "True" : "False", - mHeader.visorFlags.disableXray() ? "True" : "False", mHeader.visorFlags.thermalLevelStr()); - - /* Seek through AROT-relation sections */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - } - - /* Skip AROT */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Skip BVH */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Skip Bitmap */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Skip SCLY (for now) */ - for (atUint32 l = 0; l < head.sclyLayerCount; ++l) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - } - - /* Skip SCGN (for now) */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Read collision meshes */ - DeafBabe collision; - secStart = drs.position(); - collision.read(drs); - DeafBabe::BlenderInit(os); - collision.sendToBlender(os); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Skip unknown section */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - - /* Read BABEDEAD Lights as Cycles emissives */ - secStart = drs.position(); - DNAMP1::MREA::ReadBabeDeadToBlender_1_2(os, drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Origins to center of mass */ - os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n" - "bpy.ops.object.select_by_type(type='MESH')\n" - "bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n" - "bpy.ops.object.select_all(action='DESELECT')\n" - "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n"; - - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -UniqueID32 MREA::GetPATHId(PAKEntryReadStream& rs) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount); - - /* Skip to PATH */ - drs.seekToSection(head.pathSecIdx, head.secSizes); - return {drs}; -} - -} // namespace DNAMP2 -} // namespace DataSpec diff --git a/DataSpec/DNAMP2/MREA.hpp b/DataSpec/DNAMP2/MREA.hpp deleted file mode 100644 index 088f47c0e..000000000 --- a/DataSpec/DNAMP2/MREA.hpp +++ /dev/null @@ -1,129 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CMDLMaterials.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP2 { - -struct MREA { - class StreamReader : public athena::io::IStreamReader { - protected: - struct BlockInfo : BigDNA { - AT_DECL_DNA - Value bufSize; - Value decompSize; - Value compSize; - Value secCount; - }; - std::vector m_blockInfos; - - size_t m_compBufSz; - std::unique_ptr m_compBuf; - size_t m_decompBufSz; - std::unique_ptr m_decompBuf; - athena::io::IStreamReader& m_source; - atUint64 m_blkBase; - atUint32 m_blkCount; - atUint32 m_totalDecompLen = 0; - atUint32 m_pos = 0; - - atUint32 m_nextBlk = 0; - atUint32 m_posInBlk = 0; - atUint32 m_blkSz = 0; - void nextBlock(); - - StreamReader(athena::io::IStreamReader& source) - : m_compBufSz(0x4120) - , m_compBuf(new atUint8[0x4120]) - , m_decompBufSz(0x4120) - , m_decompBuf(new atUint8[0x4120]) - , m_source(source) {} /* Empty constructor for inheriting */ - - public: - StreamReader(athena::io::IStreamReader& source, atUint32 blkCount); - void seek(atInt64 diff, athena::SeekOrigin whence) override; - void seekToSection(atUint32 sec, const std::vector& secSizes); - atUint64 position() const override { return m_pos; } - atUint64 length() const override { return m_totalDecompLen; } - atUint64 readUBytesToBuf(void* buf, atUint64 len) override; - void writeDecompInfos(athena::io::IStreamWriter& writer) const; - }; - - struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - Value localToWorldMtx[3]; - Value meshCount; - Value sclyLayerCount; - Value secCount; - Value geomSecIdx; - Value sclySecIdx; - Value scgnSecIdx; - Value collisionSecIdx; - Value unkSecIdx; - Value lightSecIdx; - Value emptySecIdx; - Value pathSecIdx; - Value unk2SecIdx; - Value unk3SecIdx; - Value egmcSecIdx; - Value compressedBlockCount; - Seek<12, athena::SeekOrigin::Current> align1; - Vector secSizes; - }; - - struct MeshHeader : BigDNA { - AT_DECL_DNA - struct VisorFlags : BigDNA { - AT_DECL_DNA - Value flags; - enum class ThermalLevel { Cool, Hot, Warm }; - static const char* GetThermalLevelStr(ThermalLevel t) { - switch (t) { - case ThermalLevel::Cool: - return "COOL"; - case ThermalLevel::Hot: - return "HOT"; - case ThermalLevel::Warm: - return "WARM"; - default: - break; - } - return nullptr; - } - bool disableEnviro() const { return flags >> 1 & 0x1; } - void setDisableEnviro(bool v) { - flags &= ~0x2; - flags |= v << 1; - } - bool disableThermal() const { return flags >> 2 & 0x1; } - void setDisableThermal(bool v) { - flags &= ~0x4; - flags |= v << 2; - } - bool disableXray() const { return flags >> 3 & 0x1; } - void setDisableXray(bool v) { - flags &= ~0x8; - flags |= v << 3; - } - ThermalLevel thermalLevel() const { return ThermalLevel(flags >> 4 & 0x3); } - void setThermalLevel(ThermalLevel v) { - flags &= ~0x30; - flags |= atUint32(v) << 4; - } - const char* thermalLevelStr() const { return GetThermalLevelStr(thermalLevel()); } - } visorFlags; - Value xfMtx[3]; - Value aabb[2]; - }; - - static UniqueID32 GetPATHId(PAKEntryReadStream& rs); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const DNAMP2::PAK::Entry& entry, bool, - hecl::blender::Token& btok, std::function); -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PAK.cpp b/DataSpec/DNAMP2/PAK.cpp deleted file mode 100644 index b7352cadc..000000000 --- a/DataSpec/DNAMP2/PAK.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "PAK.hpp" -#include "AGSC.hpp" - -namespace DataSpec::DNAMP2 { - -std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const { - std::unordered_map::const_iterator search; - if (entry.type == FOURCC('AGSC') && (search = m_entries.find(entry.id)) != m_entries.cend()) { - /* Use internal AGSC name for entry */ - auto rs = search->second.beginReadStream(pakNode); - AGSC::Header header; - header.read(rs); - catalogueName = header.groupName; - return fmt::format(FMT_STRING("{}_{}"), header.groupName, entry.id); - } - - return DNAMP1::PAK::bestEntryName(pakNode, entry, catalogueName); -} - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PAK.hpp b/DataSpec/DNAMP2/PAK.hpp deleted file mode 100644 index c2c145d41..000000000 --- a/DataSpec/DNAMP2/PAK.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "../DNAMP1/PAK.hpp" - -namespace DataSpec::DNAMP2 { - -/* Same PAK format as MP1 */ -struct PAK : DNAMP1::PAK { - using DNAMP1::PAK::PAK; - std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const; -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PATH.hpp b/DataSpec/DNAMP2/PATH.hpp deleted file mode 100644 index 676f4479d..000000000 --- a/DataSpec/DNAMP2/PATH.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "DataSpec/DNACommon/PATH.hpp" - -namespace DataSpec::DNAMP2 { -using PATH = DNAPATH::PATH; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/PTLA.hpp b/DataSpec/DNAMP2/PTLA.hpp deleted file mode 100644 index fad338ea3..000000000 --- a/DataSpec/DNAMP2/PTLA.hpp +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" - -namespace DataSpec::DNAMP2 { -struct PTLA : BigDNA { - AT_DECL_DNA - Value magic; - struct UnknownStruct1 : BigDNA { - AT_DECL_DNA - Value count; - struct Entry : BigDNA { - AT_DECL_DNA - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - }; - Vector entries; - Value unknown1; - Value unknown2[2]; - }; - Value count1; - Vector entries1; - - struct UnknownStruct2 : BigDNA { - AT_DECL_DNA - Value count; - struct Entry : BigDNA { - AT_DECL_DNA - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - }; - Vector entries; - Value unknown; - }; - Value count2; - Vector entries2; - - Value shortCount1; - Vector shorts1; - - Value shortCount2; - Vector shorts2; - - struct UnknownStruct3 : BigDNA { - AT_DECL_DNA - Value unknown1[2]; - Value unknown2; - Value unknown3; - Value unknown4; - }; - Value count3; - Vector entries3; -}; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/SAVW.hpp b/DataSpec/DNAMP2/SAVW.hpp deleted file mode 100644 index e0eea6563..000000000 --- a/DataSpec/DNAMP2/SAVW.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "../DNAMP1/SAVW.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { -struct SAVW : DNAMP1::SAVW { - AT_DECL_DNA_YAML - Value systemVarCount; - Vector systemVars; - Value gameVarCount; - Vector gameVars; - Value gameObjectCount; - Vector gameObjects; -}; -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/STRG.cpp b/DataSpec/DNAMP2/STRG.cpp deleted file mode 100644 index d48ea8fb2..000000000 --- a/DataSpec/DNAMP2/STRG.cpp +++ /dev/null @@ -1,221 +0,0 @@ -#include "STRG.hpp" -#include "DNAMP2.hpp" - -namespace DataSpec::DNAMP2 { - -void STRG::_read(athena::io::IStreamReader& reader) { - atUint32 langCount = reader.readUint32Big(); - atUint32 strCount = reader.readUint32Big(); - - std::vector readLangs; - readLangs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - DNAFourCC lang; - lang.read(reader); - readLangs.emplace_back(lang); - reader.seek(8); - } - - atUint32 nameCount = reader.readUint32Big(); - atUint32 nameTableSz = reader.readUint32Big(); - std::unique_ptr nameTableBuf(new uint8_t[nameTableSz]); - reader.readUBytesToBuf(nameTableBuf.get(), nameTableSz); - struct NameIdxEntry { - atUint32 nameOff; - atUint32 strIdx; - }* nameIndex = (NameIdxEntry*)nameTableBuf.get(); - for (atUint32 n = 0; n < nameCount; ++n) { - const char* name = (char*)(nameTableBuf.get() + hecl::SBig(nameIndex[n].nameOff)); - names[name] = hecl::SBig(nameIndex[n].strIdx); - } - - langs.clear(); - langs.reserve(langCount); - for (FourCC& lang : readLangs) { - std::vector strs; - reader.seek(strCount * 4); - for (atUint32 s = 0; s < strCount; ++s) - strs.emplace_back(reader.readU16StringBig()); - langs.emplace_back(lang, strs); - } - - langMap.clear(); - langMap.reserve(langCount); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::IStreamReader& reader) { - atUint32 magic = reader.readUint32Big(); - if (magic != 0x87654321) - Log.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - - atUint32 version = reader.readUint32Big(); - if (version != 1) - Log.report(logvisor::Error, FMT_STRING("invalid STRG version")); - - _read(reader); -} - -template <> -void STRG::Enumerate(athena::io::IStreamWriter& writer) { - writer.writeUint32Big(0x87654321); - writer.writeUint32Big(1); - writer.writeUint32Big(langs.size()); - atUint32 strCount = STRG::count(); - writer.writeUint32Big(strCount); - - atUint32 offset = 0; - for (const auto& lang : langs) { - DNAFourCC{lang.first}.write(writer); - writer.writeUint32Big(offset); - offset += strCount * 4 + 4; - atUint32 langStrCount = lang.second.size(); - atUint32 tableSz = strCount * 4; - for (atUint32 s = 0; s < strCount; ++s) { - atUint32 chCount = lang.second[s].size(); - if (s < langStrCount) { - offset += chCount * 2 + 1; - tableSz += chCount * 2 + 1; - } else { - offset += 1; - tableSz += 1; - } - } - writer.writeUint32Big(tableSz); - } - - atUint32 nameTableSz = names.size() * 8; - for (const auto& name : names) { - nameTableSz += name.first.size() + 1; - } - writer.writeUint32Big(names.size()); - writer.writeUint32Big(nameTableSz); - offset = names.size() * 8; - for (const auto& name : names) { - writer.writeUint32Big(offset); - writer.writeInt32Big(name.second); - offset += name.first.size() + 1; - } - for (const auto& name : names) { - writer.writeString(name.first); - } - - for (const auto& lang : langs) { - offset = strCount * 4; - atUint32 langStrCount = lang.second.size(); - for (atUint32 s = 0; s < strCount; ++s) { - writer.writeUint32Big(offset); - if (s < langStrCount) - offset += lang.second[s].size() * 2 + 1; - else - offset += 1; - } - - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - writer.writeU16StringBig(lang.second[s]); - else - writer.writeUByte(0); - } - } -} - -template <> -void STRG::Enumerate(size_t& __isz) { - __isz += 16; - - __isz += langs.size() * 12; - - __isz += 8; - __isz += names.size() * 8; - for (const auto& name : names) { - __isz += name.first.size() + 1; - } - - size_t strCount = STRG::count(); - for (const auto& lang : langs) { - atUint32 langStrCount = lang.second.size(); - __isz += strCount * 4; - - for (atUint32 s = 0; s < strCount; ++s) { - if (s < langStrCount) - __isz += (lang.second[s].size() + 1) * 2; - else - __isz += 1; - } - } -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocReader& reader) { - const athena::io::YAMLNode* root = reader.getRootNode(); - - /* Validate Pass */ - if (root->m_type == YAML_MAPPING_NODE) { - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "names") - continue; - if (lang.first.size() != 4) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must be exactly 4 characters; skipping"), - lang.first); - return; - } - if (lang.second->m_type != YAML_SEQUENCE_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must contain a sequence; skipping"), - lang.first); - return; - } - for (const auto& str : lang.second->m_seqChildren) { - if (str->m_type != YAML_SCALAR_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language '{}' must contain all scalars; skipping"), - lang.first); - return; - } - } - } - } else { - Log.report(logvisor::Warning, FMT_STRING("STRG must have a mapping root node; skipping")); - return; - } - - /* Read Pass */ - langs.clear(); - for (const auto& lang : root->m_mapChildren) { - std::vector strs; - for (const auto& str : lang.second->m_seqChildren) - strs.emplace_back(hecl::UTF8ToChar16(str->m_scalarString)); - langs.emplace_back(FourCC(lang.first.c_str()), strs); - } - - names.clear(); - const athena::io::YAMLNode* namesNode = root->findMapChild("names"); - if (namesNode) - for (const auto& item : namesNode->m_mapChildren) - names[item.first] = athena::io::NodeToVal(item.second.get()); - - langMap.clear(); - langMap.reserve(langs.size()); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocWriter& writer) { - for (const auto& lang : langs) { - if (auto v = writer.enterSubVector(lang.first.toString())) - for (const std::u16string& str : lang.second) - writer.writeU16String(str); - } - if (names.size()) { - if (auto rec = writer.enterSubRecord("names")) - for (const auto& name : names) - if (auto rec = writer.enterSubRecord(name.first)) - writer.writeInt32(name.second); - } -} - -std::string_view STRG::DNAType() { return "DNAMP2::STRG"sv; } - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/STRG.hpp b/DataSpec/DNAMP2/STRG.hpp deleted file mode 100644 index d740423fe..000000000 --- a/DataSpec/DNAMP2/STRG.hpp +++ /dev/null @@ -1,64 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/STRG.hpp" - -namespace DataSpec::DNAMP2 { - -struct STRG : ISTRG { - AT_DECL_EXPLICIT_DNA_YAMLV - void _read(athena::io::IStreamReader& reader); - std::vector>> langs; - std::unordered_map*> langMap; - std::map names; - - int32_t lookupIdx(std::string_view name) const override { - // TODO: Heterogeneous lookup when C++20 available - auto search = names.find(name.data()); - if (search == names.end()) - return -1; - return search->second; - } - - size_t count() const override { - size_t retval = 0; - for (const auto& item : langs) { - size_t sz = item.second.size(); - if (sz > retval) - retval = sz; - } - return retval; - } - std::string getUTF8(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return hecl::Char16ToUTF8(search->second->at(idx)); - return std::string(); - } - std::u16string getUTF16(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return search->second->at(idx); - return std::u16string(); - } - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - STRG strg; - strg.read(rs); - athena::io::TransactionalFileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(strg, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - STRG strg; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(strg, reader); - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } -}; - -} // namespace DataSpec::DNAMP2 diff --git a/DataSpec/DNAMP2/ScriptObjects/CMakeLists.txt b/DataSpec/DNAMP2/ScriptObjects/CMakeLists.txt deleted file mode 100644 index e69de29bb..000000000 diff --git a/DataSpec/DNAMP3/ANIM.cpp b/DataSpec/DNAMP3/ANIM.cpp deleted file mode 100644 index e35825894..000000000 --- a/DataSpec/DNAMP3/ANIM.cpp +++ /dev/null @@ -1,537 +0,0 @@ -#include "ANIM.hpp" -#include -#include "zeus/Math.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP3 { - -using ANIMOutStream = hecl::blender::ANIMOutStream; - -void ANIM::IANIM::sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, - bool additive) const { - os.format(FMT_STRING("act.hecl_fps = round({})\n" - "act.hecl_additive = {}\n" - "act.hecl_looping = {}\n"), - 1.0f / mainInterval, additive ? "True" : "False", looping ? "True" : "False"); - - auto kit = chanKeys.begin() + 1; - - std::vector fixedRotKeys; - std::vector fixedTransKeys; - - for (const std::pair>& bone : bones) { - const std::string* bName = rig.getCINF().getBoneNameFromId(bone.first); - if (!bName) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - continue; - } - - os.format(FMT_STRING("bone_string = '{}'\n"), *bName); - os << "action_group = act.groups.new(bone_string)\n" - "\n"; - - if (std::get<0>(bone.second)) - os << "rotCurves = []\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=0, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=1, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=2, " - "action_group=bone_string))\n" - "rotCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].rotation_quaternion', index=3, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<1>(bone.second)) - os << "transCurves = []\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=0, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=1, " - "action_group=bone_string))\n" - "transCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].location', index=2, " - "action_group=bone_string))\n" - "\n"; - - if (std::get<2>(bone.second)) - os << "scaleCurves = []\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=0, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=1, " - "action_group=bone_string))\n" - "scaleCurves.append(act.fcurves.new('pose.bones[\"'+bone_string+'\"].scale', index=2, " - "action_group=bone_string))\n" - "\n"; - - ANIMOutStream ao = os.beginANIMCurve(); - if (std::get<0>(bone.second)) { - const std::vector& rotKeys = *kit++; - fixedRotKeys.clear(); - fixedRotKeys.resize(rotKeys.size()); - - for (int c = 0; c < 4; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : rotKeys) - fixedRotKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CQuaternion& rot : fixedRotKeys) - rot = rig.invertRotation(bone.first, rot); - - for (int c = 0; c < 4; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Rotate, c, rotKeys.size()); - for (const zeus::CQuaternion& val : fixedRotKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<1>(bone.second)) { - const std::vector& transKeys = *kit++; - fixedTransKeys.clear(); - fixedTransKeys.resize(transKeys.size()); - - for (int c = 0; c < 3; ++c) { - size_t idx = 0; - for (const DNAANIM::Value& val : transKeys) - fixedTransKeys[idx++][c] = val.simd[c]; - } - - for (zeus::CVector3f& t : fixedTransKeys) - t = rig.invertPosition(bone.first, t, !additive); - - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Translate, c, fixedTransKeys.size()); - for (const zeus::CVector3f& val : fixedTransKeys) - ao.write(*frameit++, val[c]); - } - } - - if (std::get<2>(bone.second)) { - const std::vector& scaleKeys = *kit++; - for (int c = 0; c < 3; ++c) { - auto frameit = frames.begin(); - ao.changeCurve(ANIMOutStream::CurveType::Scale, c, scaleKeys.size()); - for (const DNAANIM::Value& val : scaleKeys) - ao.write(*frameit++, val.simd[c]); - } - } - } -} - -template <> -void ANIM::Enumerate(typename Read::StreamT& reader) { - atUint32 version = reader.readUint32Big(); - switch (version) { - case 0: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case 1: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("unrecognized ANIM version")); - break; - } -} - -template <> -void ANIM::Enumerate(typename Write::StreamT& writer) { - writer.writeUint32Big(m_anim->m_version); - m_anim->write(writer); -} - -template <> -void ANIM::Enumerate(typename BinarySize::StreamT& s) { - s += 4; - m_anim->binarySize(s); -} - -std::string_view ANIM::ANIM0::DNAType() { return "ANIM0"sv; } - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - mainInterval = head.interval; - - frames.clear(); - frames.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - frames.push_back(k); - - std::map boneMap; - for (size_t b = 0; b < head.boneSlotCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx == 0xff) - continue; - boneMap[idx] = b; - } - - atUint32 boneCount = reader.readUint32Big(); - bones.clear(); - bones.reserve(boneCount); - for (size_t b = 0; b < boneCount; ++b) { - bones.emplace_back(boneMap[b], std::make_tuple(false, false, false)); - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<0>(bones.back().second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<1>(bones[b].second) = true; - } - - boneCount = reader.readUint32Big(); - for (size_t b = 0; b < boneCount; ++b) { - atUint8 idx = reader.readUByte(); - if (idx != 0xff) - std::get<2>(bones[b].second) = true; - } - - channels.clear(); - chanKeys.clear(); - channels.emplace_back(); - channels.back().type = DNAANIM::Channel::Type::KfHead; - chanKeys.emplace_back(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Rotation; - chanKeys.emplace_back(); - } - if (std::get<1>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chanKeys.emplace_back(); - } - if (std::get<2>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chanKeys.emplace_back(); - } - } - - reader.readUint32Big(); - auto kit = chanKeys.begin() + 1; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - } - - reader.readUint32Big(); - kit = chanKeys.begin() + 1; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec4fBig()); - } - if (std::get<1>(bone.second)) - ++kit; - if (std::get<2>(bone.second)) - ++kit; - } - - reader.readUint32Big(); - kit = chanKeys.begin() + 1; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++kit; - if (std::get<1>(bone.second)) { - std::vector& keys = *kit++; - for (size_t k = 0; k < head.keyCount; ++k) - keys.emplace_back(reader.readVec3fBig()); - } - if (std::get<2>(bone.second)) - ++kit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(athena::io::IStreamWriter& writer) { - Header head; - head.unk0 = 0; - head.unk1 = 0; - head.unk2 = 0; - head.keyCount = frames.size(); - head.duration = head.keyCount * mainInterval; - head.interval = mainInterval; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - head.boneSlotCount = maxId + 1; - head.write(writer); - - for (size_t s = 0; s < head.boneSlotCount; ++s) { - size_t boneIdx = 0; - bool found = false; - for (const std::pair>& bone : bones) { - if (s == bone.first) { - writer.writeUByte(boneIdx); - found = true; - break; - } - ++boneIdx; - } - if (!found) - writer.writeUByte(0xff); - } - - writer.writeUint32Big(bones.size()); - size_t boneIdx = 0; - size_t rotKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - writer.writeUByte(boneIdx); - ++rotKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t transKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<1>(bone.second)) { - writer.writeUByte(boneIdx); - ++transKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(bones.size()); - boneIdx = 0; - size_t scaleKeyCount = 0; - for (const std::pair>& bone : bones) { - if (std::get<2>(bone.second)) { - writer.writeUByte(boneIdx); - ++scaleKeyCount; - } else - writer.writeUByte(0xff); - ++boneIdx; - } - - writer.writeUint32Big(scaleKeyCount * head.keyCount); - auto cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - } - - writer.writeUint32Big(rotKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec4fBig(atVec4f{(*kit++).simd}); - } - if (std::get<1>(bone.second)) - ++cit; - if (std::get<2>(bone.second)) - ++cit; - } - - writer.writeUint32Big(transKeyCount * head.keyCount); - cit = chanKeys.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - ++cit; - if (std::get<1>(bone.second)) { - const std::vector& keys = *cit++; - auto kit = keys.begin(); - for (size_t k = 0; k < head.keyCount; ++k) - writer.writeVec3fBig(atVec3f{(*kit++).simd}); - } - if (std::get<2>(bone.second)) - ++cit; - } -} - -template <> -void ANIM::ANIM0::Enumerate(size_t& __isz) { - Header head; - - atUint32 maxId = 0; - for (const std::pair>& bone : bones) - maxId = std::max(maxId, bone.first); - - head.binarySize(__isz); - __isz += maxId + 1; - __isz += bones.size() * 3 + 12; - - __isz += 12; - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) - __isz += head.keyCount * 16; - if (std::get<1>(bone.second)) - __isz += head.keyCount * 12; - if (std::get<2>(bone.second)) - __isz += head.keyCount * 12; - } -} - -static float ComputeFrames(const std::vector& keyTimes, std::vector& framesOut) { - if (keyTimes.size() <= 1) - return 0.0; - - float mainInterval = FLT_MAX; - float lastTime = keyTimes[0]; - for (auto it = keyTimes.begin() + 1; it != keyTimes.end(); ++it) { - float diff = *it - lastTime; - if (diff < mainInterval) - mainInterval = diff; - lastTime = *it; - } - - float fps = round(1.0 / mainInterval); - if (fps < 15.0) - fps = 15.0; - mainInterval = 1.0 / fps; - - framesOut.clear(); - framesOut.reserve(keyTimes.size()); - atUint32 frameAccum = 0; - for (float time : keyTimes) { - while (frameAccum * mainInterval < time) - ++frameAccum; - framesOut.push_back(frameAccum); - } - - return mainInterval; -} - -std::string_view ANIM::ANIM1::DNAType() { return "ANIM1"sv; } - -template <> -void ANIM::ANIM1::Enumerate(athena::io::IStreamReader& reader) { - Header head; - head.read(reader); - - std::vector keyTimes; - keyTimes.reserve(head.keyCount); - for (size_t k = 0; k < head.keyCount; ++k) - keyTimes.push_back(reader.readFloatBig()); - mainInterval = ComputeFrames(keyTimes, frames); - - atUint8 boneFlagCount = reader.readUByte(); - bones.clear(); - bones.reserve(boneFlagCount); - atUint32 boneChannelCount = 0; - for (atUint8 f = 0; f < boneFlagCount; ++f) { - atUint8 flag = reader.readUByte(); - bones.emplace_back(f, std::make_tuple(bool(flag & 0x1), bool(flag & 0x2), bool(flag & 0x4))); - if (flag & 0x1) - ++boneChannelCount; - if (flag & 0x2) - ++boneChannelCount; - if (flag & 0x4) - ++boneChannelCount; - } - - std::vector initBlock; - initBlock.reserve(head.initBlockSize / 2); - for (size_t i = 0; i < head.initBlockSize / 2; ++i) - initBlock.push_back(reader.readInt16Big()); - - atUint32 rawChannelCount = reader.readUint32Big(); - reader.readUint32Big(); - reader.readUint32Big(); - - std::vector chanBitCounts; - chanBitCounts.reserve(rawChannelCount); - for (size_t c = 0; c < rawChannelCount; ++c) - chanBitCounts.push_back(reader.readUByte()); - - channels.clear(); - channels.reserve(boneChannelCount + 1); - channels.emplace_back(); - channels.back().type = DNAANIM::Channel::Type::KfHead; - auto initsIt = initBlock.begin(); - auto bitsIt = chanBitCounts.begin(); - for (const std::pair>& bone : bones) { - if (std::get<0>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::RotationMP3; - chan.i[0] = *initsIt++; - chan.q[0] = *bitsIt++; - chan.i[1] = *initsIt++; - chan.q[1] = *bitsIt++; - chan.i[2] = *initsIt++; - chan.q[2] = *bitsIt++; - chan.i[3] = *initsIt++; - chan.q[3] = *bitsIt++; - } - - if (std::get<1>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Translation; - chan.i[0] = *initsIt++; - chan.q[0] = *bitsIt++; - chan.i[1] = *initsIt++; - chan.q[1] = *bitsIt++; - chan.i[2] = *initsIt++; - chan.q[2] = *bitsIt++; - } - - if (std::get<2>(bone.second)) { - channels.emplace_back(); - DNAANIM::Channel& chan = channels.back(); - chan.type = DNAANIM::Channel::Type::Scale; - chan.i[0] = *initsIt++; - chan.q[0] = *bitsIt++; - chan.i[1] = *initsIt++; - chan.q[1] = *bitsIt++; - chan.i[2] = *initsIt++; - chan.q[2] = *bitsIt++; - } - } - - size_t bsSize = DNAANIM::ComputeBitstreamSize(head.keyCount - 1, channels); - std::unique_ptr bsData = reader.readUBytes(bsSize); - DNAANIM::BitstreamReader bsReader; - chanKeys = bsReader.read(bsData.get(), head.keyCount - 1, channels, 32767, head.translationMult, head.scaleMult); -} - -template <> -void ANIM::ANIM1::Enumerate(athena::io::IStreamWriter& writer) {} - -template <> -void ANIM::ANIM1::Enumerate(size_t& __isz) {} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/ANIM.hpp b/DataSpec/DNAMP3/ANIM.hpp deleted file mode 100644 index d7cd97aba..000000000 --- a/DataSpec/DNAMP3/ANIM.hpp +++ /dev/null @@ -1,84 +0,0 @@ -#pragma once - -#include "DNAMP3.hpp" -#include "DataSpec/DNACommon/ANIM.hpp" -#include "DataSpec/DNACommon/RigInverter.hpp" -#include "CINF.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" - -namespace DataSpec::DNAMP3 { - -struct ANIM : BigDNA { - AT_DECL_EXPLICIT_DNA - - struct IANIM : BigDNAV { - Delete expl; - atUint32 m_version; - IANIM(atUint32 version) : m_version(version) {} - - std::vector>> bones; - std::vector frames; - std::vector channels; - std::vector> chanKeys; - float mainInterval = 0.0; - bool looping = false; - - void sendANIMToBlender(hecl::blender::PyOutStream&, const DNAANIM::RigInverter& rig, bool additive) const; - }; - - struct ANIM0 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM0() : IANIM(0) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value unkS; - Value duration; - Value unk0; - Value interval; - Value unk1; - Value keyCount; - Value unk2; - Value boneSlotCount; - }; - }; - - struct ANIM1 : IANIM { - AT_DECL_EXPLICIT_DNAV - ANIM1() : IANIM(1) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value unk1; - Value unk2; - Value unk3; - Value unk4[3]; - Value translationMult; - Value scaleMult; - Value unk7; - Value unk8; - Value unk9; - Value duration; - Value keyCount; - Value blobSize; - Value unk10; - Value floatsSize; - Value flagsSize; - Value initBlockSize; - Value streamSize; - Value unk11; - Value boneCount; - }; - }; - - std::unique_ptr m_anim; - - void sendANIMToBlender(hecl::blender::PyOutStream& os, const DNAANIM::RigInverter& rig, bool additive) const { - m_anim->sendANIMToBlender(os, rig, additive); - } - - void extractEVNT(const DNAANCS::AnimationResInfo& animInfo, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, bool force) const {} -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CAUD.hpp b/DataSpec/DNAMP3/CAUD.hpp deleted file mode 100644 index 6b9964849..000000000 --- a/DataSpec/DNAMP3/CAUD.hpp +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/MayaSpline.hpp" -#include "DataSpec/DNACommon/PAK.hpp" -namespace DataSpec::DNAMP3 { - -struct CAUD : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC magic; - Value version; - String<-1> name; - Value volumeGroupCount; - Vector, AT_DNA_COUNT(volumeGroupCount)> volumeGroups; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - - struct CSMPInfo : BigDNA { - AT_DECL_DNA_YAML - Value dataLen; - UniqueID64 csmpId; - Value unknown1; - Value unknown2; - Value unknown3; - Value unknown4; - Value unknown5; - Value unknown6; - Value unknown7; - Value unknown8; - Value unknown9; - Value unknown10; - Value unknown11; - Value unknown12; - Value unknown13; - Value unknown14; - Value unknown15; - Value unknown16; - Value unknown17; - Value unknown18; - Value unknown19; - MayaSpline spline1; - MayaSpline spline2; - MayaSpline spline3; - MayaSpline spline4; - Value unkStructCount; - struct UnknownStruct : BigDNA { - AT_DECL_DNA_YAML - Value unknown1; - Value unknown2; - }; - Vector unkStructs; - Value unknown20; - Value unknown21; - Value unknown22; - Value unknown23; - MayaSpline spline5; - }; - - Value infoCount; - Vector info; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - CAUD caud; - caud.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(caud, writer); - return true; - } -}; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CHAR.cpp b/DataSpec/DNAMP3/CHAR.cpp deleted file mode 100644 index c9318d5d1..000000000 --- a/DataSpec/DNAMP3/CHAR.cpp +++ /dev/null @@ -1,157 +0,0 @@ -#include "CHAR.hpp" - -namespace DataSpec::DNAMP3 { - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::IStreamReader& reader) { - EventBase::read(reader); - caudId.read(reader); - unk1 = reader.readUint32Big(); - unk2 = reader.readUint32Big(); - unk3 = reader.readUint32Big(); - reader.enumerateBig(unk3Vals, unk3); - extraType = reader.readUint32Big(); - if (extraType == 1) - extraFloat = reader.readFloatBig(); - else if (extraType == 2) - reader.seek(35, athena::SeekOrigin::Current); -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::IStreamWriter& writer) { - EventBase::write(writer); - caudId.write(writer); - writer.writeUint32Big(unk1); - writer.writeUint32Big(unk2); - writer.writeUint32Big(unk3); - writer.enumerateBig(unk3Vals); - writer.writeUint32Big(extraType); - if (extraType == 1) - writer.writeFloatBig(extraFloat); - else if (extraType == 2) - writer.seek(35, athena::SeekOrigin::Current); -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(size_t& __isz) { - EventBase::binarySize(__isz); - caudId.binarySize(__isz); - __isz += 16; - __isz += unk3Vals.size() * 4; - if (extraType == 1) - __isz += 4; - else if (extraType == 2) - __isz += 35; -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::YAMLDocReader& reader) { - EventBase::read(reader); - reader.enumerate("caudId", caudId); - unk1 = reader.readUint32("unk1"); - unk2 = reader.readUint32("unk2"); - unk3 = reader.enumerate("unk3Vals", unk3Vals); - extraType = reader.readUint32("extraType"); - if (extraType == 1) - extraFloat = reader.readFloat("extraFloat"); -} - -template <> -void CHAR::AnimationInfo::EVNT::SFXEvent::Enumerate(athena::io::YAMLDocWriter& writer) { - EventBase::write(writer); - writer.enumerate("caudId", caudId); - writer.writeUint32("unk1", unk1); - writer.writeUint32("unk2", unk2); - writer.enumerate("unk3Vals", unk3Vals); - writer.writeUint32("extraType", extraType); - if (extraType == 1) - writer.writeFloat("extraFloat", extraFloat); -} - -std::string_view CHAR::AnimationInfo::EVNT::SFXEvent::DNAType() { - return "DNAMP3::CHAR::AnimationInfo::EVNT::SFXEvent"sv; -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::IStreamReader& reader) { - const auto type = IMetaAnim::Type(reader.readUint32Big()); - switch (type) { - case IMetaAnim::Type::Primitive: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Blend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::PhaseBlend: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Random: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - case IMetaAnim::Type::Sequence: - m_anim = std::make_unique(); - m_anim->read(reader); - break; - default: - m_anim.reset(); - break; - } -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::IStreamWriter& writer) { - if (!m_anim) - return; - writer.writeInt32Big(atInt32(m_anim->m_type)); - m_anim->write(writer); -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(size_t& __isz) { - if (!m_anim) - return; - __isz += 4; - m_anim->binarySize(__isz); -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::YAMLDocReader& reader) { - std::string type = reader.readString("type"); - std::transform(type.begin(), type.end(), type.begin(), tolower); - if (type == "primitive") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "blend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "phaseblend") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "random") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else if (type == "sequence") { - m_anim = std::make_unique(); - m_anim->read(reader); - } else { - m_anim.reset(); - } -} - -template <> -void CHAR::AnimationInfo::MetaAnimFactory::Enumerate(athena::io::YAMLDocWriter& writer) { - if (!m_anim) - return; - writer.writeString("type", m_anim->m_typeStr); - m_anim->write(writer); -} - -std::string_view CHAR::AnimationInfo::MetaAnimFactory::DNAType() { - return "DNAMP3::CHAR::AnimationInfo::MetaAnimFactory"sv; -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CHAR.hpp b/DataSpec/DNAMP3/CHAR.hpp deleted file mode 100644 index a07b4f53a..000000000 --- a/DataSpec/DNAMP3/CHAR.hpp +++ /dev/null @@ -1,295 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/ANCS.hpp" -#include "CMDLMaterials.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" -#include "ANIM.hpp" -#include "../DNAMP2/ANCS.hpp" - -namespace DataSpec::DNAMP3 { - -struct CHAR : BigDNA { - using CINFType = CINF; - using CSKRType = CSKR; - using ANIMType = ANIM; - - AT_DECL_DNA_YAML - Value version; - - struct CharacterInfo : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - UniqueID64 cmdl; - UniqueID64 cskr; - Value overlayCount; - struct Overlay : BigDNA { - AT_DECL_DNA_YAML - DNAFourCC type; - UniqueID64 cmdl; - UniqueID64 cskr; - }; - Vector overlays; - UniqueID64 cinf; - UniqueID64 sand; - - using MP1CharacterInfo = DNAMP1::ANCS::CharacterSet::CharacterInfo; - MP1CharacterInfo::PASDatabase pasDatabase; - - struct ParticleResData : BigDNA { - AT_DECL_DNA_YAML - Value partCount; - Vector part; - Value swhcCount; - Vector swhc; - Value unkCount; - Vector unk; - Value elscCount; - Vector elsc; - Value spscCount; - Vector spsc; - Value unk2Count; - Vector unk2; - } partResData; - - } characterInfo; - - struct AnimationInfo : BigDNA { - AT_DECL_DNA_YAML - - struct EVNT : BigDNA { - AT_DECL_DNA_YAML - Value eventIdx; - String<-1> eventName; - - struct EventBase : BigDNA { - AT_DECL_DNA_YAML - String<-1> name1; - Value unk0; - String<-1> name2; - Value type; - Value unk1; - Value unk2; - Value unk3; - Value unk4; - Value unk5; - Value unk6; - Value unk7; - Value unk8; - Value unk9; - Value unk10; - Value unk11; - Value unk12; - Value unk13; - }; - - struct EffectEvent : EventBase { - AT_DECL_DNA_YAML - DNAFourCC effectType; - UniqueID64 effectId; - Value scale; - Value parentMode; - }; - Value effectCount; - Vector effectEvents; - - struct SFXEvent : EventBase { - AT_DECL_DNA_YAML - Delete expl; - - UniqueID64 caudId; - Value unk1_; - Value unk2_; - Value unk3_; - std::vector unk3Vals; - Value extraType; - Value extraFloat; - }; - Value sfxCount; - Vector sfxEvents; - }; - Value evntCount; - Vector evnts; - - struct IMetaAnim : BigDNAVYaml { - Delete expl; - enum class Type { Primitive = 0, Blend = 1, PhaseBlend = 2, Random = 3, Sequence = 4 } m_type; - const char* m_typeStr; - IMetaAnim(Type type, const char* typeStr) : m_type(type), m_typeStr(typeStr) {} - virtual void gatherPrimitives(std::map>& out) = 0; - }; - struct MetaAnimFactory : BigDNA { - AT_DECL_DNA_YAML - Delete expl; - std::unique_ptr m_anim; - }; - struct MetaAnimPrimitive : IMetaAnim { - MetaAnimPrimitive() : IMetaAnim(Type::Primitive, "Primitive") {} - AT_DECL_DNA_YAMLV - UniqueID64 animId; - Value animIdx; - String<-1> animName; - Value unk1; - Value unk2; - - void gatherPrimitives(std::map>& out) override { - out[animIdx] = {animName, animId, UniqueID64(), false}; - } - }; - struct MetaAnimBlend : IMetaAnim { - MetaAnimBlend() : IMetaAnim(Type::Blend, "Blend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(std::map>& out) override { - animA.m_anim->gatherPrimitives(out); - animB.m_anim->gatherPrimitives(out); - } - }; - struct MetaAnimPhaseBlend : IMetaAnim { - MetaAnimPhaseBlend() : IMetaAnim(Type::PhaseBlend, "PhaseBlend") {} - AT_DECL_DNA_YAMLV - MetaAnimFactory animA; - MetaAnimFactory animB; - Value unkFloat; - Value unk; - - void gatherPrimitives(std::map>& out) override { - animA.m_anim->gatherPrimitives(out); - animB.m_anim->gatherPrimitives(out); - } - }; - struct MetaAnimRandom : IMetaAnim { - MetaAnimRandom() : IMetaAnim(Type::Random, "Random") {} - AT_DECL_DNA_YAMLV - Value animCount; - struct Child : BigDNA { - AT_DECL_DNA_YAML - MetaAnimFactory anim; - Value probability; - }; - Vector children; - - void gatherPrimitives(std::map>& out) override { - for (const auto& child : children) - child.anim.m_anim->gatherPrimitives(out); - } - }; - struct MetaAnimSequence : IMetaAnim { - MetaAnimSequence() : IMetaAnim(Type::Sequence, "Sequence") {} - AT_DECL_DNA_YAMLV - Value animCount; - Vector children; - - void gatherPrimitives(std::map>& out) override { - for (const auto& child : children) - child.m_anim->gatherPrimitives(out); - } - }; - - struct Animation : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - MetaAnimFactory metaAnim; - }; - Value animationCount; - Vector animations; - - struct ActionAABB : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 animId; - Value aabb[2]; - }; - Value animAABBCount; - Vector animAABBs; - - Value unkByte; - - Value additiveMapCount; - Vector additiveMap; - - } animationInfo; - - struct HitboxSet : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value hitboxCount; - struct Hitbox : BigDNA { - AT_DECL_DNA_YAML - Value unk1; - Value unk2; - Value unk3; - Value unk4; - Value unk5; - Value unk6; - Value unk7; - Value unk8; - Value unk9; - Value unk10; - Value unk11; - Value unk12; - Value unk13; - String<-1> boneName; - Value unk14; - }; - Vector hitboxes; - }; - Value hitboxSetCount; - Vector hitboxSets; - - void getCharacterResInfo(std::vector>& out) const { - out.clear(); - out.reserve(1); - out.emplace_back(); - DNAANCS::CharacterResInfo& chOut = out.back(); - chOut.name = characterInfo.name; - chOut.cmdl = characterInfo.cmdl; - chOut.cskr = characterInfo.cskr; - chOut.cinf = characterInfo.cinf; - - for (const CharacterInfo::Overlay& overlay : characterInfo.overlays) - chOut.overlays.emplace_back(overlay.type.toString(), std::make_pair(overlay.cmdl, overlay.cskr)); - } - - void getAnimationResInfo(PAKRouter* pakRouter, - std::map>& out) const { - out.clear(); - for (const AnimationInfo::Animation& ai : animationInfo.animations) - ai.metaAnim.m_anim->gatherPrimitives(out); - for (auto& animRes : out) - animRes.second.additive = animationInfo.additiveMap.at(animRes.first); - } - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - hecl::ProjectPath yamlPath = outPath.getWithExtension(".yaml", true); - hecl::ProjectPath::Type yamlType = yamlPath.getPathType(); - hecl::ProjectPath blendPath = outPath.getWithExtension(".blend", true); - hecl::ProjectPath::Type blendType = blendPath.getPathType(); - - if (force || yamlType == hecl::ProjectPath::Type::None || blendType == hecl::ProjectPath::Type::None) { - CHAR aChar; - aChar.read(rs); - - if (force || yamlType == hecl::ProjectPath::Type::None) { - athena::io::FileWriter writer(yamlPath.getAbsolutePath()); - athena::io::ToYAMLStream(aChar, writer); - } - - if (force || blendType == hecl::ProjectPath::Type::None) { - DNAANCS::ReadANCSToBlender, CHAR, MaterialSet, DNACMDL::SurfaceHeader_3, 4>( - btok, aChar, blendPath, pakRouter, entry, dataSpec, fileChanged, force); - } - } - - return true; - } -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CINF.hpp b/DataSpec/DNAMP3/CINF.hpp deleted file mode 100644 index d40286143..000000000 --- a/DataSpec/DNAMP3/CINF.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNAMP2/CINF.hpp" - -namespace DataSpec::DNAMP3 { -using CINF = DNAMP2::CINF; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMDL.cpp b/DataSpec/DNAMP3/CMDL.cpp deleted file mode 100644 index 989bfa5f6..000000000 --- a/DataSpec/DNAMP3/CMDL.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "CMDL.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP3 { - -bool CMDL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function) { - /* Check for RigPair */ - CINF cinf; - CSKR cskr; - using RigPair = std::pair, std::pair>; - RigPair loadRp = {}; - if (const typename CharacterAssociations::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id)) { - pakRouter.lookupAndReadDNA(rp->cskr, cskr); - pakRouter.lookupAndReadDNA(rp->cinf, cinf); - loadRp.first = {rp->cskr, &cskr}; - loadRp.second = {rp->cinf, &cinf}; - } - - /* Do extract */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Mesh)) - return false; - DNACMDL::ReadCMDLToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_3, 5>( - conn, rs, pakRouter, entry, dataSpec, loadRp); - return conn.saveBlend(); -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMDL.hpp b/DataSpec/DNAMP3/CMDL.hpp deleted file mode 100644 index 1650c9ccb..000000000 --- a/DataSpec/DNAMP3/CMDL.hpp +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/CMDL.hpp" -#include "CMDLMaterials.hpp" -#include "DNAMP3.hpp" -#include "CINF.hpp" -#include "CSKR.hpp" - -namespace DataSpec::DNAMP3 { - -struct CMDL { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function); -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMDLMaterials.cpp b/DataSpec/DNAMP3/CMDLMaterials.cpp deleted file mode 100644 index c675f06f6..000000000 --- a/DataSpec/DNAMP3/CMDLMaterials.cpp +++ /dev/null @@ -1,310 +0,0 @@ -#include "CMDLMaterials.hpp" -#include "hecl/Blender/Connection.hpp" - -using Stream = hecl::blender::PyOutStream; - -namespace DataSpec::DNAMP3 { -using Material = MaterialSet::Material; - -template <> -void MaterialSet::Material::Enumerate(typename Read::StreamT& reader) { - header.read(reader); - chunks.clear(); - do { - chunks.emplace_back().read(reader); - } while (!chunks.back().holds_alternative()); - chunks.pop_back(); -} -template <> -void MaterialSet::Material::Enumerate(typename Write::StreamT& writer) { - header.write(writer); - for (const auto& chunk : chunks) - chunk.visit([&](auto& arg) { arg.write(writer); }); - DNAFourCC(FOURCC('END ')).write(writer); -} -template <> -void MaterialSet::Material::Enumerate(typename BinarySize::StreamT& s) { - header.binarySize(s); - for (const auto& chunk : chunks) - chunk.visit([&](auto& arg) { arg.binarySize(s); }); - s += 4; -} - -void MaterialSet::RegisterMaterialProps(Stream& out) { - out << "bpy.types.Material.retro_enable_bloom = bpy.props.BoolProperty(name='Retro: Enable Bloom')\n" - "bpy.types.Material.retro_force_lighting_stage = bpy.props.BoolProperty(name='Retro: Force Lighting Stage')\n" - "bpy.types.Material.retro_pre_inca_transparency = bpy.props.BoolProperty(name='Retro: Pre-INCA " - "Transparency')\n" - "bpy.types.Material.retro_alpha_test = bpy.props.BoolProperty(name='Retro: Alpha Test')\n" - "bpy.types.Material.retro_shadow_occluder = bpy.props.BoolProperty(name='Retro: Shadow Occluder')\n" - "bpy.types.Material.retro_solid_white = bpy.props.BoolProperty(name='Retro: Solid White Only')\n" - "bpy.types.Material.retro_reflection_alpha_target = bpy.props.BoolProperty(name='Retro: Reflection Alpha " - "Target')\n" - "bpy.types.Material.retro_solid_color = bpy.props.BoolProperty(name='Retro: Solid Color Only')\n" - "bpy.types.Material.retro_exclude_scan = bpy.props.BoolProperty(name='Retro: Exclude From Scan Visor')\n" - "bpy.types.Material.retro_xray_opaque = bpy.props.BoolProperty(name='Retro: XRay Opaque')\n" - "bpy.types.Material.retro_xray_alpha_target = bpy.props.BoolProperty(name='Retro: XRay Alpha Target')\n" - "bpy.types.Material.retro_inca_color_mod = bpy.props.BoolProperty(name='Retro: INCA Color Mod')\n" - "\n"; -} - -static void LoadTexture(Stream& out, const UniqueID64& tex, const PAKRouter& pakRouter, - const PAK::Entry& entry) { - if (!tex.isValid()) { - out << "image = None\n"; - return; - } - std::string texName = pakRouter.getBestEntryName(tex); - const nod::Node* node; - const typename PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(tex, &node); - hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry); - if (!txtrPath.isNone()) { - txtrPath.makeDirChain(false); - PAKEntryReadStream rs = texEntry->beginReadStream(*node); - TXTR::Extract(rs, txtrPath); - } - std::string resPath = pakRouter.getResourceRelativePath(entry, tex); - out.format(FMT_STRING("if '{}' in bpy.data.images:\n" - " image = bpy.data.images['{}']\n" - "else:\n" - " image = bpy.data.images.load('''//{}''')\n" - " image.name = '{}'\n" - "\n"), - texName, texName, resPath, texName); -} - -void MaterialSet::ConstructMaterial(Stream& out, const PAKRouter& pakRouter, const PAK::Entry& entry, - const Material& material, unsigned groupIdx, unsigned matIdx) { - out.format(FMT_STRING("new_material = bpy.data.materials.new('MAT_{}_{}')\n"), groupIdx, matIdx); - out << "new_material.use_fake_user = True\n" - "new_material.use_nodes = True\n" - "new_material.use_backface_culling = True\n" - "new_material.show_transparent_back = False\n" - "new_material.blend_method = 'BLEND'\n" - "new_nodetree = new_material.node_tree\n" - "for n in new_nodetree.nodes:\n" - " new_nodetree.nodes.remove(n)\n" - "\n" - "gridder = hecl.Nodegrid(new_nodetree)\n" - "new_nodetree.nodes.remove(gridder.frames[2])\n" - "\n" - "texture_nodes = []\n" - "kcolors = {}\n" - "kalphas = {}\n" - "tex_links = []\n" - "\n"; - - /* Material Flags */ - out.format(FMT_STRING("new_material.retro_enable_bloom = {}\n" - "new_material.retro_force_lighting_stage = {}\n" - "new_material.retro_pre_inca_transparency = {}\n" - "new_material.retro_alpha_test = {}\n" - "new_material.retro_shadow_occluder = {}\n" - "new_material.retro_solid_white = {}\n" - "new_material.retro_reflection_alpha_target = {}\n" - "new_material.retro_solid_color = {}\n" - "new_material.retro_exclude_scan = {}\n" - "new_material.retro_xray_opaque = {}\n" - "new_material.retro_xray_alpha_target = {}\n" - "new_material.retro_inca_color_mod = False\n"), - material.header.flags.enableBloom() ? "True" : "False", - material.header.flags.forceLightingStage() ? "True" : "False", - material.header.flags.preIncaTransparency() ? "True" : "False", - material.header.flags.alphaTest() ? "True" : "False", - material.header.flags.shadowOccluderMesh() ? "True" : "False", - material.header.flags.justWhite() ? "True" : "False", - material.header.flags.reflectionAlphaTarget() ? "True" : "False", - material.header.flags.justSolidColor() ? "True" : "False", - material.header.flags.excludeFromScanVisor() ? "True" : "False", - material.header.flags.xrayOpaque() ? "True" : "False", - material.header.flags.xrayAlphaTarget() ? "True" : "False"); - - out << "pnode = new_nodetree.nodes.new('ShaderNodeGroup')\n" - "pnode.name = 'Output'\n" - "pnode.node_tree = bpy.data.node_groups['RetroShaderMP3']\n" - "gridder.place_node(pnode, 1)\n"; - - if (material.header.flags.additiveIncandecence()) - out << "pnode.inputs['Add INCA'].default_value = 1\n"; - - int texMtxIdx = 0; - for (const auto& chunk : material.chunks) { - if (const Material::PASS* pass = chunk.get_if()) { - LoadTexture(out, pass->txtrId, pakRouter, entry); - out << "# Texture\n" - "tex_node = new_nodetree.nodes.new('ShaderNodeTexImage')\n" - "texture_nodes.append(tex_node)\n" - "tex_node.image = image\n"; - - if (!pass->uvAnim.empty()) { - const auto& uva = pass->uvAnim[0]; - switch (uva.uvSource) { - case Material::UVAnimationUVSource::Position: - default: - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Window'], tex_node.inputs['Vector']))\n"; - break; - case Material::UVAnimationUVSource::Normal: - out << "tex_uv_node = new_nodetree.nodes.new('ShaderNodeTexCoord')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['Normal'], tex_node.inputs['Vector']))\n"; - break; - case Material::UVAnimationUVSource::UV: - out.format( - FMT_STRING( - "tex_uv_node = new_nodetree.nodes.new('ShaderNodeUVMap')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['UV'], tex_node.inputs['Vector']))\n" - "tex_uv_node.uv_map = 'UV_{}'\n"), - pass->uvSrc); - break; - } - out.format(FMT_STRING("tex_uv_node.label = 'MTX_{}'\n"), texMtxIdx); - } else { - out.format( - FMT_STRING( - "tex_uv_node = new_nodetree.nodes.new('ShaderNodeUVMap')\n" - "tex_links.append(new_nodetree.links.new(tex_uv_node.outputs['UV'], tex_node.inputs['Vector']))\n" - "tex_uv_node.uv_map = 'UV_{}'\n"), - pass->uvSrc); - } - - out << "gridder.place_node(tex_uv_node, 0)\n" - "gridder.place_node(tex_node, 0)\n" - "tex_uv_node.location[0] -= 120\n" - "tex_node.location[0] += 120\n" - "tex_node.location[1] += 176\n" - "\n"; - - if (!pass->uvAnim.empty()) { - const auto& uva = pass->uvAnim[0]; - DNAMP1::MaterialSet::Material::AddTextureAnim(out, uva.anim.mode, texMtxIdx++, uva.anim.vals); - } - - auto DoSwap = [&]() { - if (pass->flags.swapColorComponent() == Material::SwapColorComponent::Alpha) { - out << "swap_output = tex_node.outputs['Alpha']\n"; - } else { - out << "separate_node = new_nodetree.nodes.new('ShaderNodeSeparateRGB')\n" - "gridder.place_node(separate_node, 0, False)\n" - "separate_node.location[0] += 350\n" - "separate_node.location[1] += 350\n" - "new_nodetree.links.new(tex_node.outputs['Color'], separate_node.inputs[0])\n"; - out.format(FMT_STRING("swap_output = separate_node.outputs[{}]\n"), int(pass->flags.swapColorComponent())); - } - }; - - using Subtype = Material::PASS::Subtype; - switch (Subtype(pass->subtype.toUint32())) { - case Subtype::DIFF: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['DIFFC'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['DIFFA'])\n"; - break; - case Subtype::BLOL: - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['BLOL'])\n"; - break; - case Subtype::BLOD: - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['BLOD'])\n"; - break; - case Subtype::CLR: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['CLR'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['CLRA'])\n"; - break; - case Subtype::TRAN: - DoSwap(); - if (pass->flags.TRANInvert()) - out << "invert_node = new_nodetree.nodes.new('ShaderNodeInvert')\n" - "gridder.place_node(invert_node, 0, False)\n" - "invert_node.location[0] += 400\n" - "invert_node.location[1] += 350\n" - "new_nodetree.links.new(swap_output, invert_node.inputs['Color'])\n" - "swap_output = invert_node.outputs['Color']\n"; - out << "new_nodetree.links.new(swap_output, pnode.inputs['TRAN'])\n"; - break; - case Subtype::INCA: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['INCAC'])\n"; - if (pass->flags.alphaContribution()) { - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['INCAA'])\n"; - } - out.format(FMT_STRING("new_material.retro_inca_color_mod = {}\n"), - pass->flags.INCAColorMod() ? "True" : "False"); - break; - case Subtype::RFLV: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['RFLV'])\n"; - break; - case Subtype::RFLD: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['RFLD'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['RFLDA'])\n"; - break; - case Subtype::LRLD: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['LRLD'])\n"; - break; - case Subtype::LURD: - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['LURDC'])\n" - "new_nodetree.links.new(tex_node.outputs['Alpha'], pnode.inputs['LURDA'])\n"; - break; - case Subtype::BLOI: - DoSwap(); - out << "new_nodetree.links.new(swap_output, pnode.inputs['BLOI'])\n"; - break; - case Subtype::XRAY: - DoSwap(); - out << "new_nodetree.links.new(tex_node.outputs['Color'], pnode.inputs['XRAYC'])\n" - "new_nodetree.links.new(swap_output, pnode.inputs['XRAYA'])\n"; - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unknown PASS subtype")); - break; - } - } else if (const Material::CLR* clr = chunk.get_if()) { - using Subtype = Material::CLR::Subtype; - athena::simd_floats vec4; - clr->color.toVec4f().simd.copy_to(vec4); - switch (Subtype(clr->subtype.toUint32())) { - case Subtype::CLR: - out.format(FMT_STRING("pnode.inputs['CLR'].default_value = ({}, {}, {}, 1.0)\n" - "pnode.inputs['CLRA'].default_value = {}\n"), - vec4[0], vec4[1], vec4[2], vec4[3]); - break; - case Subtype::DIFB: - out.format(FMT_STRING("pnode.inputs['DIFBC'].default_value = ({}, {}, {}, 1.0)\n" - "pnode.inputs['DIFBA'].default_value = {}\n"), - vec4[0], vec4[1], vec4[2], vec4[3]); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unknown CLR subtype")); - break; - } - } else if (const Material::INT* val = chunk.get_if()) { - using Subtype = Material::INT::Subtype; - switch (Subtype(val->subtype.toUint32())) { - case Subtype::OPAC: - out.format(FMT_STRING("pnode.inputs['OPAC'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::BLOD: - out.format(FMT_STRING("pnode.inputs['BLOD'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::BLOI: - out.format(FMT_STRING("pnode.inputs['BLOI'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::BNIF: - out.format(FMT_STRING("pnode.inputs['BNIF'].default_value = {}\n"), val->value / 255.f); - break; - case Subtype::XRBR: - out.format(FMT_STRING("pnode.inputs['XRBR'].default_value = {}\n"), val->value / 255.f); - break; - default: - Log.report(logvisor::Fatal, FMT_STRING("Unknown INT subtype")); - break; - } - } - } -} - -} // namespace DataSpec::DNAMP3 - -AT_SPECIALIZE_TYPED_VARIANT_BIGDNA(DataSpec::DNAMP3::MaterialSet::Material::PASS, - DataSpec::DNAMP3::MaterialSet::Material::CLR, - DataSpec::DNAMP3::MaterialSet::Material::INT, - DataSpec::DNAMP3::MaterialSet::Material::END) diff --git a/DataSpec/DNAMP3/CMDLMaterials.hpp b/DataSpec/DNAMP3/CMDLMaterials.hpp deleted file mode 100644 index f933974a7..000000000 --- a/DataSpec/DNAMP3/CMDLMaterials.hpp +++ /dev/null @@ -1,202 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/GX.hpp" -#include "../DNAMP1/CMDLMaterials.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -struct MaterialSet : BigDNA { - static constexpr bool OneSection() { return true; } - - AT_DECL_DNA - Value materialCount; - - /* Dummy methods from MP1/2 */ - void addTexture(const UniqueID32&) {} - void addMaterialEndOff(atUint32) { ++materialCount; } - - struct Material : BigDNA { - enum class SwapColorComponent { Red, Green, Blue, Alpha }; - enum class UVAnimationUVSource : atUint16 { Position, Normal, UV }; - enum class UVAnimationMatrixConfig : atUint16 { NoMtxNoPost, MtxNoPost, NoMtxPost, MtxPost }; - - AT_DECL_EXPLICIT_DNA - using VAFlags = DNAMP1::MaterialSet::Material::VAFlags; - struct Header : BigDNA { - AT_DECL_DNA - Value size; - struct Flags : BigDNA { - AT_DECL_DNA - Value flags; - bool enableBloom() const { return (flags & 0x1) != 0; } - void setEnableBloom(bool enabled) { - flags &= ~0x1; - flags |= atUint32(enabled) << 0; - } - bool forceLightingStage() const { return (flags & 0x4) != 0; } - void setForceLightingStage(bool enabled) { - flags &= ~0x4; - flags |= atUint32(enabled) << 2; - } - bool preIncaTransparency() const { return (flags & 0x8) != 0; } - void setPreIncaTransparency(bool enabled) { - flags &= ~0x8; - flags |= atUint32(enabled) << 3; - } - bool alphaTest() const { return (flags & 0x10) != 0; } - void setPunchthroughAlpha(bool enabled) { - flags &= ~0x10; - flags |= atUint32(enabled) << 4; - } - bool additiveIncandecence() const { return (flags & 0x20) != 0; } - void setAdditiveIncandecence(bool enabled) { - flags &= ~0x20; - flags |= atUint32(enabled) << 5; - } - bool shadowOccluderMesh() const { return (flags & 0x100) != 0; } - void setShadowOccluderMesh(bool enabled) { - flags &= ~0x100; - flags |= atUint32(enabled) << 8; - } - bool justWhite() const { return (flags & 0x200) != 0; } - void setJustWhite(bool enabled) { - flags &= ~0x200; - flags |= atUint32(enabled) << 9; - } - bool reflectionAlphaTarget() const { return (flags & 0x400) != 0; } - void setReflectionAlphaTarget(bool enabled) { - flags &= ~0x400; - flags |= atUint32(enabled) << 10; - } - bool justSolidColor() const { return (flags & 0x800) != 0; } - void setJustSolidColor(bool enabled) { - flags &= ~0x800; - flags |= atUint32(enabled) << 11; - } - bool excludeFromScanVisor() const { return (flags & 0x4000) != 0; } - void setExcludeFromScanVisor(bool enabled) { - flags &= ~0x4000; - flags |= atUint32(enabled) << 14; - } - bool xrayOpaque() const { return (flags & 0x8000) != 0; } - void setXRayOpaque(bool enabled) { - flags &= ~0x8000; - flags |= atUint32(enabled) << 15; - } - bool xrayAlphaTarget() const { return (flags & 0x10000) != 0; } - void setXRayAlphaTarget(bool enabled) { - flags &= ~0x10000; - flags |= atUint32(enabled) << 16; - } - bool lightmapUVArray() const { return false; } /* For polymorphic compatibility with MP1/2 */ - } flags; - Value uniqueIdx; - Value unk1; - VAFlags vaFlags; - Value unk2; - Value unk3; - Value unk4; - } header; - const Header::Flags& getFlags() const { return header.flags; } - const VAFlags& getVAFlags() const { return header.vaFlags; } - - enum class ChunkType : atUint32 { PASS = 'PASS', CLR = 'CLR ', INT = 'INT ', END = 'END ' }; - - struct PASS : hecl::TypedRecordBigDNA { - AT_DECL_DNA - Value size; - enum class Subtype : atUint32 { - DIFF = SBIG('DIFF'), - RIML = SBIG('RIML'), - BLOL = SBIG('BLOL'), - BLOD = SBIG('BLOD'), - CLR = SBIG('CLR '), - TRAN = SBIG('TRAN'), - INCA = SBIG('INCA'), - RFLV = SBIG('RFLV'), - RFLD = SBIG('RFLD'), - LRLD = SBIG('LRLD'), - LURD = SBIG('LURD'), - BLOI = SBIG('BLOI'), - XRAY = SBIG('XRAY'), - TOON = SBIG('TOON') - }; - DNAFourCC subtype; - struct Flags : BigDNA { - AT_DECL_DNA - Value flags; - SwapColorComponent swapColorComponent() const { return SwapColorComponent(flags & 0x3); } - void setSwapColorComponent(SwapColorComponent comp) { - flags &= ~0x3; - flags |= atUint32(comp) << 0; - } - bool alphaContribution() const { return (flags & 0x4) != 0; } - void setAlphaContribution(bool enabled) { - flags &= ~0x4; - flags |= atUint32(enabled) << 2; - } - bool INCAColorMod() const { return (flags & 0x8) != 0; } - void setINCAColorMod(bool enabled) { - flags &= ~0x8; - flags |= atUint32(enabled) << 3; - } - bool TRANInvert() const { return (flags & 0x10) != 0; } - void setTRANInvert(bool enabled) { - flags &= ~0x10; - flags |= atUint32(enabled) << 4; - } - } flags; - UniqueID64 txtrId; - Value uvSrc; - Value uvAnimSize; - struct UVAnimation : BigDNA { - AT_DECL_DNA - Value uvSource; - Value mtxConfig; - DNAMP1::MaterialSet::Material::UVAnimation anim; - }; - Vector uvAnim; - }; - struct CLR : hecl::TypedRecordBigDNA { - AT_DECL_DNA - enum class Subtype : atUint32 { CLR = SBIG('CLR '), DIFB = SBIG('DIFB') }; - DNAFourCC subtype; - GX::Color color; - CLR() = default; - }; - struct INT : hecl::TypedRecordBigDNA { - AT_DECL_DNA - enum class Subtype : atUint32 { - OPAC = SBIG('OPAC'), - BLOD = SBIG('BLOD'), - BLOI = SBIG('BLOI'), - BNIF = SBIG('BNIF'), - XRBR = SBIG('XRBR') - }; - DNAFourCC subtype; - Value value; - }; - struct END : hecl::TypedRecordBigDNA { - AT_DECL_DNA - }; - using Chunk = hecl::TypedVariantBigDNA; - std::vector chunks; - }; - Vector materials; - - static void RegisterMaterialProps(hecl::blender::PyOutStream& out); - static void ConstructMaterial(hecl::blender::PyOutStream& out, const PAKRouter& pakRouter, - const PAK::Entry& entry, const MaterialSet::Material& material, unsigned groupIdx, - unsigned matIdx); - - void readToBlender(hecl::blender::PyOutStream& os, const PAKRouter& pakRouter, - const PAKRouter::EntryType& entry, unsigned setIdx) { - DNACMDL::ReadMaterialSetToBlender_3(os, *this, pakRouter, entry, setIdx); - } - - void ensureTexturesExtracted(PAKRouter& pakRouter) const {} -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CMakeLists.txt b/DataSpec/DNAMP3/CMakeLists.txt deleted file mode 100644 index 68a9cf943..000000000 --- a/DataSpec/DNAMP3/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -make_dnalist(PAK - MLVL - ANIM - CHAR - CMDLMaterials - CINF - CSKR - MREA - SAVW - CAUD - HINT - SAND) -set(DNAMP3_SOURCES - DNAMP3.hpp DNAMP3.cpp - PAK.cpp - ANIM.cpp - CINF.hpp - CHAR.cpp - CMDL.hpp CMDL.cpp - CMDLMaterials.cpp - CSKR.cpp - PATH.hpp - STRG.hpp STRG.cpp - MAPA.hpp - MREA.cpp) - -dataspec_add_list(DNAMP3 DNAMP3_SOURCES) diff --git a/DataSpec/DNAMP3/CSKR.cpp b/DataSpec/DNAMP3/CSKR.cpp deleted file mode 100644 index 11711dd5d..000000000 --- a/DataSpec/DNAMP3/CSKR.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include "CSKR.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec::DNAMP3 { - -void CSKR::weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atInt16 skinIdx) const { - if (skinIdx < 0) - return; - const DNAMP2::CSKR::SkinningRule& rule = data.skinningRules[skinIdx]; - for (const DNAMP2::CSKR::SkinningRule::Weight& weight : rule.weights) - os.format(FMT_STRING("vert[dvert_lay][{}] = {}\n"), cinf.getBoneIdxFromId(weight.boneId), weight.weight); -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/CSKR.hpp b/DataSpec/DNAMP3/CSKR.hpp deleted file mode 100644 index 2de889e0c..000000000 --- a/DataSpec/DNAMP3/CSKR.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CINF.hpp" -#include "../DNAMP2/CSKR.hpp" - -namespace DataSpec::DNAMP3 { - -struct CSKR : BigDNA { - AT_DECL_DNA - DNAFourCC magic; - Value version; - DNAMP2::CSKR data; - Value matrixCount; - struct MatrixBindings : BigDNA { - AT_DECL_DNA - Value mtxs[10]; - }; - Vector mtxBindings; - - Value unkCount1; - Vector unk1; - Value unkCount2; - Vector unk2; - Value unkCount3; - Vector unk3; - Value unkCount4; - Vector unk4; - Value unkCount5; - Vector unk5; - - const atInt16* getMatrixBank(size_t idx) const { return mtxBindings.at(idx).mtxs; } - - void weightVertex(hecl::blender::PyOutStream& os, const CINF& cinf, atInt16 skinIdx) const; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/DNAMP3.cpp b/DataSpec/DNAMP3/DNAMP3.cpp deleted file mode 100644 index dc98b26e6..000000000 --- a/DataSpec/DNAMP3/DNAMP3.cpp +++ /dev/null @@ -1,273 +0,0 @@ -#include - -#define NOD_ATHENA 1 -#include "DNAMP3.hpp" -#include "STRG.hpp" -#include "MLVL.hpp" -#include "CAUD.hpp" -#include "CMDL.hpp" -#include "CHAR.hpp" -#include "MREA.hpp" -#include "MAPA.hpp" -#include "PATH.hpp" -#include "SAVW.hpp" -#include "HINT.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/FONT.hpp" -#include "DataSpec/DNACommon/FSM2.hpp" -#include "DataSpec/DNACommon/DGRP.hpp" -#include "Runtime/GCNTypes.hpp" - -namespace DataSpec::DNAMP3 { -logvisor::Module Log("DataSpec::DNAMP3"); - -static bool GetNoShare(std::string_view name) { - std::string lowerName(name); - std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower); - return !lowerName.starts_with("metroid"sv) && !lowerName.starts_with("frontend"sv) && - !lowerName.starts_with("rs5fe"sv) && !lowerName.starts_with("universearea"sv) && - !lowerName.starts_with("mp1fe"sv); -} - -PAKBridge::PAKBridge(const nod::Node& node, bool doExtract) -: m_node(node), m_pak(GetNoShare(node.getName())), m_doExtract(doExtract) { - nod::AthenaPartReadStream rs(node.beginReadStream()); - m_pak.read(rs); - - /* Append Level String */ - std::set uniq; - for (auto& ent : m_pak.m_entries) { - PAK::Entry& entry = ent.second; - if (entry.type == FOURCC('MLVL')) { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - MLVL mlvl; - mlvl.read(rs); - const PAK::Entry* nameEnt = m_pak.lookupEntry(mlvl.worldNameId); - if (nameEnt) { - PAKEntryReadStream rs = nameEnt->beginReadStream(m_node); - STRG mlvlName; - mlvlName.read(rs); - uniq.insert(mlvlName.getUTF8(FOURCC('ENGL'), 0)); - } - } - } - bool comma = false; - for (const std::string& str : uniq) { - if (comma) - m_levelString += ", "; - comma = true; - m_levelString += str; - } -} - -static std::string LayerName(std::string_view name) { - std::string ret(name); - for (auto& ch : ret) - if (ch == '/' || ch == '\\') - ch = '-'; - return ret; -} - -void PAKBridge::build() { - /* First pass: build per-area/per-layer dependency map */ - for (const auto& ent : m_pak.m_entries) { - const PAK::Entry& entry = ent.second; - if (entry.type == FOURCC('MLVL')) { - Level& level = m_levelDeps[entry.id]; - - MLVL mlvl; - { - PAKEntryReadStream rs = entry.beginReadStream(m_node); - mlvl.read(rs); - } - std::string catalogueName; - std::string bestName = m_pak.bestEntryName(m_node, entry, catalogueName); - level.name = bestName; - level.areas.reserve(mlvl.areaCount); - unsigned layerIdx = 0; - - /* Make MAPW available to lookup MAPAs */ - const PAK::Entry* worldMapEnt = m_pak.lookupEntry(mlvl.worldMap); - std::vector mapw; - if (worldMapEnt) { - PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node); - rs.seek(8, athena::SeekOrigin::Current); - atUint32 areaCount = rs.readUint32Big(); - mapw.reserve(areaCount); - for (atUint32 i = 0; i < areaCount; ++i) - mapw.emplace_back(rs); - } - - /* Index areas */ - unsigned ai = 0; - auto layerFlagsIt = mlvl.layerFlags.begin(); - for (const MLVL::Area& area : mlvl.areas) { - Level::Area& areaDeps = level.areas[area.areaMREAId]; - const PAK::Entry* areaNameEnt = m_pak.lookupEntry(area.areaNameId); - if (areaNameEnt) { - STRG areaName; - { - PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node); - areaName.read(rs); - } - areaDeps.name = areaName.getUTF8(FOURCC('ENGL'), 0); - areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); - } - if (areaDeps.name.empty()) { - areaDeps.name = area.internalAreaName; - if (areaDeps.name.empty()) { - areaDeps.name = "MREA_" + area.areaMREAId.toString(); - } - } - std::string num = fmt::format(FMT_STRING("{:02d} "), ai); - areaDeps.name = num + areaDeps.name; - - const MLVL::LayerFlags& layerFlags = *layerFlagsIt++; - if (layerFlags.layerCount) { - areaDeps.layers.reserve(layerFlags.layerCount); - for (unsigned l = 1; l < layerFlags.layerCount; ++l) { - areaDeps.layers.emplace_back(); - Level::Area::Layer& layer = areaDeps.layers.back(); - layer.name = LayerName(mlvl.layerNames[layerIdx++]); - layer.active = layerFlags.flags >> (l - 1) & 0x1; - layer.name = hecl::StringUtils::TrimWhitespace(layer.name); - num = fmt::format(FMT_STRING("{:02d} "), l - 1); - layer.name = num + layer.name; - } - } - - /* Load area DEPS */ - const PAK::Entry* areaEntry = m_pak.lookupEntry(area.areaMREAId); - if (areaEntry) { - PAKEntryReadStream ars = areaEntry->beginReadStream(m_node); - MREA::ExtractLayerDeps(ars, areaDeps); - } - areaDeps.resources.emplace(area.areaMREAId); - if (mapw.size() > ai) - areaDeps.resources.emplace(mapw[ai]); - ++ai; - } - } - } - - /* Second pass: cross-compare uniqueness */ - for (auto& entry : m_pak.m_entries) { - entry.second.unique.checkEntry(*this, entry.second); - } -} - -void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('CHAR')) { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - CHAR aChar; - aChar.read(rs); - const CHAR::CharacterInfo& ci = aChar.characterInfo; - charAssoc.m_cmdlRigs[ci.cmdl] = {ci.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[ci.cskr] = - std::make_pair(entry.second.id, fmt::format(FMT_STRING("{}_{}.CSKR"), ci.name, ci.cskr)); - for (const CHAR::CharacterInfo::Overlay& overlay : ci.overlays) { - charAssoc.m_cmdlRigs[overlay.cmdl] = {overlay.cskr, ci.cinf}; - charAssoc.m_cskrToCharacter[overlay.cskr] = std::make_pair( - entry.second.id, fmt::format(FMT_STRING("{}.{}_{}.CSKR"), ci.name, overlay.type, overlay.cskr)); - } - } - } -} - -static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}}; - -void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, - std::unordered_map& addTo, - std::unordered_map& pathOverrides) const { - for (const auto& entry : m_pak.m_entries) { - if (entry.second.type == FOURCC('MLVL')) { - MLVL mlvl; - { - PAKEntryReadStream rs = entry.second.beginReadStream(m_node); - mlvl.read(rs); - } - hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath(); - - if (mlvl.worldNameId.isValid()) - pathOverrides[mlvl.worldNameId] = - hecl::ProjectPath(mlvlDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), mlvl.worldNameId)); - - for (const MLVL::Area& area : mlvl.areas) { - { - /* Get PATH transform */ - const nod::Node* areaNode; - const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode); - PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode); - UniqueID64 pathId = MREA::GetPATHId(rs); - if (pathId.isValid()) - addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow) - .transposed(); - } - hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); - if (area.areaNameId.isValid()) - pathOverrides[area.areaNameId] = - hecl::ProjectPath(areaDirPath, fmt::format(FMT_STRING("!name_{}.yaml"), area.areaNameId)); - } - - if (mlvl.worldMap.isValid()) { - const nod::Node* mapNode; - const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); - if (mapEntry) { - PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); - u32 magic = rs.readUint32Big(); - if (magic == 0xDEADF00D) { - rs.readUint32Big(); - u32 count = rs.readUint32Big(); - for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) { - MLVL::Area& areaData = mlvl.areas[i]; - UniqueID64 mapaId; - mapaId.read(rs); - addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1], - areaData.transformMtx[2], BottomRow) - .transposed(); - } - } - } - } - } - } -} - -ResExtractor PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) { - switch (entry.type.toUint32()) { - case SBIG('CAUD'): - return {CAUD::Extract, {".yaml"}}; - case SBIG('STRG'): - return {STRG::Extract, {".yaml"}}; - case SBIG('TXTR'): - return {TXTR::Extract, {".png"}}; - case SBIG('SAVW'): - return {SAVWCommon::ExtractSAVW, {".yaml"}}; - case SBIG('HINT'): - return {HINT::Extract, {".yaml"}}; - case SBIG('CMDL'): - return {CMDL::Extract, {".blend"}, 1}; - case SBIG('CINF'): - return {CINF::Extract, {".blend"}, 1}; - case SBIG('CHAR'): - return {CHAR::Extract, {".yaml", ".blend"}, 2}; - case SBIG('MLVL'): - return {MLVL::Extract, {".yaml", ".blend"}, 3}; - case SBIG('MREA'): - return {MREA::Extract, {".blend"}, 4}; - case SBIG('MAPA'): - return {MAPA::Extract, {".blend"}, 4}; - case SBIG('PATH'): - return {PATH::Extract, {".blend"}, 5}; - case SBIG('FSM2'): - return {DNAFSM2::ExtractFSM2, {".yaml"}}; - case SBIG('FONT'): - return {DNAFont::ExtractFONT, {".yaml"}}; - case SBIG('DGRP'): - return {DNADGRP::ExtractDGRP, {".yaml"}}; - } - return {}; -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/DNAMP3.hpp b/DataSpec/DNAMP3/DNAMP3.hpp deleted file mode 100644 index 4c399d33f..000000000 --- a/DataSpec/DNAMP3/DNAMP3.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" - -namespace DataSpec::DNAMP3 { - -extern logvisor::Module Log; - -/* MP3-specific, one-shot PAK traversal/extraction class */ -class PAKBridge { - const nod::Node& m_node; - PAK m_pak; - -public: - bool m_doExtract; - using Level = DataSpec::Level; - std::unordered_map m_levelDeps; - std::string m_levelString; - - PAKBridge(const nod::Node& node, bool doExtract = true); - void build(); - static ResExtractor LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry); - std::string_view getName() const { return m_node.getName(); } - std::string_view getLevelString() const { return m_levelString; } - - using PAKType = PAK; - const PAKType& getPAK() const { return m_pak; } - const nod::Node& getNode() const { return m_node; } - - void addCMDLRigPairs(PAKRouter& pakRouter, CharacterAssociations& charAssoc) const; - - void addMAPATransforms(PAKRouter& pakRouter, std::unordered_map& addTo, - std::unordered_map& pathOverrides) const; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/HINT.hpp b/DataSpec/DNAMP3/HINT.hpp deleted file mode 100644 index 7885f9f00..000000000 --- a/DataSpec/DNAMP3/HINT.hpp +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "PAK.hpp" - -namespace DataSpec::DNAMP3 { -struct HINT : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - - struct Hint : BigDNA { - AT_DECL_DNA_YAML - String<-1> name; - Value unknown1; - Value fadeInTime; - UniqueID64 stringID; - Value unknown2; - struct Location : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 worldAssetID; - UniqueID64 areaAssetID; - Value areaID; - UniqueID64 stringID; - Value unknown[3]; - }; - - Value locationCount; - Vector locations; - }; - Value hintCount; - Vector hints; - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - HINT hint; - hint.read(rs); - athena::io::FileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(hint, writer); - return true; - } -}; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/MAPA.hpp b/DataSpec/DNAMP3/MAPA.hpp deleted file mode 100644 index 5a7ab9b48..000000000 --- a/DataSpec/DNAMP3/MAPA.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MAPA.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { -struct MAPA : DNAMAPA::MAPA { - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MAPA mapa; - mapa.read(rs); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMAPA::ReadMAPAToBlender(conn, mapa, outPath, pakRouter, entry, force); - } - - static bool Cook(const hecl::blender::MapArea& mapa, const hecl::ProjectPath& out) { - return DNAMAPA::Cook(mapa, out); - } - - static uint32_t Version() { return 5; } - using Header = DNAMAPA::MAPA::HeaderMP3; - using MappableObject = DNAMAPA::MAPA::MappableObjectMP3; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/MLVL.hpp b/DataSpec/DNAMP3/MLVL.hpp deleted file mode 100644 index ba3f56aee..000000000 --- a/DataSpec/DNAMP3/MLVL.hpp +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/MLVL.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -struct MLVL : BigDNA { - AT_DECL_DNA_YAML - Value magic; - Value version; - UniqueID64 worldNameId; - Value unk; - UniqueID64 saveWorldId; - UniqueID64 worldSkyboxId; - - Value areaCount; - struct Area : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 areaNameId; - Value transformMtx[3]; - Value aabb[2]; - UniqueID64 areaMREAId; - Value areaId; - - Value attachedAreaCount; - Vector attachedAreas; - - Value dockCount; - struct Dock : BigDNA { - AT_DECL_DNA_YAML - Value endpointCount; - struct Endpoint : BigDNA { - AT_DECL_DNA_YAML - Value areaIdx; - Value dockIdx; - }; - Vector endpoints; - - Value planeVertCount; - Vector planeVerts; - }; - Vector docks; - - String<-1> internalAreaName; - }; - Vector areas; - - UniqueID64 worldMap; - Value unknown2; - Value unknown3; - - Value layerFlagCount; - struct LayerFlags : BigDNA { - AT_DECL_DNA_YAML - Value layerCount; - Value flags; - }; - Vector layerFlags; - - Value layerNameCount; - Vector, AT_DNA_COUNT(layerNameCount)> layerNames; - - Value layerIDCount; - struct LayerID : BigDNA { - AT_DECL_DNA_YAML - Value id[2]; - }; - Vector layerIDs; - - Value layerNameOffsetCount; - Vector layerNameOffsets; - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function fileChanged) { - MLVL mlvl; - mlvl.read(rs); - athena::io::FileWriter writer(outPath.getWithExtension(".yaml", true).getAbsolutePath()); - athena::io::ToYAMLStream(mlvl, writer); - hecl::blender::Connection& conn = btok.getBlenderConnection(); - return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged); - } -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/MREA.cpp b/DataSpec/DNAMP3/MREA.cpp deleted file mode 100644 index 45f5de33a..000000000 --- a/DataSpec/DNAMP3/MREA.cpp +++ /dev/null @@ -1,279 +0,0 @@ -#include -#include "MREA.hpp" -#include "../DNAMP2/DeafBabe.hpp" -#include "DataSpec/DNACommon/BabeDead.hpp" -#include "hecl/Blender/Connection.hpp" - -namespace DataSpec { -extern hecl::Database::DataSpecEntry SpecEntMP3ORIG; - -namespace DNAMP3 { - -MREA::StreamReader::StreamReader(athena::io::IStreamReader& source, atUint32 blkCount, atUint32 secIdxCount) -: DNAMP2::MREA::StreamReader(source) { - m_blkCount = blkCount; - m_blockInfos.reserve(blkCount); - for (atUint32 i = 0; i < blkCount; ++i) { - BlockInfo& info = m_blockInfos.emplace_back(); - info.read(source); - m_totalDecompLen += info.decompSize; - } - source.seekAlign32(); - m_secIdxs.reserve(secIdxCount); - for (atUint32 i = 0; i < secIdxCount; ++i) { - std::pair& idx = m_secIdxs.emplace_back(); - idx.first.read(source); - idx.second = source.readUint32Big(); - } - source.seekAlign32(); - m_blkBase = source.position(); - nextBlock(); -} - -void MREA::StreamReader::writeSecIdxs(athena::io::IStreamWriter& writer) const { - for (const std::pair& idx : m_secIdxs) { - idx.first.write(writer); - writer.writeUint32Big(idx.second); - } -} - -bool MREA::StreamReader::seekToSection(FourCC sec, const std::vector& secSizes) { - auto search = std::find_if(m_secIdxs.begin(), m_secIdxs.end(), [sec](const auto& s) { return s.first == sec; }); - if (search != m_secIdxs.end()) { - DNAMP2::MREA::StreamReader::seekToSection(search->second, secSizes); - return true; - } - return false; -} - -void MREA::ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs) { - atUint32 bdMagic = rs.readUint32Big(); - if (bdMagic != 0xBABEDEAD) - Log.report(logvisor::Fatal, FMT_STRING("invalid BABEDEAD magic")); - os << "bpy.context.scene.world.use_nodes = True\n" - "bg_node = bpy.context.scene.world.node_tree.nodes['Background']\n" - "bg_node.inputs[1].default_value = 0.0\n"; - for (atUint32 s = 0; s < 4; ++s) { - atUint32 lightCount = rs.readUint32Big(); - for (atUint32 l = 0; l < lightCount; ++l) { - BabeDeadLight light; - light.read(rs); - ReadBabeDeadLightToBlender(os, light, s, l); - } - } -} - -bool MREA::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool force, hecl::blender::Token& btok, - std::function) { - using RigPair = std::pair, std::pair>; - RigPair dummy = {}; - - if (!force && outPath.isFile()) - return true; - - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount); - hecl::ProjectPath decompPath = outPath.getCookedPath(SpecEntMP3ORIG).getWithExtension(".decomp"); - decompPath.makeDirChain(false); - athena::io::FileWriter mreaDecompOut(decompPath.getAbsolutePath()); - head.write(mreaDecompOut); - mreaDecompOut.seekAlign32(); - drs.writeDecompInfos(mreaDecompOut); - mreaDecompOut.seekAlign32(); - drs.writeSecIdxs(mreaDecompOut); - mreaDecompOut.seekAlign32(); - atUint64 decompLen = drs.length(); - mreaDecompOut.writeBytes(drs.readBytes(decompLen).get(), decompLen); - mreaDecompOut.close(); - drs.seek(0, athena::SeekOrigin::Begin); - - /* Start up blender connection */ - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.createBlend(outPath, hecl::blender::BlendType::Area)) - return false; - - /* Open Py Stream and read sections */ - hecl::blender::PyOutStream os = conn.beginPythonOut(true); - os.format(FMT_STRING("import bpy\n" - "import bmesh\n" - "from mathutils import Vector\n" - "\n" - "bpy.context.scene.name = '{}'\n"), - pakRouter.getBestEntryName(entry, false)); - DNACMDL::InitGeomBlenderContext(os, dataSpec.getMasterShaderPath()); - MaterialSet::RegisterMaterialProps(os); - os << "# Clear Scene\n" - "if len(bpy.data.collections):\n" - " bpy.data.collections.remove(bpy.data.collections[0])\n" - "\n" - "bpy.types.Light.retro_layer = bpy.props.IntProperty(name='Retro: Light Layer')\n" - "bpy.types.Light.retro_origtype = bpy.props.IntProperty(name='Retro: Original Type')\n" - "\n"; - - /* One shared material set for all meshes */ - os << "# Materials\n" - "materials = []\n" - "\n"; - MaterialSet matSet; - atUint64 secStart = drs.position(); - matSet.read(drs); - matSet.readToBlender(os, pakRouter, entry, 0); - drs.seek(secStart + head.secSizes[0], athena::SeekOrigin::Begin); - std::vector vertAttribs; - DNACMDL::GetVertexAttributes(matSet, vertAttribs); - - /* Read mesh info */ - atUint32 curSec = 1; - std::vector surfaceCounts; - surfaceCounts.reserve(head.meshCount); - for (atUint32 m = 0; m < head.meshCount; ++m) { - /* Mesh header */ - MeshHeader mHeader; - secStart = drs.position(); - mHeader.read(drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Surface count from here */ - secStart = drs.position(); - surfaceCounts.push_back(drs.readUint32Big()); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - - /* Seek through AROT-relation sections */ - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - } - - /* Skip though WOBJs */ - auto secIdxIt = drs.beginSecIdxs(); - while (secIdxIt->first == FOURCC('WOBJ')) - ++secIdxIt; - - /* Skip AROT */ - if (secIdxIt->first == FOURCC('ROCT')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Skip AABB */ - if (secIdxIt->first == FOURCC('AABB')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Now the meshes themselves */ - if (secIdxIt->first == FOURCC('GPUD')) { - for (atUint32 m = 0; m < head.meshCount; ++m) { - curSec += - DNACMDL::ReadGeomSectionsToBlender, MaterialSet, RigPair, DNACMDL::SurfaceHeader_3>( - os, drs, pakRouter, entry, dummy, true, false, vertAttribs, m, head.secCount, 0, &head.secSizes[curSec], - surfaceCounts[m]); - } - ++secIdxIt; - } - - /* Skip DEPS */ - if (secIdxIt->first == FOURCC('DEPS')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Skip SOBJ (SCLY) */ - if (secIdxIt->first == FOURCC('SOBJ')) { - for (atUint32 l = 0; l < head.sclyLayerCount; ++l) - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Skip SGEN */ - if (secIdxIt->first == FOURCC('SGEN')) { - drs.seek(head.secSizes[curSec++], athena::SeekOrigin::Current); - ++secIdxIt; - } - - /* Read Collision Meshes */ - if (secIdxIt->first == FOURCC('COLI')) { - DNAMP2::DeafBabe collision; - secStart = drs.position(); - collision.read(drs); - DNAMP2::DeafBabe::BlenderInit(os); - collision.sendToBlender(os); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - ++secIdxIt; - } - - /* Read BABEDEAD Lights as Cycles emissives */ - if (secIdxIt->first == FOURCC('LITE')) { - secStart = drs.position(); - ReadBabeDeadToBlender_3(os, drs); - drs.seek(secStart + head.secSizes[curSec++], athena::SeekOrigin::Begin); - ++secIdxIt; - } - - /* Origins to center of mass */ - os << "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = False\n" - "bpy.ops.object.select_by_type(type='MESH')\n" - "bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_MASS')\n" - "bpy.ops.object.select_all(action='DESELECT')\n" - "bpy.context.view_layer.layer_collection.children['Collision'].hide_viewport = True\n"; - - os.centerView(); - os.close(); - return conn.saveBlend(); -} - -bool MREA::ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount); - for (const std::pair& idx : drs.m_secIdxs) { - if (idx.first == FOURCC('DEPS')) { - drs.seek(head.getSecOffset(idx.second), athena::SeekOrigin::Begin); - DEPS deps; - deps.read(drs); - - unsigned r = 0; - for (unsigned l = 1; l < deps.depLayerCount; ++l) { - if (l > areaOut.layers.size()) - break; - PAKBridge::Level::Area::Layer& layer = areaOut.layers.at(l - 1); - layer.resources.reserve(deps.depLayers[l] - r); - for (; r < deps.depLayers[l]; ++r) - layer.resources.emplace(deps.deps[r].id); - } - areaOut.resources.reserve(deps.depCount - r + 2); - for (; r < deps.depCount; ++r) - areaOut.resources.emplace(deps.deps[r].id); - - return true; - } - } - return false; -} - -UniqueID64 MREA::GetPATHId(PAKEntryReadStream& rs) { - /* Do extract */ - Header head; - head.read(rs); - rs.seekAlign32(); - - /* MREA decompression stream */ - StreamReader drs(rs, head.compressedBlockCount, head.secIndexCount); - - /* Skip to PATH */ - if (drs.seekToSection(FOURCC('PFL2'), head.secSizes)) - return {drs}; - return {}; -} - -} // namespace DNAMP3 -} // namespace DataSpec diff --git a/DataSpec/DNAMP3/MREA.hpp b/DataSpec/DNAMP3/MREA.hpp deleted file mode 100644 index 2fb0ebf9b..000000000 --- a/DataSpec/DNAMP3/MREA.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "CMDLMaterials.hpp" -#include "CSKR.hpp" -#include "../DNAMP2/MREA.hpp" - -namespace DataSpec::DNAMP3 { - -struct MREA { - struct StreamReader : DNAMP2::MREA::StreamReader { - std::vector> m_secIdxs; - StreamReader(athena::io::IStreamReader& source, atUint32 blkCount, atUint32 secIdxCount); - std::vector>::const_iterator beginSecIdxs() { return m_secIdxs.begin(); } - void writeSecIdxs(athena::io::IStreamWriter& writer) const; - bool seekToSection(FourCC sec, const std::vector& secSizes); - }; - - struct Header : BigDNA { - AT_DECL_DNA - Value magic; - Value version; - Value localToWorldMtx[3]; - Value meshCount; - Value sclyLayerCount; - Value secCount; - Value compressedBlockCount; - Value secIndexCount; - Seek<20, athena::SeekOrigin::Current> align1; - Vector secSizes; - - atUint32 getSecOffset(atUint32 idx) const { - if (idx >= secSizes.size()) - return -1; - atUint32 retval = 0; - for (atUint32 i = 0; i < idx; ++i) - retval += secSizes[i]; - return retval; - } - }; - - struct MeshHeader : BigDNA { - AT_DECL_DNA - struct VisorFlags : BigDNA { - AT_DECL_DNA - Value flags; - } visorFlags; - Value xfMtx[3]; - Value aabb[2]; - }; - - struct DEPS : BigDNA { - AT_DECL_DNA - Value depCount; - struct Dependency : BigDNA { - AT_DECL_DNA - UniqueID64 id; - DNAFourCC type; - }; - Vector deps; - Value depLayerCount; - Vector depLayers; - }; - - struct BabeDeadLight : BigDNA { - AT_DECL_DNA - enum class LightType : atUint32 { LocalAmbient, Directional, Custom, Spot, Spot2, LocalAmbient2 }; - enum class Falloff : atUint32 { Constant, Linear, Quadratic }; - Value lightType; - Value color; - Value alpha = 1.f; - Value position; - Value direction; - Value codirection; - Value q; - Value spotCutoff; - Value unk7; - Value castShadows; - Value unk9; - Value falloff; - Value unk11; - Value unk12; - Value unk13; - }; - - static void ReadBabeDeadToBlender_3(hecl::blender::PyOutStream& os, athena::io::IStreamReader& rs); - - static UniqueID64 GetPATHId(PAKEntryReadStream& rs); - - static bool Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath, - PAKRouter& pakRouter, const PAK::Entry& entry, bool, hecl::blender::Token& btok, - std::function); - - static bool ExtractLayerDeps(PAKEntryReadStream& rs, PAKBridge::Level::Area& areaOut); -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/PAK.cpp b/DataSpec/DNAMP3/PAK.cpp deleted file mode 100644 index 81a4b016a..000000000 --- a/DataSpec/DNAMP3/PAK.cpp +++ /dev/null @@ -1,231 +0,0 @@ -#include "PAK.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -const hecl::FourCC CMPD("CMPD"); - -template <> -void PAK::Enumerate(athena::io::IStreamReader& reader) { - m_header.read(reader); - if (m_header.version != 2) - Log.report(logvisor::Fatal, FMT_STRING("unexpected PAK magic")); - - reader.seek(8, athena::SeekOrigin::Current); - atUint32 strgSz = reader.readUint32Big(); - reader.seek(4, athena::SeekOrigin::Current); - atUint32 rshdSz = reader.readUint32Big(); - reader.seek(44, athena::SeekOrigin::Current); - atUint32 dataOffset = 128 + strgSz + rshdSz; - - atUint64 strgBase = reader.position(); - atUint32 nameCount = reader.readUint32Big(); - m_nameEntries.clear(); - m_nameEntries.reserve(nameCount); - for (atUint32 n = 0; n < nameCount; ++n) { - m_nameEntries.emplace_back(); - m_nameEntries.back().read(reader); - } - reader.seek(strgBase + strgSz, athena::SeekOrigin::Begin); - - atUint32 count = reader.readUint32Big(); - m_entries.clear(); - m_entries.reserve(count); - m_firstEntries.clear(); - m_firstEntries.reserve(count); - std::vector entries; - entries.reserve(count); - for (atUint32 e = 0; e < count; ++e) { - entries.emplace_back(); - entries.back().read(reader); - } - for (atUint32 e = 0; e < count; ++e) { - Entry& entry = entries[e]; - entry.offset += dataOffset; - - auto search = m_entries.find(entry.id); - if (search == m_entries.end()) { - m_firstEntries.push_back(entry.id); - m_entries[entry.id] = std::move(entry); - } else { - /* Find next MREA to record which area has dupes */ - for (atUint32 e2 = e + 1; e2 < count; ++e2) { - Entry& entry2 = entries[e2]; - if (entry2.type != FOURCC('MREA')) - continue; - m_dupeMREAs.insert(entry2.id); - break; - } - } - } - - m_nameMap.clear(); - m_nameMap.reserve(nameCount); - for (NameEntry& entry : m_nameEntries) - m_nameMap[entry.name] = entry.id; -} - -template <> -void PAK::Enumerate(athena::io::IStreamWriter& writer) { - m_header.write(writer); - - DNAFourCC("STRG").write(writer); - atUint32 strgSz = 4; - for (const NameEntry& entry : m_nameEntries) - strgSz += (atUint32)entry.name.size() + 13; - atUint32 strgPad = ((strgSz + 63) & ~63) - strgSz; - strgSz += strgPad; - writer.writeUint32Big(strgSz); - - DNAFourCC("RSHD").write(writer); - atUint32 rshdSz = 4 + 24 * m_entries.size(); - atUint32 rshdPad = ((rshdSz + 63) & ~63) - rshdSz; - rshdSz += rshdPad; - writer.writeUint32Big(rshdSz); - atUint32 dataOffset = 128 + strgSz + rshdSz; - - DNAFourCC("DATA").write(writer); - atUint32 dataSz = 0; - for (const auto& entry : m_entries) - dataSz += (entry.second.size + 63) & ~63; - atUint32 dataPad = ((dataSz + 63) & ~63) - dataSz; - dataSz += dataPad; - writer.writeUint32Big(dataSz); - writer.seek(36, athena::SeekOrigin::Current); - - writer.writeUint32Big((atUint32)m_nameEntries.size()); - for (const NameEntry& entry : m_nameEntries) - entry.write(writer); - writer.seek(strgPad, athena::SeekOrigin::Current); - - writer.writeUint32Big((atUint32)m_entries.size()); - for (const auto& entry : m_entries) { - Entry copy = entry.second; - copy.offset -= dataOffset; - copy.write(writer); - } - writer.seek(rshdPad, athena::SeekOrigin::Current); -} - -template <> -void PAK::Enumerate(size_t& __isz) { - m_header.binarySize(__isz); - - size_t strgSz = 4; - for (const NameEntry& entry : m_nameEntries) - strgSz += entry.name.size() + 13; - size_t strgPad = ((strgSz + 63) & ~63) - strgSz; - - size_t rshdSz = 4 + 24 * m_entries.size(); - size_t rshdPad = ((rshdSz + 63) & ~63) - rshdSz; - - __isz += 60; - - __isz += 4; - for (const NameEntry& entry : m_nameEntries) - entry.binarySize(__isz); - __isz += strgPad; - - __isz += 4; - for (const auto& entry : m_entries) - entry.second.binarySize(__isz); - __isz += rshdPad; -} - -std::unique_ptr PAK::Entry::getBuffer(const nod::Node& pak, atUint64& szOut) const { - if (compressed) { - std::unique_ptr strm = pak.beginReadStream(offset); - struct { - hecl::FourCC magic; - atUint32 blockCount; - } head; - strm->read(&head, 8); - if (head.magic != CMPD) { - Log.report(logvisor::Error, FMT_STRING("invalid CMPD block")); - return nullptr; - } - head.blockCount = hecl::SBig(head.blockCount); - - struct Block { - atUint32 compSz; - atUint32 decompSz; - }; - std::unique_ptr blocks(new Block[head.blockCount]); - strm->read(blocks.get(), 8 * head.blockCount); - - atUint64 maxBlockSz = 0; - atUint64 totalDecompSz = 0; - for (atUint32 b = 0; b < head.blockCount; ++b) { - Block& block = blocks[b]; - block.compSz = hecl::SBig(block.compSz) & 0xffffff; - block.decompSz = hecl::SBig(block.decompSz); - if (block.compSz > maxBlockSz) - maxBlockSz = block.compSz; - totalDecompSz += block.decompSz; - } - - std::unique_ptr compBuf(new atUint8[maxBlockSz]); - std::unique_ptr buf{new atUint8[totalDecompSz]}; - atUint8* bufCur = buf.get(); - for (atUint32 b = 0; b < head.blockCount; ++b) { - Block& block = blocks[b]; - atUint8* compBufCur = compBuf.get(); - strm->read(compBufCur, block.compSz); - if (block.compSz == block.decompSz) { - memcpy(bufCur, compBufCur, block.decompSz); - bufCur += block.decompSz; - } else { - atUint32 rem = block.decompSz; - while (rem) { - atUint16 chunkSz = hecl::SBig(*(atUint16*)compBufCur); - compBufCur += 2; - size_t dsz; - lzokay::decompress(compBufCur, chunkSz, bufCur, rem, dsz); - compBufCur += chunkSz; - bufCur += dsz; - rem -= dsz; - } - } - } - - szOut = totalDecompSz; - return buf; - } else { - std::unique_ptr buf{new atUint8[size]}; - pak.beginReadStream(offset)->read(buf.get(), size); - szOut = size; - return buf; - } -} - -const PAK::Entry* PAK::lookupEntry(const UniqueID64& id) const { - auto result = m_entries.find(id); - if (result != m_entries.end()) - return &result->second; - return nullptr; -} - -const PAK::Entry* PAK::lookupEntry(std::string_view name) const { - // TODO: Heterogeneous lookup when C++20 available - auto result = m_nameMap.find(name.data()); - if (result != m_nameMap.end()) { - auto result1 = m_entries.find(result->second); - if (result1 != m_entries.end()) - return &result1->second; - } - return nullptr; -} - -std::string PAK::bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const { - /* Prefer named entries first */ - for (const NameEntry& nentry : m_nameEntries) - if (nentry.id == entry.id) { - catalogueName = nentry.name; - return fmt::format(FMT_STRING("{}_{}"), nentry.name, entry.id); - } - - /* Otherwise return ID format string */ - return fmt::format(FMT_STRING("{}_{}"), entry.type, entry.id); -} - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/PAK.hpp b/DataSpec/DNAMP3/PAK.hpp deleted file mode 100644 index 298dc5770..000000000 --- a/DataSpec/DNAMP3/PAK.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#pragma once - -#include - -#include -#include -#include "DataSpec/DNACommon/PAK.hpp" - -namespace DataSpec::DNAMP3 { - -extern const hecl::FourCC CMPD; - -struct PAK : BigDNA { - bool m_noShare; - PAK(bool noShare) : m_noShare(noShare) {} - - struct Header : BigDNA { - AT_DECL_DNA - Value version; - Value headSz; - Value md5sum[16]; - Seek<40, athena::SeekOrigin::Current> seek; - } m_header; - - struct NameEntry : BigDNA { - AT_DECL_DNA - String<-1> name; - DNAFourCC type; - UniqueID64 id; - }; - - struct Entry : BigDNA { - AT_DECL_DNA - Value compressed; - DNAFourCC type; - UniqueID64 id; - Value size; - Value offset; - UniqueResult unique; - std::string name; - - std::unique_ptr getBuffer(const nod::Node& pak, atUint64& szOut) const; - inline PAKEntryReadStream beginReadStream(const nod::Node& pak, atUint64 off = 0) const { - atUint64 sz; - std::unique_ptr buf = getBuffer(pak, sz); - return PAKEntryReadStream(std::move(buf), sz, off); - } - }; - - std::vector m_nameEntries; - std::unordered_map m_entries; - std::vector m_firstEntries; - std::unordered_map m_nameMap; - std::unordered_set m_dupeMREAs; - - AT_DECL_EXPLICIT_DNA - - const Entry* lookupEntry(const UniqueID64& id) const; - const Entry* lookupEntry(std::string_view name) const; - std::string bestEntryName(const nod::Node& pakNode, const Entry& entry, std::string& catalogueName) const; - - bool mreaHasDupeResources(const UniqueID64& id) const { return m_dupeMREAs.find(id) != m_dupeMREAs.cend(); } - - using IDType = UniqueID64; -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/PATH.hpp b/DataSpec/DNAMP3/PATH.hpp deleted file mode 100644 index f2b218055..000000000 --- a/DataSpec/DNAMP3/PATH.hpp +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include "DataSpec/DNACommon/PATH.hpp" - -namespace DataSpec::DNAMP3 { -using PATH = DNAPATH::PATH; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/SAND.hpp b/DataSpec/DNAMP3/SAND.hpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/DataSpec/DNAMP3/SAVW.hpp b/DataSpec/DNAMP3/SAVW.hpp deleted file mode 100644 index 77c03914c..000000000 --- a/DataSpec/DNAMP3/SAVW.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include "DataSpec/DNACommon/SAVWCommon.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { -struct Scan : BigDNA { - AT_DECL_DNA_YAML - UniqueID64 scanId; - Value category; -}; - -struct SavedState : BigDNA { - AT_DECL_DNA_YAML - struct ID : BigDNA { - AT_DECL_DNA_YAML - Value id[2]; - }; - ID id; - Value instance; -}; - -struct SAVW : BigDNA { - AT_DECL_DNA_YAML - SAVWCommon::Header header; - Value skippableCutsceneCount; - Vector skippableCutscenes; - Value relayCount; - Vector relays; - Value doorCount; - Vector doors; - Value scanCount; - Vector scans; - Value systemVarCount; - Vector systemVars; - Value gameVarCount; - Vector gameVars; - Value gameObjectCount; - Vector gameObjects; -}; -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/STRG.cpp b/DataSpec/DNAMP3/STRG.cpp deleted file mode 100644 index 9ac591919..000000000 --- a/DataSpec/DNAMP3/STRG.cpp +++ /dev/null @@ -1,228 +0,0 @@ -#include "STRG.hpp" -#include "DNAMP3.hpp" - -namespace DataSpec::DNAMP3 { - -void STRG::_read(athena::io::IStreamReader& reader) { - atUint32 langCount = reader.readUint32Big(); - atUint32 strCount = reader.readUint32Big(); - - atUint32 nameCount = reader.readUint32Big(); - atUint32 nameTableSz = reader.readUint32Big(); - if (nameTableSz) { - std::unique_ptr nameTableBuf(new uint8_t[nameTableSz]); - reader.readUBytesToBuf(nameTableBuf.get(), nameTableSz); - struct NameIdxEntry { - atUint32 nameOff; - atUint32 strIdx; - }* nameIndex = (NameIdxEntry*)nameTableBuf.get(); - for (atUint32 n = 0; n < nameCount; ++n) { - const char* name = (char*)(nameTableBuf.get() + hecl::SBig(nameIndex[n].nameOff)); - names[name] = hecl::SBig(nameIndex[n].strIdx); - } - } - - std::vector readLangs; - readLangs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - DNAFourCC lang; - lang.read(reader); - readLangs.emplace_back(lang); - } - std::unique_ptr strOffs(new atUint32[langCount * strCount]); - for (atUint32 l = 0; l < langCount; ++l) { - reader.readUint32Big(); - for (atUint32 s = 0; s < strCount; ++s) - strOffs[l * strCount + s] = reader.readUint32Big(); - } - - atUint64 strBase = reader.position(); - langs.clear(); - langs.reserve(langCount); - for (atUint32 l = 0; l < langCount; ++l) { - std::vector strs; - for (atUint32 s = 0; s < strCount; ++s) { - reader.seek(strBase + strOffs[l * strCount + s], athena::SeekOrigin::Begin); - atUint32 len = reader.readUint32Big(); - strs.emplace_back(reader.readString(len)); - } - langs.emplace_back(readLangs[l], strs); - } - - langMap.clear(); - langMap.reserve(langCount); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::IStreamReader& reader) { - atUint32 magic = reader.readUint32Big(); - if (magic != 0x87654321) { - Log.report(logvisor::Error, FMT_STRING("invalid STRG magic")); - return; - } - - atUint32 version = reader.readUint32Big(); - if (version != 3) { - Log.report(logvisor::Error, FMT_STRING("invalid STRG version")); - return; - } - - _read(reader); -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocReader& reader) { - const athena::io::YAMLNode* root = reader.getRootNode(); - - /* Validate Pass */ - if (root->m_type == YAML_MAPPING_NODE) { - for (const auto& lang : root->m_mapChildren) { - if (lang.first == "names") - continue; - if (lang.first.size() != 4) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must be exactly 4 characters; skipping"), - lang.first); - return; - } - if (lang.second->m_type != YAML_SEQUENCE_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language string '{}' must contain a sequence; skipping"), - lang.first); - return; - } - for (const auto& str : lang.second->m_seqChildren) { - if (str->m_type != YAML_SCALAR_NODE) { - Log.report(logvisor::Warning, FMT_STRING("STRG language '{}' must contain all scalars; skipping"), - lang.first); - return; - } - } - } - } else { - Log.report(logvisor::Warning, FMT_STRING("STRG must have a mapping root node; skipping")); - return; - } - - const athena::io::YAMLNode* nameYAML = root->findMapChild("names"); - names.clear(); - if (nameYAML && nameYAML->m_type == YAML_MAPPING_NODE) - for (const auto& item : nameYAML->m_mapChildren) - if (item.second->m_type == YAML_SCALAR_NODE) - names[item.first] = athena::io::NodeToVal(item.second.get()); - - langs.clear(); - langs.reserve(root->m_mapChildren.size()); - for (const auto& item : root->m_mapChildren) { - if (item.first == "names" || item.first.size() != 4 || item.second->m_type != YAML_SEQUENCE_NODE) - continue; - - std::vector strs; - for (const auto& node : item.second->m_seqChildren) - if (node->m_type == YAML_SCALAR_NODE) - strs.emplace_back(node->m_scalarString); - langs.emplace_back(std::make_pair(DNAFourCC(item.first.c_str()), std::move(strs))); - } - - langMap.clear(); - langMap.reserve(langs.size()); - for (std::pair>& item : langs) - langMap.emplace(item.first, &item.second); -} - -template <> -void STRG::Enumerate(athena::io::IStreamWriter& writer) { - writer.writeUint32Big(0x87654321); - writer.writeUint32Big(3); - writer.writeUint32Big(langs.size()); - atUint32 strCount = STRG::count(); - writer.writeUint32Big(strCount); - - atUint32 nameTableSz = names.size() * 8; - for (const auto& name : names) - nameTableSz += name.first.size() + 1; - writer.writeUint32Big(names.size()); - writer.writeUint32Big(nameTableSz); - atUint32 offset = names.size() * 8; - for (const auto& name : names) { - writer.writeUint32Big(offset); - writer.writeInt32Big(name.second); - offset += name.first.size() + 1; - } - for (const auto& name : names) - writer.writeString(name.first); - - for (const auto& lang : langs) - lang.first.write(writer); - - offset = 0; - for (const auto& lang : langs) { - atUint32 langSz = 0; - for (const std::string& str : lang.second) - langSz += str.size() + 5; - writer.writeUint32Big(langSz); - - for (const std::string& str : lang.second) { - writer.writeUint32Big(offset); - offset += str.size() + 5; - } - } - - for (atUint32 s = 0; s < strCount; ++s) { - for (const auto& lang : langs) { - if (s >= lang.second.size()) { - writer.writeUint32Big(1); - writer.writeUByte(0); - } else { - const std::string& str = lang.second[s]; - writer.writeUint32Big(str.size() + 1); - writer.writeString(str); - } - } - } -} - -template <> -void STRG::Enumerate(size_t& __isz) { - __isz += 24; - __isz += names.size() * 8; - for (const auto& name : names) - __isz += name.first.size() + 1; - - __isz += langs.size() * 4; - - for (const auto& lang : langs) - __isz += 4 + lang.second.size() * 4; - - size_t strCount = STRG::count(); - for (atUint32 s = 0; s < strCount; ++s) { - for (const auto& lang : langs) { - if (s >= lang.second.size()) { - __isz += 5; - } else { - const std::string& str = lang.second[s]; - __isz += str.size() + 5; - } - } - } -} - -template <> -void STRG::Enumerate(athena::io::YAMLDocWriter& writer) { - for (const auto& item : langs) { - if (auto v = writer.enterSubVector(item.first.toString())) - for (const std::string& str : item.second) - writer.writeString(str); - } - - if (names.size()) { - if (auto rec = writer.enterSubRecord("names")) - for (const auto& item : names) - if (auto rec = writer.enterSubRecord(item.first)) - writer.writeInt32(item.second); - } -} - -std::string_view STRG::DNAType() { return "DNAMP3::STRG"sv; } - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/DNAMP3/STRG.hpp b/DataSpec/DNAMP3/STRG.hpp deleted file mode 100644 index 211dc52c3..000000000 --- a/DataSpec/DNAMP3/STRG.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include -#include "DataSpec/DNACommon/PAK.hpp" -#include "DataSpec/DNACommon/STRG.hpp" - -namespace DataSpec::DNAMP3 { - -struct STRG : ISTRG { - AT_DECL_EXPLICIT_DNA_YAMLV - void _read(athena::io::IStreamReader& reader); - std::vector>> langs; - std::unordered_map*> langMap; - std::map names; - - int32_t lookupIdx(std::string_view name) const override { - // TODO: Heterogeneous lookup when C++20 available - auto search = names.find(name.data()); - if (search == names.end()) - return -1; - return search->second; - } - - size_t count() const override { - size_t retval = 0; - for (const auto& item : langs) { - size_t sz = item.second.size(); - if (sz > retval) - retval = sz; - } - return retval; - } - std::string getUTF8(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return search->second->at(idx); - return std::string(); - } - std::u16string getUTF16(const FourCC& lang, size_t idx) const override { - auto search = langMap.find(lang); - if (search != langMap.end()) - return hecl::UTF8ToChar16(search->second->at(idx)); - return std::u16string(); - } - - static bool Extract(PAKEntryReadStream& rs, const hecl::ProjectPath& outPath) { - std::unique_ptr strg = LoadSTRG(rs); - athena::io::TransactionalFileWriter writer(outPath.getAbsolutePath()); - athena::io::ToYAMLStream(*strg, writer); - return true; - } - - static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - STRG strg; - athena::io::FileReader reader(inPath.getAbsolutePath()); - athena::io::FromYAMLStream(strg, reader); - athena::io::TransactionalFileWriter ws(outPath.getAbsolutePath()); - strg.write(ws); - return true; - } -}; - -} // namespace DataSpec::DNAMP3 diff --git a/DataSpec/SpecBase.cpp b/DataSpec/SpecBase.cpp deleted file mode 100644 index 13e3e9317..000000000 --- a/DataSpec/SpecBase.cpp +++ /dev/null @@ -1,1222 +0,0 @@ -#if _WIN32 -#define _CRT_RAND_S -#include -#endif - -#include "DataSpec/SpecBase.hpp" -#include "DataSpec/Blender/BlenderSupport.hpp" -#include "DataSpec/DNACommon/DNACommon.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/AssetNameMap.hpp" -#include "DataSpec/DNACommon/MetaforceVersionInfo.hpp" -#include "hecl/ClientProcess.hpp" -#include "nod/DiscBase.hpp" -#include "nod/nod.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/Blender/SDNARead.hpp" -#include "hecl/MultiProgressPrinter.hpp" - -#include - -#define DUMP_CACHE_FILL 1 - -namespace DataSpec { - -static logvisor::Module Log("DataSpec::SpecBase"); - -static const char* MomErr[] = {"Your metroid is in another castle", - "HECL is experiencing a PTSD attack", - "Unable to freeze metroids", - "Ridley ate your homework", - "Expected 0 maternal symbolisms, found 2147483647", - "Contradictive narratives unsupported", - "Wiimote profile \"NES + Zapper\" not recognized", - "Unable to find Waldo", - "Expected Ridley, found furby", - "Adam has not authorized this, please do not bug the developers", - "Lady returned objection", - "Unterminated plot thread 'Deleter' detected"}; - -constexpr uint32_t MomErrCount = std::extent::value; - -static ERegion g_CurRegion = ERegion::Invalid; -static bool g_CurSpecIsWii = false; - -ERegion getCurrentRegion() { return g_CurRegion; } -bool isCurrentSpecWii() { return g_CurSpecIsWii; } - -SpecBase::SpecBase(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) -: hecl::Database::IDataSpec(specEntry) -, m_project(project) -, m_pc(pc) -, m_masterShader(project.getProjectWorkingPath(), ".hecl/RetroMasterShader.blend") -, m_region(ERegion::Invalid) -, m_game(EGame::Invalid) { - AssetNameMap::InitAssetNameMap(); - SpecBase::setThreadProject(); -} - -SpecBase::~SpecBase() { cancelBackgroundIndex(); } - -static const std::string regNONE = ""; -static const std::string regE = "NTSC"; -static const std::string regJ = "NTSC-J"; -static const std::string regP = "PAL"; - -void SpecBase::setThreadProject() { UniqueIDBridge::SetThreadProject(m_project); } - -bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector& reps) { - m_disc = nod::OpenDiscFromImage(info.srcpath, m_isWii); - if (!m_disc) - return false; - const char* gameID = m_disc->getHeader().m_gameID; - - if (!memcmp(gameID, "R3O", 3)) { - std::srand(std::time(0)); - int r = std::rand() % MomErrCount; - Log.report(logvisor::Fatal, FMT_STRING("{}"), MomErr[r]); - } - - m_standalone = true; - if (m_isWii && (!memcmp(gameID, "R3M", 3) || !memcmp(gameID, "R3I", 3) || !memcmp(gameID, "R32", 3))) - m_standalone = false; - - if (m_standalone && !checkStandaloneID(gameID)) - return false; - - m_region = ERegion(m_disc->getHeader().m_gameID[3]); - const std::string* regstr = ®NONE; - switch (m_region) { - case ERegion::NTSC_U: - regstr = ®E; - break; - case ERegion::NTSC_J: - regstr = ®J; - break; - case ERegion::PAL: - regstr = ®P; - break; - default: - break; - } - - setCurRegion(m_region); - setCurSpecIsWii(m_isWii); - - if (m_standalone) - return checkFromStandaloneDisc(*m_disc, *regstr, info.extractArgs, reps); - else - return checkFromTrilogyDisc(*m_disc, *regstr, info.extractArgs, reps); -} - -void SpecBase::doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress) { - setThreadProject(); - DataSpec::g_curSpec.reset(this); - if (!Blender::BuildMasterShader(m_masterShader)) - Log.report(logvisor::Fatal, FMT_STRING("Unable to build master shader blend")); - if (m_isWii) { - /* Extract root files for repacking later */ - hecl::ProjectPath outDir(m_project.getProjectWorkingPath(), "out"); - outDir.makeDirChain(true); - nod::ExtractionContext ctx = {info.force, nullptr}; - - if (!m_standalone) { - progress.print("Trilogy Files", "", 0.0); - nod::IPartition* data = m_disc->getDataPartition(); - const nod::Node& root = data->getFSTRoot(); - for (const nod::Node& child : root) - if (child.getKind() == nod::Node::Kind::File) - child.extractToDirectory(outDir.getAbsolutePath(), ctx); - progress.print("Trilogy Files", "", 1.0); - } - } - extractFromDisc(*m_disc, info.force, progress); -} - -bool IsPathAudioGroup(const hecl::ProjectPath& path) { - return (path.getPathType() == hecl::ProjectPath::Type::Directory && - hecl::ProjectPath(path, "!project.yaml").isFile() && - hecl::ProjectPath(path, "!pool.yaml").isFile()); -} - -static bool IsPathSong(const hecl::ProjectPath& path) { - if (path.getPathType() != hecl::ProjectPath::Type::Glob || !path.getWithExtension(".mid", true).isFile() || - !path.getWithExtension(".yaml", true).isFile()) { - return path.isFile() && path.getLastComponentExt() == "mid" && - path.getWithExtension(".yaml", true).isFile(); - } - return true; -} - -bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok) { - if (!checkPathPrefix(path)) - return false; - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath()); - return type != hecl::blender::BlendType::None; - } - - if (hecl::IsPathPNG(path)) { - return true; - } else if (hecl::IsPathYAML(path)) { - athena::io::FileReader reader(path.getAbsolutePath()); - bool retval = validateYAMLDNAType(reader); - return retval; - } else if (IsPathAudioGroup(path)) { - return true; - } else if (IsPathSong(path)) { - return true; - } - return false; -} - -const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path, - const hecl::Database::DataSpecEntry* oldEntry) const { - if (!checkPathPrefix(path)) - return nullptr; - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR") || - hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM")) - return oldEntry; - - hecl::blender::BlendType type = hecl::blender::GetBlendType(asBlend.getAbsolutePath()); - if (type == hecl::blender::BlendType::None) { - Log.report(logvisor::Error, FMT_STRING("unable to cook '{}'"), path.getAbsolutePath()); - return nullptr; - } - if (type == hecl::blender::BlendType::Mesh || type == hecl::blender::BlendType::Area) - return oldEntry; - } else if (hecl::IsPathPNG(path)) { - return oldEntry; - } - return &getOriginalSpec(); -} - -void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, - hecl::blender::Token& btok, FCookProgress progress) { - cookedPath.makeDirChain(false); - DataSpec::g_curSpec.reset(this); - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.openBlend(asBlend)) - return; - switch (conn.getBlendType()) { - case hecl::blender::BlendType::Mesh: { - hecl::blender::DataStream ds = conn.beginData(); - cookMesh(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::ColMesh: { - hecl::blender::DataStream ds = conn.beginData(); - cookColMesh(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Armature: { - hecl::blender::DataStream ds = conn.beginData(); - cookArmature(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::PathMesh: { - hecl::blender::DataStream ds = conn.beginData(); - cookPathMesh(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Actor: { - hecl::blender::DataStream ds = conn.beginData(); - cookActor(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Area: { - hecl::blender::DataStream ds = conn.beginData(); - cookArea(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::World: { - hecl::blender::DataStream ds = conn.beginData(); - cookWorld(cookedPath, path, ds, fast, btok, progress); - break; - } - case hecl::blender::BlendType::Frame: { - hecl::blender::DataStream ds = conn.beginData(); - cookGuiFrame(cookedPath, path, ds, btok, progress); - break; - } - case hecl::blender::BlendType::MapArea: { - hecl::blender::DataStream ds = conn.beginData(); - cookMapArea(cookedPath, path, ds, btok, progress); - break; - } - case hecl::blender::BlendType::MapUniverse: { - hecl::blender::DataStream ds = conn.beginData(); - cookMapUniverse(cookedPath, path, ds, btok, progress); - break; - } - default: - break; - } - } else if (hecl::IsPathPNG(path)) { - if (m_pc) - TXTR::CookPC(path, cookedPath); - else - TXTR::Cook(path, cookedPath); - } else if (hecl::IsPathYAML(path)) { - athena::io::FileReader reader(path.getAbsolutePath()); - cookYAML(cookedPath, path, reader, btok, progress); - } else if (IsPathAudioGroup(path)) { - cookAudioGroup(cookedPath, path, progress); - } else if (IsPathSong(path)) { - cookSong(cookedPath, path, progress); - } -} - -void SpecBase::flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.openBlend(in)) - return; - switch (conn.getBlendType()) { - case hecl::blender::BlendType::Mesh: - case hecl::blender::BlendType::Area: { - hecl::blender::DataStream ds = conn.beginData(); - std::vector texs = ds.getTextures(); - pathsOut.insert(pathsOut.end(), std::make_move_iterator(texs.begin()), std::make_move_iterator(texs.end())); - break; - } - case hecl::blender::BlendType::Actor: { - hecl::ProjectPath asGlob = in.getWithExtension(".*", true); - hecl::ProjectPath parentPath = asGlob.getParentPath(); - hecl::DirectoryEnumerator dEnum(parentPath.getAbsolutePath()); - hecl::blender::DataStream ds = conn.beginData(); - hecl::blender::Actor actor = ds.compileActorCharacterOnly(); - auto actNames = ds.getActionNames(); - ds.close(); - - auto doSubtype = [&](Actor::Subtype& sub) { - if (sub.armature >= 0) { - if (hecl::IsPathBlend(sub.mesh)) { - flattenDependenciesBlend(sub.mesh, pathsOut, btok); - pathsOut.push_back(sub.mesh); - } - - if (!sub.cskrId.empty()) { - pathsOut.push_back( - asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), sub.name, sub.cskrId))); - } else { - pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), sub.name))); - } - - const auto& arm = actor.armatures[sub.armature]; - if (hecl::IsPathBlend(arm.path)) - pathsOut.push_back(arm.path); - - for (const auto& overlay : sub.overlayMeshes) { - if (hecl::IsPathBlend(overlay.mesh)) { - flattenDependenciesBlend(overlay.mesh, pathsOut, btok); - pathsOut.push_back(overlay.mesh); - } - pathsOut.push_back(asGlob.ensureAuxInfo( - fmt::format(FMT_STRING("{}.{}_{}.CSKR"), sub.name, overlay.name, overlay.cskrId))); - } - } - }; - if (charIdx < 0) - for (auto& sub : actor.subtypes) - doSubtype(sub); - else if (charIdx < actor.subtypes.size()) - doSubtype(actor.subtypes[charIdx]); - - for (const Actor::Attachment& att : actor.attachments) { - if (hecl::IsPathBlend(att.mesh)) { - flattenDependenciesBlend(att.mesh, pathsOut, btok); - pathsOut.push_back(att.mesh); - } - - pathsOut.push_back( - asGlob.ensureAuxInfo(fmt::format(FMT_STRING("ATTACH.{}_{}.CSKR"), att.name, att.cskrId))); - - if (att.armature >= 0) { - const auto& arm = actor.armatures[att.armature]; - if (hecl::IsPathBlend(arm.path)) - pathsOut.push_back(arm.path); - } - } - - for (const auto& act : actNames) { - pathsOut.push_back(asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.first, act.second))); - std::string searchPrefix( - asGlob.getWithExtension(fmt::format(FMT_STRING(".{}_"), act.first).c_str(), true) - .getLastComponent()); - hecl::ProjectPath evntPath; - for (const auto& ent : dEnum) { - if (hecl::StringUtils::BeginsWith(ent.m_name, searchPrefix.c_str()) && - hecl::StringUtils::EndsWith(ent.m_name, ".evnt.yaml")) { - evntPath = hecl::ProjectPath(parentPath, ent.m_name); - break; - } - } - if (evntPath.isFile()) - pathsOut.push_back(evntPath); - } - - hecl::ProjectPath yamlPath = asGlob.getWithExtension(".yaml", true); - if (yamlPath.isFile()) { - athena::io::FileReader reader(yamlPath.getAbsolutePath()); - flattenDependenciesANCSYAML(reader, pathsOut, charIdx); - } - - pathsOut.push_back(asGlob); - return; - } - default: - break; - } -} - -void SpecBase::flattenDependencies(const hecl::ProjectPath& path, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx) { - DataSpec::g_curSpec.reset(this); - g_ThreadBlenderToken.reset(&btok); - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - flattenDependenciesBlend(asBlend, pathsOut, btok, charIdx); - } else if (hecl::IsPathYAML(path)) { - athena::io::FileReader reader(path.getAbsolutePath()); - flattenDependenciesYAML(reader, pathsOut); - } - - pathsOut.push_back(path); -} - -void SpecBase::flattenDependencies(const UniqueID32& id, std::vector& pathsOut, int charIdx) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - if (path) - flattenDependencies(path, pathsOut, *g_ThreadBlenderToken.get(), charIdx); -} - -void SpecBase::flattenDependencies(const UniqueID64& id, std::vector& pathsOut, int charIdx) { - hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id); - if (path) - flattenDependencies(path, pathsOut, *g_ThreadBlenderToken.get(), charIdx); -} - -bool SpecBase::canPackage(const hecl::ProjectPath& path) { - auto components = path.getPathComponents(); - if (components.size() <= 1) - return false; - return path.isFile() || path.isDirectory(); -} - -void SpecBase::recursiveBuildResourceList(std::vector& listOut, - std::unordered_set& addedTags, - const hecl::ProjectPath& path, hecl::blender::Token& btok) { - hecl::DirectoryEnumerator dEnum(path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsThenFilesSorted, false, - false, true); - for (const auto& ent : dEnum) { - hecl::ProjectPath childPath(path, ent.m_name); - if (ent.m_isDir) { - if (hecl::ProjectPath(childPath, "!project.yaml").isFile() && - hecl::ProjectPath(childPath, "!pool.yaml").isFile()) { - /* Handle AudioGroup case */ - if (metaforce::SObjectTag tag = tagFromPath(childPath)) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - listOut.push_back(tag); - } - continue; - } - - recursiveBuildResourceList(listOut, addedTags, childPath, btok); - } else { - std::vector subPaths; - flattenDependencies(childPath, subPaths, btok); - for (const auto& subPath : subPaths) { - if (metaforce::SObjectTag tag = tagFromPath(subPath)) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - listOut.push_back(tag); - } - } - } - } -} - -void SpecBase::copyBuildListData(std::vector>& fileIndex, - const std::vector& buildList, - const hecl::Database::DataSpecEntry* entry, bool fast, - const hecl::MultiProgressPrinter& progress, athena::io::FileWriter& pakOut, - const std::unordered_map>& mlvlData) { - fileIndex.reserve(buildList.size()); - int loadIdx = 0; - for (const auto& tag : buildList) { - std::string str = fmt::format(FMT_STRING("Copying {}"), tag); - progress.print(str, std::nullopt, ++loadIdx / float(buildList.size())); - - auto& [positionOut, sizeOut, compressedOut] = fileIndex.emplace_back(); - - if (tag.type == FOURCC('MLVL')) { - auto search = mlvlData.find(tag.id); - if (search == mlvlData.end()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to find MLVL {}"), tag.id); - - positionOut = pakOut.position(); - sizeOut = ROUND_UP_32(search->second.size()); - compressedOut = false; - pakOut.writeUBytes(search->second.data(), search->second.size()); - for (atUint64 i = search->second.size(); i < sizeOut; ++i) - pakOut.writeUByte(0xff); - - continue; - } - - hecl::ProjectPath path = pathFromTag(tag); - hecl::ProjectPath cooked = getCookedPath(path, true); - athena::io::FileReader r(cooked.getAbsolutePath()); - if (r.hasError()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to open resource {}"), cooked.getRelativePath()); - atUint64 size = r.length(); - auto data = r.readUBytes(size); - auto compData = compressPakData(tag, data.get(), size); - if (compData.first) { - positionOut = pakOut.position(); - sizeOut = ROUND_UP_32(compData.second + 4); - compressedOut = true; - pakOut.writeUint32Big(atUint32(size)); - pakOut.writeUBytes(compData.first.get(), compData.second); - for (atUint64 i = compData.second + 4; i < sizeOut; ++i) - pakOut.writeUByte(0xff); - } else { - positionOut = pakOut.position(); - sizeOut = ROUND_UP_32(size); - compressedOut = false; - pakOut.writeUBytes(data.get(), size); - for (atUint64 i = size; i < sizeOut; ++i) - pakOut.writeUByte(0xff); - } - } - progress.startNewLine(); -} - -static bool IsWorldBlend(const hecl::ProjectPath& path) { - if (path.isFile()) { - auto lastComp = path.getLastComponent(); - return hecl::StringUtils::BeginsWith(lastComp, "!world") && - hecl::StringUtils::EndsWith(lastComp, ".blend"); - } - return false; -} - -void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast, - hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress, - hecl::ClientProcess* cp) { - /* Prepare complete resource index */ - if (!m_backgroundRunning && m_tagToPath.empty()) - beginBackgroundIndex(); - waitForIndexComplete(); - - /* Name pak based on root-relative components */ - auto components = path.getWithExtension("", true).getPathComponents(); - if (components.size() <= 1) - return; - hecl::ProjectPath outPath; - if (hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/" + components[0]).isDirectory()) - outPath.assign(m_project.getProjectWorkingPath(), - "out/files/" + components[0] + "/" + components[1] + entry->m_pakExt.data()); - else - outPath.assign(m_project.getProjectWorkingPath(), "out/files/" + components[1] + entry->m_pakExt.data()); - outPath.makeDirChain(false); - - /* Output file */ - athena::io::FileWriter pakOut(outPath.getAbsolutePath()); - std::vector buildList; - atUint64 resTableOffset = 0; - std::unordered_map> mlvlData; - - if (IsWorldBlend(path)) /* World PAK */ - { - /* Force-cook MLVL and write resource list structure */ - m_project.cookPath(path, progress, false, true, fast, entry, cp); - if (cp) - cp->waitUntilComplete(); - progress.startNewLine(); - hecl::ProjectPath cooked = getCookedPath(path, true); - buildWorldPakList(path, cooked, btok, pakOut, buildList, resTableOffset, mlvlData); - if (int64_t rem = pakOut.position() % 32) - for (int64_t i = 0; i < 32 - rem; ++i) - pakOut.writeUByte(0xff); - } else if (path.getPathType() == hecl::ProjectPath::Type::Directory) /* General PAK */ - { - /* Build resource list */ - std::unordered_set addedTags; - recursiveBuildResourceList(buildList, addedTags, path, btok); - std::vector> nameList; - - /* Build name list */ - for (const auto& item : buildList) { - auto search = m_catalogTagToNames.find(item); - if (search != m_catalogTagToNames.end()) - for (const auto& name : search->second) - nameList.emplace_back(item, name); - } - - /* Write resource list structure */ - buildPakList(btok, pakOut, buildList, nameList, resTableOffset); - if (int64_t rem = pakOut.position() % 32) - for (int64_t i = 0; i < 32 - rem; ++i) - pakOut.writeUByte(0xff); - } else if (path.getPathType() == hecl::ProjectPath::Type::File) /* One-file General PAK */ - { - /* Build resource list */ - std::vector subPaths; - flattenDependencies(path, subPaths, btok); - std::unordered_set addedTags; - std::vector> nameList; - for (const auto& subPath : subPaths) { - if (metaforce::SObjectTag tag = tagFromPath(subPath)) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - buildList.push_back(tag); - } - } - - /* Build name list */ - for (const auto& item : buildList) { - auto search = m_catalogTagToNames.find(item); - if (search != m_catalogTagToNames.end()) - for (const auto& name : search->second) - nameList.emplace_back(item, name); - } - - /* Write resource list structure */ - buildPakList(btok, pakOut, buildList, nameList, resTableOffset); - if (int64_t rem = pakOut.position() % 32) - for (int64_t i = 0; i < 32 - rem; ++i) - pakOut.writeUByte(0xff); - } - - /* Async cook resource list if using ClientProcess */ - if (cp) { - Log.report(logvisor::Info, FMT_STRING("Validating resources")); - progress.setMainIndeterminate(true); - std::vector cookTags; - cookTags.reserve(buildList.size()); - - /* Ensure CMDLs are enqueued first to minimize synchronous dependency cooking */ - for (int i = 0; i < 2; ++i) { - std::unordered_set addedTags; - addedTags.reserve(buildList.size()); - for (auto& tag : buildList) { - if ((i == 0 && tag.type == FOURCC('CMDL')) || (i == 1 && tag.type != FOURCC('CMDL'))) { - if (addedTags.find(tag) != addedTags.end()) - continue; - addedTags.insert(tag); - cookTags.push_back(tag); - } - } - } - - /* Cook ordered tags */ - for (auto& tag : cookTags) { - hecl::ProjectPath depPath = pathFromTag(tag); - if (!depPath) - Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve {}"), tag); - m_project.cookPath(depPath, progress, false, false, fast, entry, cp); - } - progress.setMainIndeterminate(false); - cp->waitUntilComplete(); - progress.startNewLine(); - } - - /* Write resource data and build file index */ - std::vector> fileIndex; - Log.report(logvisor::Info, FMT_STRING("Copying data into {}"), outPath.getRelativePath()); - copyBuildListData(fileIndex, buildList, entry, fast, progress, pakOut, mlvlData); - - /* Write file index */ - writePakFileIndex(pakOut, buildList, fileIndex, resTableOffset); - pakOut.close(); -} - -void SpecBase::interruptCook() { cancelBackgroundIndex(); } - -std::optional SpecBase::compileWorldFromDir(const hecl::ProjectPath& dir, - hecl::blender::Token& btok) const { - hecl::ProjectPath asBlend; - for (const auto& ent : hecl::DirectoryEnumerator(dir.getAbsolutePath())) { - if (hecl::StringUtils::BeginsWith(ent.m_name, "!world")) { - asBlend = hecl::ProjectPath(dir, ent.m_name).getWithExtension(".blend", true); - break; - } - } - if (hecl::IsPathBlend(asBlend)) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - if (!conn.openBlend(asBlend)) - return {}; - hecl::blender::DataStream ds = conn.beginData(); - return {ds.compileWorld()}; - } - return {}; -} - -hecl::ProjectPath SpecBase::getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const { - const hecl::Database::DataSpecEntry* spec = &getOriginalSpec(); - if (pcTarget) - spec = overrideDataSpec(working, getDataSpecEntry()); - if (!spec) - return {}; - return working.getCookedPath(*spec); -} - -static void PNGErr(png_structp png, png_const_charp msg) { Log.report(logvisor::Error, FMT_STRING("{}"), msg); } - -static void PNGWarn(png_structp png, png_const_charp msg) { Log.report(logvisor::Warning, FMT_STRING("{}"), msg); } - -constexpr uint8_t Convert4To8(uint8_t v) { - /* Swizzle bits: 00001234 -> 12341234 */ - return (v << 4) | v; -} - -void SpecBase::extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& pakPath) { - hecl::ProjectPath entropyPath(pakPath, "RandomStaticEntropy.png"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - entropyPath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("RandomStaticEntropy: {}\n"), entropyPath.getRelativePath()); - } - - auto fp = hecl::FopenUnique(entropyPath.getAbsolutePath().data(), "wb"); - if (fp == nullptr) { - Log.report(logvisor::Error, FMT_STRING("Unable to open '{}' for writing"), entropyPath.getAbsolutePath()); - return; - } - png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, PNGErr, PNGWarn); - png_init_io(png, fp.get()); - png_infop info = png_create_info_struct(png); - - png_text textStruct = {}; - textStruct.key = png_charp("meta_nomip"); - png_set_text(png, info, &textStruct, 1); - - png_set_IHDR(png, info, 1024, 512, 8, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_write_info(png, info); - - std::unique_ptr rowbuf(new uint8_t[1024 * 2]); - for (int y = 0; y < 512; ++y) { - for (int x = 0; x < 1024; ++x) { - uint8_t texel = buf[y * 1024 + x]; - rowbuf[x * 2] = Convert4To8(texel >> 4 & 0xf); - rowbuf[x * 2 + 1] = Convert4To8(texel & 0xf); - } - png_write_row(png, rowbuf.get()); - } - - png_write_end(png, info); - png_write_flush(png); - png_destroy_write_struct(&png, &info); -} - -void SpecBase::clearTagCache() { - m_tagToPath.clear(); - m_pathToTag.clear(); - m_catalogNameToTag.clear(); - m_catalogTagToNames.clear(); -} - -hecl::ProjectPath SpecBase::pathFromTag(const metaforce::SObjectTag& tag) const { - std::unique_lock lk(m_backgroundIndexMutex); - auto search = m_tagToPath.find(tag); - if (search != m_tagToPath.cend()) - return search->second; - return {}; -} - -metaforce::SObjectTag SpecBase::tagFromPath(const hecl::ProjectPath& path) const { - auto search = m_pathToTag.find(path.hash()); - if (search != m_pathToTag.cend()) - return search->second; - return buildTagFromPath(path); -} - -bool SpecBase::waitForTagReady(const metaforce::SObjectTag& tag, const hecl::ProjectPath*& pathOut) { - std::unique_lock lk(m_backgroundIndexMutex); - auto search = m_tagToPath.find(tag); - if (search == m_tagToPath.end()) { - if (m_backgroundRunning) { - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - search = m_tagToPath.find(tag); - if (search != m_tagToPath.end()) - break; - } - if (search == m_tagToPath.end()) - return false; - } else - return false; - } - lk.unlock(); - pathOut = &search->second; - return true; -} - -const metaforce::SObjectTag* SpecBase::getResourceIdByName(std::string_view name) const { - std::string lower(name); - std::transform(lower.cbegin(), lower.cend(), lower.begin(), tolower); - - std::unique_lock lk(m_backgroundIndexMutex); - auto search = m_catalogNameToTag.find(lower); - if (search == m_catalogNameToTag.end()) { - if (m_backgroundRunning) { - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - search = m_catalogNameToTag.find(lower); - if (search != m_catalogNameToTag.end()) - break; - } - if (search == m_catalogNameToTag.end()) - return nullptr; - } else - return nullptr; - } - return &search->second; -} - -FourCC SpecBase::getResourceTypeById(metaforce::CAssetId id) const { - if (!id.IsValid()) - return {}; - - std::unique_lock lk(m_backgroundIndexMutex); - metaforce::SObjectTag searchTag = {FourCC(), id}; - auto search = m_tagToPath.find(searchTag); - if (search == m_tagToPath.end()) { - if (m_backgroundRunning) { - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - search = m_tagToPath.find(searchTag); - if (search != m_tagToPath.end()) - break; - } - if (search == m_tagToPath.end()) - return {}; - } else - return {}; - } - - return search->first.type; -} - -void SpecBase::enumerateResources(const std::function& lambda) const { - waitForIndexComplete(); - for (const auto& pair : m_tagToPath) { - if (!lambda(pair.first)) - break; - } -} - -void SpecBase::enumerateNamedResources( - const std::function& lambda) const { - waitForIndexComplete(); - for (const auto& pair : m_catalogNameToTag) { - if (!lambda(pair.first, pair.second)) - break; - } -} - -static void WriteTag(athena::io::YAMLDocWriter& cacheWriter, const metaforce::SObjectTag& pathTag, - const hecl::ProjectPath& path) { - auto key = fmt::format(FMT_STRING("{}"), pathTag.id); - if (auto* existing = cacheWriter.getCurNode()->findMapChild(key)) { - existing->m_seqChildren.emplace_back(athena::io::ValToNode(path.getEncodableString())); - } else if (auto v = cacheWriter.enterSubVector(key)) { - cacheWriter.writeString(pathTag.type.toString()); - cacheWriter.writeString(path.getEncodableString()); - } -} - -static void WriteNameTag(athena::io::YAMLDocWriter& nameWriter, const metaforce::SObjectTag& pathTag, - std::string_view name) { - nameWriter.writeString(name.data(), fmt::format(FMT_STRING("{}"), pathTag.id)); -} - -void SpecBase::readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAMLDocWriter& nameWriter) { - athena::io::FileReader freader(catalogPath.getAbsolutePath()); - if (!freader.isOpen()) - return; - - athena::io::YAMLDocReader reader; - bool res = reader.parse(&freader); - if (!res) - return; - - const athena::io::YAMLNode* root = reader.getRootNode(); - for (const auto& p : root->m_mapChildren) { - /* Hash as lowercase since lookup is case-insensitive */ - std::string pLower = p.first; - std::transform(pLower.cbegin(), pLower.cend(), pLower.begin(), tolower); - - /* Avoid redundant filesystem access for re-caches */ - if (m_catalogNameToTag.find(pLower) != m_catalogNameToTag.cend()) - continue; - - athena::io::YAMLNode& node = *p.second; - hecl::ProjectPath path; - if (node.m_type == YAML_SCALAR_NODE) { - path = hecl::ProjectPath(m_project.getProjectWorkingPath(), node.m_scalarString); - } else if (node.m_type == YAML_SEQUENCE_NODE) { - if (node.m_seqChildren.size() >= 2) - path = hecl::ProjectPath(m_project.getProjectWorkingPath(), node.m_seqChildren[0]->m_scalarString) - .ensureAuxInfo(node.m_seqChildren[1]->m_scalarString); - else if (node.m_seqChildren.size() == 1) - path = hecl::ProjectPath(m_project.getProjectWorkingPath(), node.m_seqChildren[0]->m_scalarString); - } - if (path.isNone()) - continue; - metaforce::SObjectTag pathTag = tagFromPath(path); - if (pathTag) { - std::unique_lock lk(m_backgroundIndexMutex); - m_catalogNameToTag[pLower] = pathTag; - m_catalogTagToNames[pathTag].insert(p.first); - - WriteNameTag(nameWriter, pathTag, p.first); -#if 0 - fmt::print(stderr, FMT_STRING("{} {} {:08X}\n"), p.first, pathTag.type.toString(), pathTag.id.Value()); -#endif - } - } -} - -void SpecBase::backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& dir, athena::io::YAMLDocWriter& nameWriter, - int level) { - hecl::DirectoryEnumerator dEnum(dir.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsThenFilesSorted, false, - false, true); - - /* Enumerate all items */ - for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) { - hecl::ProjectPath path(dir, ent.m_name); - if (ent.m_isDir && level < 1) - backgroundIndexRecursiveCatalogs(path, nameWriter, level + 1); - else { - if (!path.isFile()) - continue; - - /* Read catalog.yaml for .pak directory if exists */ - if (level == 1 && ent.m_name == "!catalog.yaml") { - readCatalog(path, nameWriter); - continue; - } - } - - /* bail if cancelled by client */ - if (!m_backgroundRunning) - break; - } -} - -void SpecBase::insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const metaforce::SObjectTag& tag, - const hecl::ProjectPath& path, bool dump) { -#if 0 - auto search = m_tagToPath.find(tag); - /* ANCS subresources are allowed to be weak-linked */ - if (search != m_tagToPath.end() && search->second != path && - tag.type != FOURCC('CINF') && tag.type != FOURCC('CSKR') && - tag.type != FOURCC('ANIM') && tag.type != FOURCC('EVNT')) { - Log.report(logvisor::Fatal, FMT_STRING("'{}|{}' already exists for tag {} as '{}|{}'"), - path.getRelativePath(), path.getAuxInfo(), tag, - search->second.getRelativePath(), search->second.getAuxInfo()); - } -#endif - m_tagToPath.insert(std::make_pair(tag, path)); - m_pathToTag[path.hash()] = tag; - WriteTag(cacheWriter, tag, path); -#if DUMP_CACHE_FILL - if (dump) - fmt::print(stderr, FMT_STRING("{} {}\n"), tag, path.getRelativePath()); -#endif -} - -bool SpecBase::addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter) { - /* Avoid redundant filesystem access for re-caches */ - if (m_pathToTag.find(path.hash()) != m_pathToTag.cend()) - return true; - - /* Try as glob */ - hecl::ProjectPath asGlob = path.getWithExtension(".*", true); - if (m_pathToTag.find(asGlob.hash()) != m_pathToTag.cend()) - return true; - - /* Classify intermediate into tag */ - metaforce::SObjectTag pathTag = buildTagFromPath(path); - if (pathTag) { - std::unique_lock lk{m_backgroundIndexMutex}; - bool useGlob = false; - - /* Special multi-resource intermediates */ - if (pathTag.type == SBIG('ANCS')) { - hecl::blender::Connection& conn = m_backgroundBlender.getBlenderConnection(); - if (!conn.openBlend(path) || conn.getBlendType() != hecl::blender::BlendType::Actor) - return false; - - /* Transform tag to glob */ - pathTag = {SBIG('ANCS'), asGlob.parsedHash32()}; - useGlob = true; - - hecl::blender::DataStream ds = conn.beginData(); - std::vector> subtypeNames = ds.getSubtypeNames(); - std::vector> actionNames = ds.getActionNames(); - - for (const auto& sub : subtypeNames) { - hecl::ProjectPath subPath; - if (!sub.second.empty()) { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.CSKR"), sub.first, sub.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.CSKR"), sub.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - - std::vector> overlayNames = ds.getSubtypeOverlayNames(sub.first); - for (const auto& overlay : overlayNames) { - if (!overlay.second.empty()) { - subPath = asGlob.ensureAuxInfo( - fmt::format(FMT_STRING("{}.{}_{}.CSKR"), sub.first, overlay.first, overlay.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.{}.CSKR"), sub.first, overlay.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - } - } - - std::vector> attachmentNames = ds.getAttachmentNames(); - for (const auto& attachment : attachmentNames) { - hecl::ProjectPath subPath; - if (!attachment.second.empty()) { - subPath = asGlob.ensureAuxInfo( - fmt::format(FMT_STRING("ATTACH.{}_{}.CSKR"), attachment.first, attachment.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("ATTACH.{}.CSKR"), attachment.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - } - - for (const auto& act : actionNames) { - hecl::ProjectPath subPath; - if (!act.second.empty()) { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}_{}.ANIM"), act.first, act.second)); - } else { - subPath = asGlob.ensureAuxInfo(fmt::format(FMT_STRING("{}.ANIM"), act.first)); - } - insertPathTag(cacheWriter, buildTagFromPath(subPath), subPath); - } - } - - /* Cache in-memory */ - const hecl::ProjectPath& usePath = useGlob ? asGlob : path; - insertPathTag(cacheWriter, pathTag, usePath); - } - - return true; -} - -void SpecBase::backgroundIndexRecursiveProc(const hecl::ProjectPath& dir, athena::io::YAMLDocWriter& cacheWriter, - athena::io::YAMLDocWriter& nameWriter, int level) { - hecl::DirectoryEnumerator dEnum(dir.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsThenFilesSorted, false, - false, true); - - /* Enumerate all items */ - for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) { - /* bail if cancelled by client */ - if (!m_backgroundRunning) - break; - - hecl::ProjectPath path(dir, ent.m_name); - if (ent.m_isDir) { - /* Index AGSC here */ - if (hecl::ProjectPath(path, "!project.yaml").isFile() && hecl::ProjectPath(path, "!pool.yaml").isFile()) { - /* Avoid redundant filesystem access for re-caches */ - if (m_pathToTag.find(path.hash()) == m_pathToTag.cend()) { - metaforce::SObjectTag pathTag(SBIG('AGSC'), path.parsedHash32()); - insertPathTag(cacheWriter, pathTag, path); - } - } else { - backgroundIndexRecursiveProc(path, cacheWriter, nameWriter, level + 1); - } - } else { - if (!path.isFile()) - continue; - - /* Read catalog.yaml for .pak directory if exists */ - if (level == 1 && ent.m_name == "!catalog.yaml") { - readCatalog(path, nameWriter); - continue; - } - - /* Index the regular file */ - addFileToIndex(path, cacheWriter); - } - } -} - -void SpecBase::backgroundIndexProc() { - logvisor::RegisterThreadName("Resource Index"); - - hecl::ProjectPath tagCachePath(m_project.getProjectCookedPath(getOriginalSpec()), "tag_cache.yaml"); - hecl::ProjectPath nameCachePath(m_project.getProjectCookedPath(getOriginalSpec()), "name_cache.yaml"); - hecl::ProjectPath specRoot(m_project.getProjectWorkingPath(), getOriginalSpec().m_name); - - /* Cache will be overwritten with validated entries afterwards */ - athena::io::YAMLDocWriter cacheWriter; - athena::io::YAMLDocWriter nameWriter; - - /* Read in tag cache */ - if (tagCachePath.isFile()) { - athena::io::FileReader reader(tagCachePath.getAbsolutePath()); - if (reader.isOpen()) { - Log.report(logvisor::Info, FMT_STRING("Cache index of '{}' loading"), getOriginalSpec().m_name); - athena::io::YAMLDocReader cacheReader; - if (cacheReader.parse(&reader)) { - std::unique_lock lk(m_backgroundIndexMutex); - size_t tagCount = cacheReader.getRootNode()->m_mapChildren.size(); - m_tagToPath.reserve(tagCount); - m_pathToTag.reserve(tagCount); - size_t loadIdx = 0; - for (const auto& child : cacheReader.getRootNode()->m_mapChildren) { - if (!m_backgroundRunning) - return; - - const athena::io::YAMLNode& node = *child.second; - if (node.m_seqChildren.size() >= 2) { - unsigned long id = strtoul(child.first.c_str(), nullptr, 16); - hecl::FourCC type(node.m_seqChildren[0]->m_scalarString.c_str()); - metaforce::SObjectTag pathTag(type, id); - for (auto I = node.m_seqChildren.begin() + 1, E = node.m_seqChildren.end(); I != E; ++I) { - hecl::ProjectPath path(m_project.getProjectWorkingPath(), (*I)->m_scalarString); - if (!path.isNone()) - insertPathTag(cacheWriter, pathTag, path, false); - } - } - - ++loadIdx; - if (!(loadIdx % 100)) - fmt::print(stderr, FMT_STRING("\r {} / {}"), loadIdx, tagCount); - } - fmt::print(stderr, FMT_STRING("\r {} / {}\n"), loadIdx, tagCount); - } - Log.report(logvisor::Info, FMT_STRING("Cache index of '{}' loaded; {} tags"), getOriginalSpec().m_name, - m_tagToPath.size()); - - if (nameCachePath.isFile()) { - /* Read in name cache */ - Log.report(logvisor::Info, FMT_STRING("Name index of '{}' loading"), getOriginalSpec().m_name); - athena::io::FileReader nreader(nameCachePath.getAbsolutePath()); - athena::io::YAMLDocReader nameReader; - if (nameReader.parse(&nreader)) { - std::unique_lock lk(m_backgroundIndexMutex); - m_catalogNameToTag.reserve(nameReader.getRootNode()->m_mapChildren.size()); - m_catalogTagToNames.reserve(nameReader.getRootNode()->m_mapChildren.size()); - for (const auto& child : nameReader.getRootNode()->m_mapChildren) { - unsigned long id = strtoul(child.second->m_scalarString.c_str(), nullptr, 16); - auto search = m_tagToPath.find(metaforce::SObjectTag(FourCC(), uint32_t(id))); - if (search != m_tagToPath.cend()) { - std::string chLower = child.first; - std::transform(chLower.cbegin(), chLower.cend(), chLower.begin(), tolower); - m_catalogNameToTag[chLower] = search->first; - m_catalogTagToNames[search->first].insert(child.first); - WriteNameTag(nameWriter, search->first, child.first); - } - } - } - Log.report(logvisor::Info, FMT_STRING("Name index of '{}' loaded; {} names"), - getOriginalSpec().m_name, m_catalogNameToTag.size()); - } - } - } - - Log.report(logvisor::Info, FMT_STRING("Background index of '{}' started"), getOriginalSpec().m_name); - backgroundIndexRecursiveProc(specRoot, cacheWriter, nameWriter, 0); - - tagCachePath.makeDirChain(false); - athena::io::FileWriter twriter(tagCachePath.getAbsolutePath()); - cacheWriter.finish(&twriter); - - athena::io::FileWriter nwriter(nameCachePath.getAbsolutePath()); - nameWriter.finish(&nwriter); - - m_backgroundBlender.shutdown(); - Log.report(logvisor::Info, FMT_STRING("Background index of '{}' complete; {} tags, {} names"), - getOriginalSpec().m_name, m_tagToPath.size(), m_catalogNameToTag.size()); - m_backgroundRunning = false; -} - -void SpecBase::cancelBackgroundIndex() { - m_backgroundRunning = false; - if (m_backgroundIndexTh.joinable()) - m_backgroundIndexTh.join(); -} - -void SpecBase::beginBackgroundIndex() { - cancelBackgroundIndex(); - clearTagCache(); - m_backgroundRunning = true; - m_backgroundIndexTh = std::thread(&SpecBase::backgroundIndexProc, this); -} - -void SpecBase::waitForIndexComplete() const { - std::unique_lock lk(m_backgroundIndexMutex); - while (m_backgroundRunning) { - lk.unlock(); - std::this_thread::sleep_for(std::chrono::milliseconds(2)); - lk.lock(); - } -} - -void SpecBase::WriteVersionInfo(hecl::Database::Project& project, const hecl::ProjectPath& pakPath) { - hecl::ProjectPath versionPath(pakPath, "version.yaml"); - versionPath.makeDirChain(false); - - MetaforceVersionInfo info; - info.version = m_version; - info.region = m_region; - info.game = m_game; - info.isTrilogy = !m_standalone; - athena::io::FileWriter writer(versionPath.getAbsolutePath()); - athena::io::ToYAMLStream(info, writer); -} -void SpecBase::setCurRegion(ERegion region) { g_CurRegion = region; } -void SpecBase::setCurSpecIsWii(bool isWii) { g_CurSpecIsWii = isWii; } - -} // namespace DataSpec diff --git a/DataSpec/SpecBase.hpp b/DataSpec/SpecBase.hpp deleted file mode 100644 index f7a02763d..000000000 --- a/DataSpec/SpecBase.hpp +++ /dev/null @@ -1,219 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include "hecl/Database.hpp" -#include "hecl/Blender/Token.hpp" -#include "Runtime/RetroTypes.hpp" - -namespace nod { -class DiscBase; -class Node; -} // namespace nod - -namespace athena::io { -class FileWriter; -class YAMLDocWriter; -} // namespace athena::io - -namespace DataSpec { -enum class ERegion; -enum class EGame; -ERegion getCurrentRegion(); -bool isCurrentSpecWii(); - -struct SpecBase : hecl::Database::IDataSpec { - /* HECL Adaptors */ - void setThreadProject() override; - bool canExtract(const ExtractPassInfo& info, std::vector& reps) override; - void doExtract(const ExtractPassInfo& info, const hecl::MultiProgressPrinter& progress) override; - - bool canCook(const hecl::ProjectPath& path, hecl::blender::Token& btok) override; - const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path, - const hecl::Database::DataSpecEntry* oldEntry) const override; - void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::blender::Token& btok, - FCookProgress progress) override; - - bool canPackage(const hecl::ProjectPath& path) override; - void doPackage(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* entry, bool fast, - hecl::blender::Token& btok, const hecl::MultiProgressPrinter& progress, - hecl::ClientProcess* cp) override; - - void interruptCook() override; - - /* Extract handlers */ - virtual bool checkStandaloneID(const char* id) const = 0; - virtual bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, - std::vector& reps) = 0; - virtual bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) = 0; - virtual bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) = 0; - - /* Convert path to object tag */ - virtual metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const = 0; - - /* Even if PC spec is being cooked, this will return the vanilla GCN spec */ - virtual const hecl::Database::DataSpecEntry& getOriginalSpec() const = 0; - - /* This will return a pseudo-spec for unmodified resources */ - virtual const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const = 0; - - /* Basic path check (game directory matching) */ - virtual bool checkPathPrefix(const hecl::ProjectPath& path) const = 0; - - /* Pre-cook handlers */ - virtual bool validateYAMLDNAType(athena::io::IStreamReader& fp) const = 0; - - std::optional compileWorldFromDir(const hecl::ProjectPath& dir, - hecl::blender::Token& btok) const; - - /* Cook handlers */ - using BlendStream = hecl::blender::DataStream; - using Mesh = hecl::blender::Mesh; - using Armature = hecl::blender::Armature; - using ColMesh = hecl::blender::ColMesh; - using PathMesh = hecl::blender::PathMesh; - using Light = hecl::blender::Light; - using Actor = hecl::blender::Actor; - - virtual void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0; - virtual void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) = 0; - virtual void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) = 0; - virtual void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) = 0; - - /* Dependency flatteners */ - void flattenDependencies(const hecl::ProjectPath& in, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx = -1); - void flattenDependencies(const class UniqueID32& id, std::vector& pathsOut, int charIdx = -1); - void flattenDependencies(const class UniqueID64& id, std::vector& pathsOut, int charIdx = -1); - void flattenDependenciesBlend(const hecl::ProjectPath& in, std::vector& pathsOut, - hecl::blender::Token& btok, int charIdx = -1); - virtual void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) = 0; - virtual void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx = -1) = 0; - - virtual void buildWorldPakList(const hecl::ProjectPath& worldPath, const hecl::ProjectPath& worldPathCooked, - hecl::blender::Token& btok, athena::io::FileWriter& w, - std::vector& listOut, atUint64& resTableOffset, - std::unordered_map>& mlvlData) {} - virtual void buildPakList(hecl::blender::Token& btok, athena::io::FileWriter& w, - const std::vector& list, - const std::vector>& nameList, - atUint64& resTableOffset) {} - virtual void writePakFileIndex(athena::io::FileWriter& w, const std::vector& tags, - const std::vector>& index, atUint64 resTableOffset) {} - virtual std::pair, size_t> compressPakData(const metaforce::SObjectTag& tag, - const uint8_t* data, size_t len) { - return {}; - } - - const hecl::ProjectPath& getMasterShaderPath() const { return m_masterShader; } - - /* Support functions for resolving paths from IDs */ - virtual hecl::ProjectPath getWorking(class UniqueID32&) { return hecl::ProjectPath(); } - virtual hecl::ProjectPath getWorking(class UniqueID64&) { return hecl::ProjectPath(); } - - hecl::ProjectPath getCookedPath(const hecl::ProjectPath& working, bool pcTarget) const; - - /* Project accessor */ - hecl::Database::Project& getProject() const { return m_project; } - - /* Extract RandomStatic entropy */ - void extractRandomStaticEntropy(const uint8_t* buf, const hecl::ProjectPath& pakPath); - - /* Tag cache functions */ - metaforce::SObjectTag tagFromPath(const hecl::ProjectPath& path) const; - hecl::ProjectPath pathFromTag(const metaforce::SObjectTag& tag) const; - bool waitForTagReady(const metaforce::SObjectTag& tag, const hecl::ProjectPath*& pathOut); - const metaforce::SObjectTag* getResourceIdByName(std::string_view name) const; - hecl::FourCC getResourceTypeById(metaforce::CAssetId id) const; - void enumerateResources(const std::function& lambda) const; - void enumerateNamedResources(const std::function& lambda) const; - void cancelBackgroundIndex(); - void beginBackgroundIndex(); - bool backgroundIndexRunning() const { return m_backgroundRunning; } - void waitForIndexComplete() const; - - virtual void getTagListForFile(const char* pakName, std::vector& out) const {} - - SpecBase(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc); - ~SpecBase(); - -protected: - hecl::Database::Project& m_project; - bool m_pc; - hecl::ProjectPath m_masterShader; - - std::unordered_multimap m_tagToPath; - std::unordered_map m_pathToTag; - std::unordered_map m_catalogNameToTag; - std::unordered_map> m_catalogTagToNames; - void clearTagCache(); - - hecl::blender::Token m_backgroundBlender; - std::thread m_backgroundIndexTh; - mutable std::mutex m_backgroundIndexMutex; - bool m_backgroundRunning = false; - - void readCatalog(const hecl::ProjectPath& catalogPath, athena::io::YAMLDocWriter& nameWriter); - void insertPathTag(athena::io::YAMLDocWriter& cacheWriter, const metaforce::SObjectTag& tag, - const hecl::ProjectPath& path, bool dump = true); - bool addFileToIndex(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter); - void backgroundIndexRecursiveProc(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& cacheWriter, - athena::io::YAMLDocWriter& nameWriter, int level); - void backgroundIndexRecursiveCatalogs(const hecl::ProjectPath& path, athena::io::YAMLDocWriter& nameWriter, - int level); - void backgroundIndexProc(); - - void recursiveBuildResourceList(std::vector& listOut, - std::unordered_set& addedTags, const hecl::ProjectPath& path, - hecl::blender::Token& btok); - void copyBuildListData(std::vector>& fileIndex, - const std::vector& buildList, - const hecl::Database::DataSpecEntry* entry, bool fast, - const hecl::MultiProgressPrinter& progress, athena::io::FileWriter& pakOut, - const std::unordered_map>& mlvlData); - - std::unique_ptr m_disc; - bool m_isWii{}; - bool m_standalone{}; - ERegion m_region; - EGame m_game; - std::string m_version; - - void WriteVersionInfo(hecl::Database::Project& project, const hecl::ProjectPath& pakPath); - - static void setCurRegion(ERegion region); - static void setCurSpecIsWii(bool isWii); -}; - -bool IsPathAudioGroup(const hecl::ProjectPath& path); - -} // namespace DataSpec diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp deleted file mode 100644 index e60408956..000000000 --- a/DataSpec/SpecMP1.cpp +++ /dev/null @@ -1,1271 +0,0 @@ -#include -#include -#include - -#include "SpecBase.hpp" -#include "DNAMP1/DNAMP1.hpp" - -#include "DNAMP1/HINT.hpp" -#include "DNAMP1/MLVL.hpp" -#include "DNAMP1/STRG.hpp" -#include "DNAMP1/SCAN.hpp" -#include "DNAMP1/CMDL.hpp" -#include "DNAMP1/DCLN.hpp" -#include "DNAMP1/MREA.hpp" -#include "DNAMP1/ANCS.hpp" -#include "DNAMP1/AGSC.hpp" -#include "DNAMP1/CSNG.hpp" -#include "DNAMP1/MAPA.hpp" -#include "DNAMP1/PATH.hpp" -#include "DNAMP1/FRME.hpp" -#include "DNAMP1/AFSM.hpp" -#include "DNACommon/ATBL.hpp" -#include "DNACommon/FONT.hpp" -#include "DNACommon/PART.hpp" -#include "DNACommon/SWHC.hpp" -#include "DNACommon/ELSC.hpp" -#include "DNACommon/WPSC.hpp" -#include "DNACommon/CRSC.hpp" -#include "DNACommon/DPSC.hpp" -#include "DNACommon/DGRP.hpp" -#include "DNACommon/MAPU.hpp" -#include "DNACommon/MetaforceVersionInfo.hpp" -#include "DNACommon/Tweaks/TweakWriter.hpp" -#include "DNAMP1/Tweaks/CTweakPlayerRes.hpp" -#include "DNAMP1/Tweaks/CTweakGunRes.hpp" -#include "DNAMP1/Tweaks/CTweakSlideShow.hpp" -#include "DNAMP1/Tweaks/CTweakPlayer.hpp" -#include "DNAMP1/Tweaks/CTweakCameraBob.hpp" -#include "DNAMP1/Tweaks/CTweakGame.hpp" -#include "DNAMP1/Tweaks/CTweakTargeting.hpp" -#include "DNAMP1/Tweaks/CTweakAutoMapper.hpp" -#include "DNAMP1/Tweaks/CTweakGui.hpp" -#include "DNAMP1/Tweaks/CTweakPlayerControl.hpp" -#include "DNAMP1/Tweaks/CTweakBall.hpp" -#include "DNAMP1/Tweaks/CTweakParticle.hpp" -#include "DNAMP1/Tweaks/CTweakGuiColors.hpp" -#include "DNAMP1/Tweaks/CTweakPlayerGun.hpp" -#include "DNAMP1/MazeSeeds.hpp" -#include "DNAMP1/SnowForces.hpp" -#include "hecl/ClientProcess.hpp" -#include "hecl/MultiProgressPrinter.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/Blender/SDNARead.hpp" -#include "nod/nod.hpp" - -namespace DataSpec { - -using namespace std::literals; - -static logvisor::Module Log("DataSpec::SpecMP1"); -extern hecl::Database::DataSpecEntry SpecEntMP1; -extern hecl::Database::DataSpecEntry SpecEntMP1PC; -extern hecl::Database::DataSpecEntry SpecEntMP1ORIG; - -struct TextureCache { - static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, - const hecl::ProjectPath& pakPath) { - hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - texturePath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath()); - } - - Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)...")); - std::unordered_map metaMap; - - pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) { - if (ent->type == FOURCC('TXTR') && metaMap.find(ent->id) == metaMap.end()) { - PAKEntryReadStream rs = pakRouter.beginReadStreamForId(ent->id); - metaMap[ent->id] = TXTR::GetMetaData(rs); - } - return true; - }); - - athena::io::YAMLDocWriter yamlW("MP1TextureCache"); - for (const auto& pair : metaMap) { - hecl::ProjectPath path = pakRouter.getWorking(pair.first); - auto rec = yamlW.enterSubRecord(path.getRelativePath()); - pair.second.write(yamlW); - } - - athena::io::FileWriter fileW(texturePath.getAbsolutePath()); - yamlW.finish(&fileW); - Log.report(logvisor::Level::Info, FMT_STRING("Done...")); - } - - static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::Database::Project& project = inPath.getProject(); - athena::io::YAMLDocReader r; - athena::io::FileReader fr(inPath.getAbsolutePath()); - if (!fr.isOpen() || !r.parse(&fr)) - return; - - std::vector> metaPairs; - metaPairs.reserve(r.getRootNode()->m_mapChildren.size()); - for (const auto& node : r.getRootNode()->m_mapChildren) { - hecl::ProjectPath projectPath(project, node.first); - auto rec = r.enterSubRecord(node.first.c_str()); - TXTR::Meta meta; - meta.read(r); - metaPairs.emplace_back(projectPath.parsedHash32(), meta); - } - - std::sort(metaPairs.begin(), metaPairs.end(), - [](const auto& a, const auto& b) -> bool { return a.first < b.first; }); - - athena::io::FileWriter w(outPath.getAbsolutePath()); - w.writeUint32Big(metaPairs.size()); - for (const auto& pair : metaPairs) { - pair.first.write(w); - pair.second.write(w); - } - } -}; - -struct SpecMP1 : SpecBase { - bool checkStandaloneID(const char* id) const override { return !memcmp(id, "GM8", 3); } - - std::vector m_nonPaks; - std::vector m_paks; - std::map m_orderedPaks; - - hecl::ProjectPath m_workPath; - hecl::ProjectPath m_cookPath; - PAKRouter m_pakRouter; - - std::unique_ptr m_dolBuf; - - std::unordered_map m_mreaPathToXF; - - SpecMP1(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) - : SpecBase(specEntry, project, pc) - , m_workPath(project.getProjectWorkingPath(), "MP1") - , m_cookPath(project.getProjectCookedPath(SpecEntMP1), "MP1") - , m_pakRouter(*this, m_workPath, m_cookPath) { - m_game = EGame::MetroidPrime1; - SpecBase::setThreadProject(); - } - - void buildPaks(nod::Node& root, const std::vector& args, ExtractReport& rep) { - m_nonPaks.clear(); - m_paks.clear(); - for (const nod::Node& child : root) { - bool isPak = false; - auto name = child.getName(); - std::string lowerName(name); - hecl::ToLower(lowerName); - if (name.size() > 4) { - std::string::iterator extit = lowerName.end() - 4; - if (std::string(extit, lowerName.end()) == ".pak") { - /* This is a pak */ - isPak = true; - std::string lowerBase(lowerName.begin(), extit); - - /* Needs filter */ - bool good = true; - if (args.size()) { - good = false; - if (!lowerName.compare(0, 7, "metroid")) { - char idxChar = lowerName[7]; - for (const std::string& arg : args) { - if (arg.size() == 1 && iswdigit(arg[0])) - if (arg[0] == idxChar) - good = true; - } - } else - good = true; - - if (!good) { - for (const std::string& arg : args) { - std::string lowerArg(arg); - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, lowerBase.size(), lowerBase)) - good = true; - } - } - } - - m_paks.emplace_back(child, good); - } - } - - if (!isPak) - m_nonPaks.push_back(&child); - } - - /* Sort PAKs alphabetically */ - m_orderedPaks.clear(); - for (DNAMP1::PAKBridge& dpak : m_paks) { - m_orderedPaks[std::string(dpak.getName())] = &dpak; - } - - /* Assemble extract report */ - rep.childOpts.reserve(m_orderedPaks.size()); - for (const auto& item : m_orderedPaks) { - if (!item.second->m_doExtract) { - continue; - } - - ExtractReport& childRep = rep.childOpts.emplace_back(); - childRep.name = item.first; - childRep.desc = item.second->getLevelString(); - } - } - - bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - nod::IPartition* partition = disc.getDataPartition(); - m_dolBuf = partition->getDOLBuf(); - const char* buildInfo = - static_cast(memmem(m_dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16)) + 19; - - if (buildInfo == nullptr) - return false; - - m_version = std::string(buildInfo); - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP1"; - rep.desc = "Metroid Prime " + regstr; - if (buildInfo) { - rep.desc += " (" + m_version + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node& root = partition->getFSTRoot(); - buildPaks(root, args, rep); - - return true; - } - - bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - std::vector mp1args; - bool doExtract = false; - if (args.size()) { - /* Needs filter */ - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 3, "mp1")) { - doExtract = true; - mp1args.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - mp1args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - } else - doExtract = true; - - if (!doExtract) - return false; - - nod::IPartition* partition = disc.getDataPartition(); - nod::Node& root = partition->getFSTRoot(); - nod::Node::DirectoryIterator dolIt = root.find("rs5mp1_p.dol"); - if (dolIt == root.end()) { - dolIt = root.find("rs5mp1jpn_p.dol"); - if (dolIt == root.end()) - return false; - } - - m_dolBuf = dolIt->getBuf(); - const char* buildInfo = static_cast(memmem(m_dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16)) + 19; - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP1"; - rep.desc = "Metroid Prime " + regstr; - if (buildInfo != nullptr) { - m_version = std::string(buildInfo); - rep.desc += " (" + m_version + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator mp1It = root.find("MP1"); - if (mp1It == root.end()) { - mp1It = root.find("MP1JPN"); - if (mp1It == root.end()) - return false; - } - buildPaks(*mp1It, mp1args, rep); - - return true; - } - - bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override { - m_project.enableDataSpecs({"MP1-PC"}); - - nod::ExtractionContext ctx = {force, nullptr}; - - m_workPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_pakRouter.build(m_paks, - [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - hecl::ProjectPath mp1OutPath(outPath, "files/MP1"); - mp1OutPath.makeDirChain(true); - - /* Extract non-pak files */ - progress.startNewLine(); - progress.print("MP1 Root", "", 0.0); - int prog = 0; - ctx.progressCB = [&](std::string_view name, float) { - progress.print("MP1 Root", name, prog / (float)m_nonPaks.size()); - }; - for (const nod::Node* node : m_nonPaks) { - node->extractToDirectory(mp1OutPath.getAbsolutePath(), ctx); - prog++; - } - progress.print("MP1 Root", "", 1.0); - - /* Extract unique resources */ - hecl::ClientProcess process; - progress.startNewLine(); - for (std::pair& pair : m_orderedPaks) { -#if 0 - const DNAMP1::PAK::Entry* ent = pair.second->getPAK().lookupEntry(UniqueID32(0xE39FC9A1)); - if (ent) { - PAKEntryReadStream rs = ent->beginReadStream(pair.second->getNode()); - DNAMP1::CMDL::Extract(*this, rs, hecl::ProjectPath(m_project.getProjectWorkingPath(), "MP1/Metroid1/!1IntroLevel1027/CMDL_E39FC9A1.blend"), m_pakRouter, *ent, true, hecl::blender::SharedBlenderToken, {}); - - ent = pair.second->getPAK().lookupEntry(UniqueID32(0xC1AE2B4A)); - rs = ent->beginReadStream(pair.second->getNode()); - DNAMP1::CMDL::Extract(*this, rs, hecl::ProjectPath(m_project.getProjectWorkingPath(), "MP1/Metroid1/!1IntroLevel1027/CMDL_C1AE2B4A.blend"), m_pakRouter, *ent, true, hecl::blender::SharedBlenderToken, {}); - - exit(0); - } - else - continue; -#endif - - DNAMP1::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - auto pakName = std::string(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - int threadIdx = hecl::ClientProcess::GetThreadWorkerIdx(); - m_pakRouter.extractResources(pak, force, btok, - [&progress, &pakName, threadIdx](const char* substr, float factor) { - progress.print(pakName, substr, factor, threadIdx); - }); - }); - } - - process.waitUntilComplete(); - - /* Extract part of .dol for RandomStatic entropy */ - hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), "MP1/URDE"); - extractRandomStaticEntropy(m_dolBuf.get() + 0x4f60, noAramPath); - - /* Generate Texture Cache containing meta data for every texture file */ - TextureCache::Generate(m_pakRouter, m_project, noAramPath); - - /* Write version data */ - hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/MP1"); - WriteVersionInfo(m_project, versionPath); - return true; - } - - const hecl::Database::DataSpecEntry& getOriginalSpec() const override { return SpecEntMP1; } - - const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const override { return SpecEntMP1ORIG; } - - hecl::ProjectPath getWorking(class UniqueID32& id) override { return m_pakRouter.getWorking(id); } - - bool checkPathPrefix(const hecl::ProjectPath& path) const override { - return path.getRelativePath().compare(0, 4, "MP1/") == 0; - } - - bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { - athena::io::YAMLDocReader reader; - yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp); - return reader.ClassTypeOperation([](std::string_view classType) { - if (classType == DNAMP1::MLVL::DNAType()) - return true; - else if (classType == DNAMP1::STRG::DNAType()) - return true; - else if (classType == DNAMP1::SCAN::DNAType()) - return true; - else if (classType == DNAParticle::GPSM::DNAType()) - return true; - else if (classType == DNAParticle::SWSH::DNAType()) - return true; - else if (classType == DNAParticle::ELSM::DNAType()) - return true; - else if (classType == DNAParticle::WPSM::DNAType()) - return true; - else if (classType == DNAParticle::CRSM::DNAType()) - return true; - else if (classType == DNAParticle::DPSM::DNAType()) - return true; - else if (classType == DNADGRP::DGRP::DNAType()) - return true; - else if (classType == DNAFont::FONT::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerRes::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerRes::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGunRes::DNAType()) - return true; - else if (classType == DNAMP1::CTweakSlideShow::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayer::DNAType()) - return true; - else if (classType == DNAMP1::CTweakCameraBob::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGame::DNAType()) - return true; - else if (classType == DNAMP1::CTweakAutoMapper::DNAType()) - return true; - else if (classType == DNAMP1::CTweakTargeting::DNAType()) - return true; - else if (classType == DNAMP1::CTweakTargeting::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGui::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerControl::DNAType()) - return true; - else if (classType == DNAMP1::CTweakBall::DNAType()) - return true; - else if (classType == DNAMP1::CTweakParticle::DNAType()) - return true; - else if (classType == DNAMP1::CTweakGuiColors::DNAType()) - return true; - else if (classType == DNAMP1::CTweakPlayerGun::DNAType()) - return true; - else if (classType == DNAMP1::HINT::DNAType()) - return true; - else if (classType == DNAMP1::EVNT::DNAType()) - return true; - else if (classType == DNAMP1::MazeSeeds::DNAType()) - return true; - else if (classType == DNAMP1::SnowForces::DNAType()) - return true; - else if (classType == "ATBL") - return true; - else if (classType == DNAMP1::AFSM::DNAType()) - return true; - else if (classType == "MP1TextureCache") - return true; - return false; - }); - } - - metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override { - if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR")) - return {SBIG('CSKR'), path.parsedHash32()}; - else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM")) - return {SBIG('ANIM'), path.parsedHash32()}; - else if (const char* ext = path.getLastComponentExt().data()) { - if (ext[0] == '*' || !hecl::StrCmp(ext, "mid")) { - if (path.getWithExtension(".mid", true).isFile() && - path.getWithExtension(".yaml", true).isFile()) { - hecl::ProjectPath glob = path.getWithExtension(".*", true); - return {SBIG('CSNG'), glob.parsedHash32()}; - } - } - } - - if (path.getPathType() == hecl::ProjectPath::Type::Directory) { - if (hecl::ProjectPath(path, "!project.yaml").isFile() && - hecl::ProjectPath(path, "!pool.yaml").isFile()) - return {SBIG('AGSC'), path.parsedHash32()}; - } - - hecl::ProjectPath asBlend; - if (path.getPathType() == hecl::ProjectPath::Type::Glob) - asBlend = path.getWithExtension(".blend", true); - else - asBlend = path; - - if (hecl::IsPathBlend(asBlend)) { - switch (hecl::blender::GetBlendType(asBlend.getAbsolutePath())) { - case hecl::blender::BlendType::Mesh: - return {SBIG('CMDL'), path.parsedHash32()}; - case hecl::blender::BlendType::ColMesh: - return {SBIG('DCLN'), path.parsedHash32()}; - case hecl::blender::BlendType::Armature: - return {SBIG('CINF'), path.parsedHash32()}; - case hecl::blender::BlendType::PathMesh: - return {SBIG('PATH'), path.parsedHash32()}; - case hecl::blender::BlendType::Actor: - if (path.getAuxInfo().size()) { - if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".CSKR")) - return {SBIG('CSKR'), path.getWithExtension(".*", true).parsedHash32()}; - else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), ".ANIM")) - return {SBIG('ANIM'), path.getWithExtension(".*", true).parsedHash32()}; - } - return {SBIG('ANCS'), path.getWithExtension(".*", true).parsedHash32()}; - case hecl::blender::BlendType::Area: - return {SBIG('MREA'), path.parsedHash32()}; - case hecl::blender::BlendType::World: - return {SBIG('MLVL'), path.getWithExtension(".*", true).parsedHash32()}; - case hecl::blender::BlendType::MapArea: - return {SBIG('MAPA'), path.parsedHash32()}; - case hecl::blender::BlendType::MapUniverse: - return {SBIG('MAPU'), path.parsedHash32()}; - case hecl::blender::BlendType::Frame: - return {SBIG('FRME'), path.parsedHash32()}; - default: - return {}; - } - } else if (hecl::IsPathPNG(path)) { - return {SBIG('TXTR'), path.parsedHash32()}; - } else if (hecl::IsPathYAML(path)) { - auto fp = hecl::FopenUnique(path.getAbsolutePath().data(), "r"); - if (fp == nullptr) { - return {}; - } - - athena::io::YAMLDocReader reader; - yaml_parser_set_input_file(reader.getParser(), fp.get()); - - metaforce::SObjectTag resTag; - if (reader.ClassTypeOperation([&](std::string_view className) { - if (className == DNAParticle::GPSM::DNAType()) { - resTag.type = SBIG('PART'); - return true; - } - if (className == DNAParticle::SWSH::DNAType()) { - resTag.type = SBIG('SWHC'); - return true; - } - if (className == DNAParticle::ELSM::DNAType()) { - resTag.type = SBIG('ELSC'); - return true; - } - if (className == DNAParticle::WPSM::DNAType()) { - resTag.type = SBIG('WPSC'); - return true; - } - if (className == DNAParticle::CRSM::DNAType()) { - resTag.type = SBIG('CRSC'); - return true; - } - if (className == DNAParticle::DPSM::DNAType()) { - resTag.type = SBIG('DPSC'); - return true; - } else if (className == DNAFont::FONT::DNAType()) { - resTag.type = SBIG('FONT'); - return true; - } else if (className == DNAMP1::EVNT::DNAType()) { - resTag.type = SBIG('EVNT'); - return true; - } else if (className == DNADGRP::DGRP::DNAType()) { - resTag.type = SBIG('DGRP'); - return true; - } else if (className == DataSpec::DNAMP1::STRG::DNAType()) { - resTag.type = SBIG('STRG'); - return true; - } else if (className == DataSpec::DNAMP1::SCAN::DNAType()) { - resTag.type = SBIG('SCAN'); - return true; - } else if (className == DataSpec::DNAMP1::CTweakPlayerRes::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayerRes::DNAType() || - className == DataSpec::DNAMP1::CTweakGunRes::DNAType() || - className == DataSpec::DNAMP1::CTweakSlideShow::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayer::DNAType() || - className == DataSpec::DNAMP1::CTweakCameraBob::DNAType() || - className == DataSpec::DNAMP1::CTweakGame::DNAType() || - className == DataSpec::DNAMP1::CTweakTargeting::DNAType() || - className == DataSpec::DNAMP1::CTweakTargeting::DNAType() || - className == DataSpec::DNAMP1::CTweakAutoMapper::DNAType() || - className == DataSpec::DNAMP1::CTweakGui::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayerControl::DNAType() || - className == DataSpec::DNAMP1::CTweakBall::DNAType() || - className == DataSpec::DNAMP1::CTweakParticle::DNAType() || - className == DataSpec::DNAMP1::CTweakGuiColors::DNAType() || - className == DataSpec::DNAMP1::CTweakPlayerGun::DNAType()) { - resTag.type = SBIG('CTWK'); - return true; - } else if (className == DataSpec::DNAMP1::MazeSeeds::DNAType() || - className == DataSpec::DNAMP1::SnowForces::DNAType()) { - resTag.type = SBIG('DUMB'); - return true; - } else if (className == DataSpec::DNAMP1::HINT::DNAType()) { - resTag.type = SBIG('HINT'); - return true; - } else if (className == "ATBL") { - resTag.type = SBIG('ATBL'); - return true; - } else if (className == DataSpec::DNAMP1::AFSM::DNAType()) { - resTag.type = SBIG('AFSM'); - return true; - } else if (className == "MP1TextureCache") { - resTag.type = SBIG('TMET'); - return true; - } else if (className == "DataSpec::DNAMP1::SAVW") { - resTag.type = SBIG('SAVW'); - return true; - } else if (className == "DataSpec::DNAMP1::MAPW") { - resTag.type = SBIG('MAPW'); - return true; - } - - return false; - })) { - resTag.id = path.parsedHash32(); - fp.reset(); - return resTag; - } - } - return {}; - } - - void getTagListForFile(const char* pakName, std::vector& out) const override { - std::string pathPrefix("MP1/"); - pathPrefix += pakName; - pathPrefix += '/'; - - std::unique_lock lk(m_backgroundIndexMutex); - for (const auto& tag : m_tagToPath) - if (!tag.second.getRelativePath().compare(0, pathPrefix.size(), pathPrefix)) - out.push_back(tag.first); - } - - void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - Mesh mesh = ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, m_pc ? 16 : -1); - - if (m_pc) - DNAMP1::CMDL::HMDLCook(out, in, mesh); - else - DNAMP1::CMDL::Cook(out, in, mesh); - } - - void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - std::vector mesh = ds.compileColMeshes(); - ds.close(); - DNAMP1::DCLN::Cook(out, mesh); - } - - void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - Armature armature = ds.compileArmature(); - ds.close(); - DNAMP1::CINF::Cook(out, in, armature); - } - - void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - PathMesh mesh = ds.compilePathMesh(); - ds.close(); - DNAMP1::PATH::Cook(out, in, mesh, btok); - } - - void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - if (hecl::StringUtils::EndsWith(in.getAuxInfo(), ".CSKR")) { - Actor actor = ds.compileActorCharacterOnly(); - ds.close(); - if (m_pc) { - DNAMP1::ANCS::CookCSKRPC(out, in, actor, [&](const hecl::ProjectPath& modelPath) { - hecl::ProjectPath cooked = modelPath.getCookedPath(SpecEntMP1PC); - doCook(modelPath, cooked, fast, btok, progress); - return true; - }); - } else { - DNAMP1::ANCS::CookCSKR(out, in, actor, [&](const hecl::ProjectPath& modelPath) { - hecl::ProjectPath cooked = modelPath.getCookedPath(SpecEntMP1); - doCook(modelPath, cooked, fast, btok, progress); - return true; - }); - } - } else if (hecl::StringUtils::EndsWith(in.getAuxInfo(), ".ANIM")) { - Actor actor = ds.compileActorCharacterOnly(); - DNAMP1::ANCS::CookANIM(out, in, actor, ds, m_pc); - } else { - Actor actor = ds.compileActor(); - DNAMP1::ANCS::Cook(out, in, actor); - } - } - - void buildAreaXFs(hecl::blender::Token& btok) { - hecl::blender::Connection& conn = btok.getBlenderConnection(); - for (const auto& ent : m_workPath.enumerateDir()) { - if (ent.m_isDir) { - hecl::ProjectPath pakPath(m_workPath, ent.m_name); - for (const auto& ent2 : pakPath.enumerateDir()) { - if (ent2.m_isDir) { - hecl::ProjectPath wldDir(pakPath, ent2.m_name); - for (const auto& ent3 : wldDir.enumerateDir()) { - if (hecl::StringUtils::BeginsWith(ent3.m_name, "!world") && - hecl::StringUtils::EndsWith(ent3.m_name, ".blend")) { - hecl::ProjectPath wldPath(wldDir, ent3.m_name); - if (wldPath.isFile()) { - if (!conn.openBlend(wldPath)) - continue; - hecl::blender::DataStream ds = conn.beginData(); - hecl::blender::World world = ds.compileWorld(); - for (const auto& area : world.areas) - m_mreaPathToXF[area.path.hash()] = area.transform; - } - break; - } - } - } - } - } - } - } - - void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - std::vector meshes = ds.getMeshList(); - std::vector meshCompiles; - meshCompiles.reserve(meshes.size()); - - std::optional colMesh; - - for (const std::string& mesh : meshes) { - if (mesh == "CMESH") { - colMesh = ds.compileColMesh(mesh); - progress("Collision Mesh"); - continue; - } - meshCompiles.push_back( - ds.compileMesh(mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, !m_pc)); - } - - if (!colMesh) - Log.report(logvisor::Fatal, FMT_STRING("unable to find mesh named 'CMESH' in {}"), - in.getAbsolutePath()); - - std::vector lights = ds.compileLights(); - - ds.close(); - - if (m_mreaPathToXF.empty()) - buildAreaXFs(btok); - - const hecl::blender::Matrix4f* xf = nullptr; - auto xfSearch = m_mreaPathToXF.find(in.getParentPath().hash()); - if (xfSearch != m_mreaPathToXF.cend()) - xf = &xfSearch->second; - DNAMP1::MREA::Cook(out, in, meshCompiles, *colMesh, lights, btok, xf, m_pc); - } - - void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::World world = ds.compileWorld(); - ds.close(); - DNAMP1::MLVL::Cook(out, in, world, btok); - } - - void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - auto data = ds.compileGuiFrame(0); - athena::io::MemoryReader r(data.data(), data.size()); - DNAMP1::FRME frme; - frme.read(r); - athena::io::FileWriter w(out.getAbsolutePath()); - frme.write(w); - } - - void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) override { - athena::io::YAMLDocReader reader; - if (reader.parse(&fin)) { - std::string classStr = reader.readString("DNAType"); - if (classStr.empty()) - return; - - if (classStr == DNAMP1::STRG::DNAType()) { - DNAMP1::STRG strg; - strg.read(reader); - DNAMP1::STRG::Cook(strg, out); - } else if (classStr == DNAMP1::SCAN::DNAType()) { - DNAMP1::SCAN scan; - scan.read(reader); - DNAMP1::SCAN::Cook(scan, out); - } else if (classStr == DNAParticle::GPSM::DNAType()) { - DNAParticle::GPSM gpsm; - gpsm.read(reader); - DNAParticle::WriteGPSM(gpsm, out); - } else if (classStr == DNAParticle::SWSH::DNAType()) { - DNAParticle::SWSH swsh; - swsh.read(reader); - DNAParticle::WriteSWSH(swsh, out); - } else if (classStr == DNAParticle::ELSM::DNAType()) { - DNAParticle::ELSM elsm; - elsm.read(reader); - DNAParticle::WriteELSM(elsm, out); - } else if (classStr == DNAParticle::WPSM::DNAType()) { - DNAParticle::WPSM wpsm; - wpsm.read(reader); - DNAParticle::WriteWPSM(wpsm, out); - } else if (classStr == DNAParticle::CRSM::DNAType()) { - DNAParticle::CRSM crsm; - crsm.read(reader); - DNAParticle::WriteCRSM(crsm, out); - } else if (classStr == DNAParticle::DPSM::DNAType()) { - DNAParticle::DPSM dpsm; - dpsm.read(reader); - DNAParticle::WriteDPSM(dpsm, out); - } else if (classStr == DNADGRP::DGRP::DNAType()) { - DNADGRP::DGRP dgrp; - dgrp.read(reader); - dgrp.validateDeps(); - DNADGRP::WriteDGRP(dgrp, out); - } else if (classStr == DNAFont::FONT::DNAType()) { - DNAFont::FONT font; - font.read(reader); - DNAFont::WriteFONT(font, out); - } else if (classStr == DNAMP1::CTweakPlayerRes::DNAType()) { - DNAMP1::CTweakPlayerRes playerRes; - playerRes.read(reader); - WriteTweak(playerRes, out); - } else if (classStr == DNAMP1::CTweakPlayerRes::DNAType()) { - DNAMP1::CTweakPlayerRes playerRes; - playerRes.read(reader); - WriteTweak(playerRes, out); - } else if (classStr == DNAMP1::CTweakGunRes::DNAType()) { - DNAMP1::CTweakGunRes gunRes; - gunRes.read(reader); - WriteTweak(gunRes, out); - } else if (classStr == DNAMP1::CTweakSlideShow::DNAType()) { - DNAMP1::CTweakSlideShow slideShow; - slideShow.read(reader); - WriteTweak(slideShow, out); - } else if (classStr == DNAMP1::CTweakPlayer::DNAType()) { - DNAMP1::CTweakPlayer player; - player.read(reader); - WriteTweak(player, out); - } else if (classStr == DNAMP1::CTweakCameraBob::DNAType()) { - DNAMP1::CTweakCameraBob cBob; - cBob.read(reader); - WriteTweak(cBob, out); - } else if (classStr == DNAMP1::CTweakGame::DNAType()) { - DNAMP1::CTweakGame cGame; - cGame.read(reader); - WriteTweak(cGame, out); - } else if (classStr == DNAMP1::CTweakAutoMapper::DNAType()) { - DNAMP1::CTweakAutoMapper autoMapper; - autoMapper.read(reader); - WriteTweak(autoMapper, out); - } else if (classStr == DNAMP1::CTweakTargeting::DNAType()) { - DNAMP1::CTweakTargeting targeting; - targeting.read(reader); - WriteTweak(targeting, out); - } else if (classStr == DNAMP1::CTweakTargeting::DNAType()) { - DNAMP1::CTweakTargeting targeting; - targeting.read(reader); - WriteTweak(targeting, out); - } else if (classStr == DNAMP1::CTweakGui::DNAType()) { - DNAMP1::CTweakGui gui; - gui.read(reader); - WriteTweak(gui, out); - } else if (classStr == DNAMP1::CTweakPlayerControl::DNAType()) { - DNAMP1::CTweakPlayerControl pc; - pc.read(reader); - WriteTweak(pc, out); - } else if (classStr == DNAMP1::CTweakBall::DNAType()) { - DNAMP1::CTweakBall ball; - ball.read(reader); - WriteTweak(ball, out); - } else if (classStr == DNAMP1::CTweakParticle::DNAType()) { - DNAMP1::CTweakParticle part; - part.read(reader); - WriteTweak(part, out); - } else if (classStr == DNAMP1::CTweakGuiColors::DNAType()) { - DNAMP1::CTweakGuiColors gColors; - gColors.read(reader); - WriteTweak(gColors, out); - } else if (classStr == DNAMP1::CTweakPlayerGun::DNAType()) { - DNAMP1::CTweakPlayerGun pGun; - pGun.read(reader); - WriteTweak(pGun, out); - } else if (classStr == DNAMP1::CTweakPlayerControl::DNAType()) { - DNAMP1::CTweakPlayerControl pControl; - pControl.read(reader); - WriteTweak(pControl, out); - } else if (classStr == DNAMP1::MazeSeeds::DNAType()) { - DNAMP1::MazeSeeds mSeeds; - mSeeds.read(reader); - WriteTweak(mSeeds, out); - } else if (classStr == DNAMP1::SnowForces::DNAType()) { - DNAMP1::SnowForces sForces; - sForces.read(reader); - WriteTweak(sForces, out); - } else if (classStr == DNAMP1::HINT::DNAType()) { - DNAMP1::HINT::Cook(in, out); - } else if (classStr == DNAMP1::EVNT::DNAType()) { - DNAMP1::EVNT::Cook(in, out); - } else if (classStr == "ATBL") { - DNAAudio::ATBL::Cook(in, out); - } else if (classStr == DNAMP1::AFSM::DNAType()) { - DNAMP1::AFSM::Cook(in, out); - } else if (classStr == "MP1TextureCache") { - TextureCache::Cook(in, out); - } - } - progress("Done"); - } - - void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) override { - athena::io::YAMLDocReader reader; - if (reader.parse(&fin)) { - std::string classStr = reader.readString("DNAType"sv); - if (classStr.empty()) - return; - - if (classStr == DNAMP1::STRG::DNAType()) { - DNAMP1::STRG strg; - strg.read(reader); - strg.gatherDependencies(pathsOut); - } - if (classStr == DNAMP1::SCAN::DNAType()) { - DNAMP1::SCAN scan; - scan.read(reader); - scan.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::GPSM::DNAType()) { - DNAParticle::GPSM gpsm; - gpsm.read(reader); - gpsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::SWSH::DNAType()) { - DNAParticle::SWSH swsh; - swsh.read(reader); - swsh.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::ELSM::DNAType()) { - DNAParticle::ELSM elsm; - elsm.read(reader); - elsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::WPSM::DNAType()) { - DNAParticle::WPSM wpsm; - wpsm.read(reader); - wpsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::CRSM::DNAType()) { - DNAParticle::CRSM crsm; - crsm.read(reader); - crsm.gatherDependencies(pathsOut); - } else if (classStr == DNAParticle::DPSM::DNAType()) { - DNAParticle::DPSM dpsm; - dpsm.read(reader); - dpsm.gatherDependencies(pathsOut); - } else if (classStr == DNAFont::FONT::DNAType()) { - DNAFont::FONT font; - font.read(reader); - font.gatherDependencies(pathsOut); - } else if (classStr == DNAMP1::EVNT::DNAType()) { - DNAMP1::EVNT evnt; - evnt.read(reader); - evnt.gatherDependencies(pathsOut); - } - } - } - - void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx) override { - athena::io::YAMLDocReader reader; - if (reader.parse(&fin)) { - std::string classStr = reader.readString("DNAType"); - if (classStr == DNAMP1::ANCS::DNAType()) { - DNAMP1::ANCS ancs; - ancs.read(reader); - ancs.gatherDependencies(pathsOut, charIdx); - } - } - } - - void buildWorldPakList(const hecl::ProjectPath& worldPath, const hecl::ProjectPath& worldPathCooked, - hecl::blender::Token& btok, athena::io::FileWriter& w, - std::vector& listOut, atUint64& resTableOffset, - std::unordered_map>& mlvlData) override { - DNAMP1::MLVL mlvl; - { - athena::io::FileReader r(worldPathCooked.getAbsolutePath()); - if (r.hasError()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to open world {}"), worldPathCooked.getRelativePath()); - mlvl.read(r); - } - - size_t count = 5; - for (const auto& area : mlvl.areas) { - auto lazyIt = area.lazyDeps.cbegin(); - auto it = area.deps.cbegin(); - while (it != area.deps.cend()) { - if (it->id != lazyIt->id) - ++count; - ++lazyIt; - ++it; - } - } - listOut.reserve(count); - - metaforce::SObjectTag worldTag = tagFromPath(worldPath.getWithExtension(".*", true)); - - w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005); - w.writeUint32Big(0); - - w.writeUint32Big(1); - DNAMP1::PAK::NameEntry nameEnt; - hecl::ProjectPath parentDir = worldPath.getParentPath(); - nameEnt.type = worldTag.type; - nameEnt.id = worldTag.id.Value(); - nameEnt.nameLen = atUint32(parentDir.getLastComponent().size()); - nameEnt.name = parentDir.getLastComponent(); - nameEnt.write(w); - - std::unordered_set addedTags; - for (auto& area : mlvl.areas) { - metaforce::SObjectTag areaTag(FOURCC('MREA'), area.areaMREAId.toUint64()); - - bool dupeRes = false; - if (hecl::ProjectPath areaDir = pathFromTag(areaTag).getParentPath()) - dupeRes = hecl::ProjectPath(areaDir, "!duperes").isFile(); - - metaforce::SObjectTag nameTag(FOURCC('STRG'), area.areaNameId.toUint64()); - if (nameTag) - listOut.push_back(nameTag); - for (const auto& dep : area.deps) { - metaforce::CAssetId newId = dep.id.toUint64(); - if (dupeRes || addedTags.find(newId) == addedTags.end()) { - listOut.emplace_back(dep.type, newId); - addedTags.insert(newId); - } - } - if (areaTag) - listOut.push_back(areaTag); - - std::vector strippedDeps; - strippedDeps.reserve(area.deps.size()); - std::vector strippedDepLayers; - strippedDepLayers.reserve(area.depLayers.size()); - auto lazyIt = area.lazyDeps.cbegin(); - auto it = area.deps.cbegin(); - auto layerIt = area.depLayers.cbegin(); - while (it != area.deps.cend()) { - while (layerIt != area.depLayers.cend() && it - area.deps.cbegin() == *layerIt) { - strippedDepLayers.push_back(atUint32(strippedDeps.size())); - ++layerIt; - } - if (it->id != lazyIt->id) - strippedDeps.push_back(*it); - ++lazyIt; - ++it; - } - - area.lazyDepCount = 0; - area.lazyDeps.clear(); - area.depCount = strippedDeps.size(); - area.deps = std::move(strippedDeps); - area.depLayerCount = strippedDepLayers.size(); - area.depLayers = std::move(strippedDepLayers); - } - - metaforce::SObjectTag nameTag(FOURCC('STRG'), mlvl.worldNameId.toUint64()); - if (nameTag) - listOut.push_back(nameTag); - - metaforce::SObjectTag savwTag(FOURCC('SAVW'), mlvl.saveWorldId.toUint64()); - if (savwTag) { - if (hecl::ProjectPath savwPath = pathFromTag(savwTag)) - m_project.cookPath(savwPath, {}, false, true); - listOut.push_back(savwTag); - } - - metaforce::SObjectTag mapTag(FOURCC('MAPW'), mlvl.worldMap.toUint64()); - if (mapTag) { - if (hecl::ProjectPath mapPath = pathFromTag(mapTag)) { - m_project.cookPath(mapPath, {}, false, true); - if (hecl::ProjectPath mapCookedPath = getCookedPath(mapPath, true)) { - athena::io::FileReader r(mapCookedPath.getAbsolutePath()); - if (r.hasError()) - Log.report(logvisor::Fatal, FMT_STRING("Unable to open {}"), mapCookedPath.getRelativePath()); - - if (r.readUint32Big() != 0xDEADF00D) - Log.report(logvisor::Fatal, FMT_STRING("Corrupt MAPW {}"), mapCookedPath.getRelativePath()); - r.readUint32Big(); - atUint32 mapaCount = r.readUint32Big(); - for (atUint32 i = 0; i < mapaCount; ++i) { - UniqueID32 id; - id.read(r); - listOut.emplace_back(FOURCC('MAPA'), id.toUint64()); - } - } - } - listOut.push_back(mapTag); - } - - metaforce::SObjectTag skyboxTag(FOURCC('CMDL'), mlvl.worldSkyboxId.toUint64()); - if (skyboxTag) { - listOut.push_back(skyboxTag); - hecl::ProjectPath skyboxPath = pathFromTag(skyboxTag); - if (btok.getBlenderConnection().openBlend(skyboxPath)) { - auto data = btok.getBlenderConnection().beginData(); - std::vector textures = data.getTextures(); - for (const auto& tex : textures) { - metaforce::SObjectTag texTag = tagFromPath(tex); - if (!texTag) - Log.report(logvisor::Fatal, FMT_STRING("Unable to resolve {}"), tex.getRelativePath()); - listOut.push_back(texTag); - } - } - } - - listOut.push_back(worldTag); - - w.writeUint32Big(atUint32(listOut.size())); - resTableOffset = w.position(); - for (const auto& item : listOut) { - DNAMP1::PAK::Entry ent; - ent.compressed = 0; - ent.type = item.type; - ent.id = item.id.Value(); - ent.size = 0; - ent.offset = 0; - ent.write(w); - } - - { - std::vector& mlvlOut = mlvlData[worldTag.id]; - size_t mlvlSize = 0; - mlvl.binarySize(mlvlSize); - mlvlOut.resize(mlvlSize); - athena::io::MemoryWriter mw(&mlvlOut[0], mlvlSize); - mlvl.write(mw); - } - } - - void buildPakList(hecl::blender::Token& btok, athena::io::FileWriter& w, - const std::vector& list, - const std::vector>& nameList, - atUint64& resTableOffset) override { - w.writeUint32Big(m_pc ? 0x80030005 : 0x00030005); - w.writeUint32Big(0); - - w.writeUint32Big(atUint32(nameList.size())); - for (const auto& item : nameList) { - DNAMP1::PAK::NameEntry nameEnt; - nameEnt.type = item.first.type; - nameEnt.id = item.first.id.Value(); - nameEnt.nameLen = atUint32(item.second.size()); - nameEnt.name = item.second; - nameEnt.write(w); - } - - w.writeUint32Big(atUint32(list.size())); - resTableOffset = w.position(); - for (const auto& item : list) { - DNAMP1::PAK::Entry ent; - ent.compressed = 0; - ent.type = item.type; - ent.id = item.id.Value(); - ent.size = 0; - ent.offset = 0; - ent.write(w); - } - } - - void writePakFileIndex(athena::io::FileWriter& w, const std::vector& tags, - const std::vector>& index, atUint64 resTableOffset) override { - w.seek(resTableOffset, athena::SeekOrigin::Begin); - - auto it = tags.begin(); - for (const auto& item : index) { - const metaforce::SObjectTag& tag = *it++; - DNAMP1::PAK::Entry ent; - ent.compressed = atUint32(std::get<2>(item)); - ent.type = tag.type; - ent.id = tag.id.Value(); - ent.size = atUint32(std::get<1>(item)); - ent.offset = atUint32(std::get<0>(item)); - ent.write(w); - } - } - - std::pair, size_t> compressPakData(const metaforce::SObjectTag& tag, const uint8_t* data, - size_t len) override { - bool doCompress = false; - switch (tag.type.toUint32()) { - case SBIG('TXTR'): - case SBIG('CMDL'): - case SBIG('CSKR'): - case SBIG('ANCS'): - case SBIG('ANIM'): - case SBIG('FONT'): - doCompress = true; - break; - case SBIG('PART'): - case SBIG('ELSC'): - case SBIG('SWHC'): - case SBIG('WPSC'): - case SBIG('DPSC'): - case SBIG('CRSC'): - doCompress = len >= 0x400; - break; - default: - break; - } - if (!doCompress) - return {}; - - uLong destLen = compressBound(len); - std::pair, size_t> ret; - ret.first.reset(new uint8_t[destLen]); - compress2(ret.first.get(), &destLen, data, len, Z_BEST_COMPRESSION); - ret.second = destLen; - return ret; - }; - - void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP1::AGSC::Cook(in, out); - progress("Done"); - } - - void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP1::CSNG::Cook(in, out); - progress("Done"); - } - - void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapArea mapa = ds.compileMapArea(); - ds.close(); - DNAMP1::MAPA::Cook(mapa, out); - progress("Done"); - } - - void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapUniverse mapu = ds.compileMapUniverse(); - ds.close(); - DNAMAPU::MAPU::Cook(mapu, out); - progress("Done"); - } -}; - -hecl::Database::DataSpecEntry SpecEntMP1 = { - "MP1"sv, "Data specification for original Metroid Prime engine"sv, ".pak"sv, - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr { - return std::make_unique(&SpecEntMP1, project, false); - }}; - -hecl::Database::DataSpecEntry SpecEntMP1PC = { - "MP1-PC"sv, "Data specification for PC-optimized Metroid Prime engine"sv, ".upak"sv, - [](hecl::Database::Project& project, - hecl::Database::DataSpecTool tool) -> std::unique_ptr { - if (tool != hecl::Database::DataSpecTool::Extract) - return std::make_unique(&SpecEntMP1PC, project, true); - return {}; - }}; - -hecl::Database::DataSpecEntry SpecEntMP1ORIG = { - "MP1-ORIG"sv, "Data specification for unmodified Metroid Prime resources"sv, {}, {}}; -} // namespace DataSpec diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp deleted file mode 100644 index 94438362c..000000000 --- a/DataSpec/SpecMP2.cpp +++ /dev/null @@ -1,430 +0,0 @@ -#include - -#include "SpecBase.hpp" -#include "DNAMP2/DNAMP2.hpp" - -#include "DNAMP2/MLVL.hpp" -#include "DNAMP2/STRG.hpp" -#include "DNAMP2/AGSC.hpp" -#include "DNAMP2/PATH.hpp" -#include "DNAMP2/MAPA.hpp" -#include "DNAMP1/CSNG.hpp" -#include "DNACommon/MAPU.hpp" -#include "DNACommon/PATH.hpp" -#include "DNACommon/TXTR.hpp" -#include "DNACommon/MetaforceVersionInfo.hpp" - -#include "hecl/ClientProcess.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/MultiProgressPrinter.hpp" - -#include "Runtime/RetroTypes.hpp" -#include "nod/nod.hpp" - -namespace DataSpec { - -using namespace std::literals; - -static logvisor::Module Log("DataSpec::SpecMP2"); -extern hecl::Database::DataSpecEntry SpecEntMP2; -extern hecl::Database::DataSpecEntry SpecEntMP2ORIG; - -struct TextureCache { - static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, - const hecl::ProjectPath& pakPath) { - hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - texturePath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath()); - } - - Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)...")); - std::unordered_map metaMap; - - pakRouter.enumerateResources([&](const DNAMP2::PAK::Entry* ent) { - if (ent->type == FOURCC('TXTR') && metaMap.find(ent->id) == metaMap.end()) { - PAKEntryReadStream rs = pakRouter.beginReadStreamForId(ent->id); - metaMap[ent->id] = TXTR::GetMetaData(rs); - } - return true; - }); - - athena::io::YAMLDocWriter yamlW("MP2TextureCache"); - for (const auto& pair : metaMap) { - hecl::ProjectPath path = pakRouter.getWorking(pair.first); - auto rec = yamlW.enterSubRecord(path.getRelativePath()); - pair.second.write(yamlW); - } - - athena::io::FileWriter fileW(texturePath.getAbsolutePath()); - yamlW.finish(&fileW); - Log.report(logvisor::Level::Info, FMT_STRING("Done...")); - } - - static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::Database::Project& project = inPath.getProject(); - athena::io::YAMLDocReader r; - athena::io::FileReader fr(inPath.getAbsolutePath()); - if (!fr.isOpen() || !r.parse(&fr)) - return; - - std::vector> metaPairs; - metaPairs.reserve(r.getRootNode()->m_mapChildren.size()); - for (const auto& node : r.getRootNode()->m_mapChildren) { - hecl::ProjectPath projectPath(project, node.first); - auto rec = r.enterSubRecord(node.first.c_str()); - TXTR::Meta meta; - meta.read(r); - metaPairs.emplace_back(projectPath.parsedHash32(), meta); - } - - std::sort(metaPairs.begin(), metaPairs.end(), - [](const auto& a, const auto& b) -> bool { return a.first < b.first; }); - - athena::io::FileWriter w(outPath.getAbsolutePath()); - w.writeUint32Big(metaPairs.size()); - for (const auto& pair : metaPairs) { - pair.first.write(w); - pair.second.write(w); - } - } -}; - -struct SpecMP2 : SpecBase { - bool checkStandaloneID(const char* id) const override { - if (!memcmp(id, "G2M", 3)) - return true; - return false; - } - - std::vector m_nonPaks; - std::vector m_paks; - std::map m_orderedPaks; - - hecl::ProjectPath m_workPath; - hecl::ProjectPath m_cookPath; - PAKRouter m_pakRouter; - - SpecMP2(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) - : SpecBase(specEntry, project, pc) - , m_workPath(project.getProjectWorkingPath(), "MP2") - , m_cookPath(project.getProjectCookedPath(SpecEntMP2), "MP2") - , m_pakRouter(*this, m_workPath, m_cookPath) { - m_game = EGame::MetroidPrime2; - SpecBase::setThreadProject(); - } - - void buildPaks(nod::Node& root, const std::vector& args, ExtractReport& rep) { - m_nonPaks.clear(); - m_paks.clear(); - for (const nod::Node& child : root) { - bool isPak = false; - auto name = child.getName(); - std::string lowerName(name); - hecl::ToLower(lowerName); - if (name.size() > 4) { - std::string::iterator extit = lowerName.end() - 4; - if (std::string(extit, lowerName.end()) == ".pak") { - /* This is a pak */ - isPak = true; - std::string lowerBase(lowerName.begin(), extit); - - /* Needs filter */ - bool good = true; - if (args.size()) { - good = false; - if (!lowerName.compare(0, 7, "metroid")) { - char idxChar = lowerName[7]; - for (const std::string& arg : args) { - if (arg.size() == 1 && iswdigit(arg[0])) - if (arg[0] == idxChar) - good = true; - } - } else - good = true; - - if (!good) { - for (const std::string& arg : args) { - std::string lowerArg(arg); - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, lowerBase.size(), lowerBase)) - good = true; - } - } - } - - m_paks.emplace_back(child, good); - } - } - - if (!isPak) - m_nonPaks.push_back(&child); - } - - /* Sort PAKs alphabetically */ - m_orderedPaks.clear(); - for (DNAMP2::PAKBridge& dpak : m_paks) - m_orderedPaks[std::string(dpak.getName())] = &dpak; - - /* Assemble extract report */ - for (const auto& item : m_orderedPaks) { - if (!item.second->m_doExtract) { - continue; - } - - ExtractReport& childRep = rep.childOpts.emplace_back(); - childRep.name = item.first; - childRep.desc = item.second->getLevelString(); - } - } - - bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - nod::IPartition* partition = disc.getDataPartition(); - std::unique_ptr dolBuf = partition->getDOLBuf(); - const char* buildInfo = - static_cast(memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16)) + 19; - if (buildInfo == nullptr) { - return false; - } - - m_version = std::string(buildInfo); - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP2"; - rep.desc = "Metroid Prime 2 " + regstr; - rep.desc += " (" + m_version + ")"; - - /* Iterate PAKs and build level options */ - nod::Node& root = partition->getFSTRoot(); - buildPaks(root, args, rep); - - return true; - } - - bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - std::vector mp2args; - bool doExtract = false; - if (!args.empty()) { - /* Needs filter */ - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 3, "mp2")) { - doExtract = true; - mp2args.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - mp2args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - } else - doExtract = true; - - if (!doExtract) - return false; - - nod::IPartition* partition = disc.getDataPartition(); - nod::Node& root = partition->getFSTRoot(); - nod::Node::DirectoryIterator dolIt = root.find("rs5mp2_p.dol"); - if (dolIt == root.end()) { - dolIt = root.find("rs5mp2jpn_p.dol"); - if (dolIt == root.end()) - return false; - } - - std::unique_ptr dolBuf = dolIt->getBuf(); - const char* buildInfo = static_cast(memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16)) + 19; - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP2"; - rep.desc = "Metroid Prime 2 " + regstr; - if (buildInfo != nullptr) { - m_version = std::string(buildInfo); - rep.desc += " (" + m_version + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator mp2It = root.find("MP2"); - if (mp2It == root.end()) { - mp2It = root.find("MP2JPN"); - if (mp2It == root.end()) - return false; - } - buildPaks(*mp2It, mp2args, rep); - - return true; - } - - bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override { - nod::ExtractionContext ctx = {force, nullptr}; - - m_workPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_pakRouter.build(m_paks, - [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - hecl::ProjectPath mp2OutPath(outPath, "files/MP2"); - mp2OutPath.makeDirChain(true); - - progress.startNewLine(); - progress.print("MP2 Root", "", 0.0); - int prog = 0; - ctx.progressCB = [&prog, &progress](std::string_view name, float) { - progress.print("MP2 Root", name, prog); - }; - for (const nod::Node* node : m_nonPaks) { - node->extractToDirectory(mp2OutPath.getAbsolutePath(), ctx); - prog++; - } - progress.print("MP2 Root", "", 1.0); - - hecl::ClientProcess process; - progress.startNewLine(); - for (std::pair& pair : m_orderedPaks) { - DNAMP2::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - auto pakName = std::string(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - int threadIdx = hecl::ClientProcess::GetThreadWorkerIdx(); - m_pakRouter.extractResources(pak, force, btok, - [&progress, &pakName, threadIdx](const char* substr, float factor) { - progress.print(pakName, substr, factor, threadIdx); - }); - }); - } - - process.waitUntilComplete(); - - /* Generate Texture Cache containing meta data for every texture file */ - hecl::ProjectPath noAramPath(m_project.getProjectWorkingPath(), "MP2/URDE"); - TextureCache::Generate(m_pakRouter, m_project, noAramPath); - - /* Write version data */ - hecl::ProjectPath versionPath = hecl::ProjectPath(m_project.getProjectWorkingPath(), "out/files/MP2"); - WriteVersionInfo(m_project, versionPath); - return true; - } - - const hecl::Database::DataSpecEntry& getOriginalSpec() const override { return SpecEntMP2; } - - const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const override { return SpecEntMP2ORIG; } - - hecl::ProjectPath getWorking(class UniqueID32& id) override { return m_pakRouter.getWorking(id); } - - bool checkPathPrefix(const hecl::ProjectPath& path) const override { - return path.getRelativePath().compare(0, 4, "MP2/") == 0; - } - - bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { - athena::io::YAMLDocReader reader; - yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp); - return reader.ClassTypeOperation([](std::string_view classType) { - if (classType == DNAMP2::MLVL::DNAType()) - return true; - else if (classType == DNAMP2::STRG::DNAType()) - return true; - else if (classType == "ATBL") - return true; - return false; - }); - } - - metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override { return {}; } - - void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override { - PathMesh mesh = ds.compilePathMesh(); - ds.close(); - DNAMP2::PATH::Cook(out, in, mesh, btok); - } - - void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) override {} - - void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx) override {} - - void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP2::AGSC::Cook(in, out); - progress("Done"); - } - - void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override { - DNAMP1::CSNG::Cook(in, out); - progress("Done"); - } - - void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapArea mapa = ds.compileMapArea(); - ds.close(); - DNAMP2::MAPA::Cook(mapa, out); - progress("Done"); - } - - void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapUniverse mapu = ds.compileMapUniverse(); - ds.close(); - DNAMAPU::MAPU::Cook(mapu, out); - progress("Done"); - } -}; - -hecl::Database::DataSpecEntry SpecEntMP2( - "MP2"sv, "Data specification for original Metroid Prime 2 engine"sv, ".pak"sv, - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr { - return std::make_unique(&SpecEntMP2, project, false); - }); - -hecl::Database::DataSpecEntry SpecEntMP2PC = { - "MP2-PC"sv, "Data specification for PC-optimized Metroid Prime 2 engine"sv, ".upak"sv, - [](hecl::Database::Project& project, - hecl::Database::DataSpecTool tool) -> std::unique_ptr { - if (tool != hecl::Database::DataSpecTool::Extract) - return std::make_unique(&SpecEntMP2PC, project, true); - return {}; - }}; - -hecl::Database::DataSpecEntry SpecEntMP2ORIG = { - "MP2-ORIG"sv, "Data specification for unmodified Metroid Prime 2 resources"sv, {}, {}}; - -} // namespace DataSpec diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp deleted file mode 100644 index 8b44dc857..000000000 --- a/DataSpec/SpecMP3.cpp +++ /dev/null @@ -1,577 +0,0 @@ -#include -#include - -#include "DataSpec/SpecBase.hpp" -#include "DataSpec/DNAMP3/DNAMP3.hpp" - -#include "DataSpec/DNAMP3/MLVL.hpp" -#include "DataSpec/DNAMP3/STRG.hpp" -#include "DataSpec/DNAMP3/MAPA.hpp" -#include "DataSpec/DNAMP2/STRG.hpp" -#include "DataSpec/DNACommon/TXTR.hpp" -#include "DataSpec/DNACommon/MetaforceVersionInfo.hpp" - -#include "hecl/ClientProcess.hpp" -#include "hecl/Blender/Connection.hpp" -#include "hecl/MultiProgressPrinter.hpp" - -#include "Runtime/RetroTypes.hpp" -#include "nod/nod.hpp" - -namespace DataSpec { - -using namespace std::literals; - -static logvisor::Module Log("DataSpec::SpecMP3"); -extern hecl::Database::DataSpecEntry SpecEntMP3; -extern hecl::Database::DataSpecEntry SpecEntMP3ORIG; - -struct TextureCache { - static void Generate(PAKRouter& pakRouter, hecl::Database::Project& project, - const hecl::ProjectPath& pakPath) { - hecl::ProjectPath texturePath(pakPath, "texture_cache.yaml"); - hecl::ProjectPath catalogPath(pakPath, "!catalog.yaml"); - texturePath.makeDirChain(false); - - if (const auto fp = hecl::FopenUnique(catalogPath.getAbsolutePath().data(), "a")) { - fmt::print(fp.get(), FMT_STRING("TextureCache: {}\n"), texturePath.getRelativePath()); - } - - Log.report(logvisor::Level::Info, FMT_STRING("Gathering Texture metadata (this can take up to 10 seconds)...")); - std::unordered_map metaMap; - - pakRouter.enumerateResources([&](const DNAMP3::PAK::Entry* ent) { - if (ent->type == FOURCC('TXTR') && metaMap.find(ent->id) == metaMap.end()) { - PAKEntryReadStream rs = pakRouter.beginReadStreamForId(ent->id); - metaMap[ent->id] = TXTR::GetMetaData(rs); - } - return true; - }); - - athena::io::YAMLDocWriter yamlW("MP3TextureCache"); - for (const auto& pair : metaMap) { - hecl::ProjectPath path = pakRouter.getWorking(pair.first); - auto rec = yamlW.enterSubRecord(path.getRelativePath()); - pair.second.write(yamlW); - } - - athena::io::FileWriter fileW(texturePath.getAbsolutePath()); - yamlW.finish(&fileW); - Log.report(logvisor::Level::Info, FMT_STRING("Done...")); - } - - static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) { - hecl::Database::Project& project = inPath.getProject(); - athena::io::YAMLDocReader r; - athena::io::FileReader fr(inPath.getAbsolutePath()); - if (!fr.isOpen() || !r.parse(&fr)) - return; - - std::vector> metaPairs; - metaPairs.reserve(r.getRootNode()->m_mapChildren.size()); - for (const auto& node : r.getRootNode()->m_mapChildren) { - hecl::ProjectPath projectPath(project, node.first); - auto rec = r.enterSubRecord(node.first.c_str()); - TXTR::Meta meta; - meta.read(r); - metaPairs.emplace_back(projectPath.parsedHash32(), meta); - } - - std::sort(metaPairs.begin(), metaPairs.end(), - [](const auto& a, const auto& b) -> bool { return a.first < b.first; }); - - athena::io::FileWriter w(outPath.getAbsolutePath()); - w.writeUint32Big(metaPairs.size()); - for (const auto& pair : metaPairs) { - pair.first.write(w); - pair.second.write(w); - } - } -}; - -struct SpecMP3 : SpecBase { - bool checkStandaloneID(const char* id) const override { return memcmp(id, "RM3", 3) == 0; } - - bool doMP3 = false; - std::vector m_nonPaks; - std::vector m_paks; - std::map m_orderedPaks; - - hecl::ProjectPath m_workPath; - hecl::ProjectPath m_cookPath; - hecl::ProjectPath m_outPath; - PAKRouter m_pakRouter; - - /* These are populated when extracting MPT's frontend (uses MP3's DataSpec) */ - bool doMPTFE = false; - std::vector m_feNonPaks; - std::vector m_fePaks; - std::map m_feOrderedPaks; - - hecl::ProjectPath m_feWorkPath; - hecl::ProjectPath m_feCookPath; - hecl::ProjectPath m_feOutPath; - PAKRouter m_fePakRouter; - - SpecMP3(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) - : SpecBase(specEntry, project, pc) - , m_workPath(project.getProjectWorkingPath(), "MP3") - , m_cookPath(project.getProjectCookedPath(SpecEntMP3), "MP3") - , m_pakRouter(*this, m_workPath, m_cookPath) - , m_feWorkPath(project.getProjectWorkingPath(), "fe") - , m_feCookPath(project.getProjectCookedPath(SpecEntMP3), "fe") - , m_fePakRouter(*this, m_feWorkPath, m_feCookPath) { - m_game = EGame::MetroidPrime3; - SpecBase::setThreadProject(); - } - - void buildPaks(nod::Node& root, const std::vector& args, ExtractReport& rep, bool fe) { - if (fe) { - m_feNonPaks.clear(); - m_fePaks.clear(); - } else { - m_nonPaks.clear(); - m_paks.clear(); - } - for (const nod::Node& child : root) { - bool isPak = false; - auto name = child.getName(); - std::string lowerName(name); - hecl::ToLower(lowerName); - if (name.size() > 4) { - std::string::iterator extit = lowerName.end() - 4; - if (std::string(extit, lowerName.end()) == ".pak") { - /* This is a pak */ - isPak = true; - std::string lowerBase(lowerName.begin(), extit); - - /* Needs filter */ - bool good = true; - if (args.size()) { - good = false; - if (!lowerName.compare(0, 7, "metroid")) { - char idxChar = lowerName[7]; - for (const std::string& arg : args) { - if (arg.size() == 1 && iswdigit(arg[0])) - if (arg[0] == idxChar) - good = true; - } - } else - good = true; - - if (!good) { - for (const std::string& arg : args) { - std::string lowerArg(arg); - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, lowerBase.size(), lowerBase)) - good = true; - } - } - } - - if (fe) - m_fePaks.emplace_back(child, good); - else - m_paks.emplace_back(child, good); - } - } - - if (!isPak) { - if (fe) - m_feNonPaks.push_back(&child); - else - m_nonPaks.push_back(&child); - } - } - - /* Sort PAKs alphabetically */ - if (fe) { - m_feOrderedPaks.clear(); - for (DNAMP3::PAKBridge& dpak : m_fePaks) - m_feOrderedPaks[std::string(dpak.getName())] = &dpak; - } else { - m_orderedPaks.clear(); - for (DNAMP3::PAKBridge& dpak : m_paks) - m_orderedPaks[std::string(dpak.getName())] = &dpak; - } - - /* Assemble extract report */ - for (const auto& item : fe ? m_feOrderedPaks : m_orderedPaks) { - if (!item.second->m_doExtract) - continue; - - ExtractReport& childRep = rep.childOpts.emplace_back(); - childRep.name = item.first; - if (item.first == "Worlds.pak") - continue; - else if (item.first == "Metroid6.pak") { - /* Phaaze doesn't have a world name D: */ - childRep.desc = "Phaaze"; - continue; - } else if (item.first == "Metroid8.pak") { - /* Space world is misnamed */ - childRep.desc = "Space"; - continue; - } - childRep.desc = item.second->getLevelString(); - } - } - - bool checkFromStandaloneDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - doMP3 = true; - nod::IPartition* partition = disc.getDataPartition(); - std::unique_ptr dolBuf = partition->getDOLBuf(); - const char* buildInfo = - static_cast(memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16)) + 19; - if (buildInfo == nullptr) { - return false; - } - - /* We don't want no stinking demo dammit */ - if (strcmp(buildInfo, "Build v3.068 3/2/2006 14:55:13") == 0) { - return false; - } - - m_version = std::string(buildInfo); - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP3"; - rep.desc = "Metroid Prime 3 " + regstr; - rep.desc += " (" + m_version + ")"; - - /* Iterate PAKs and build level options */ - nod::Node& root = partition->getFSTRoot(); - buildPaks(root, args, rep, false); - - return true; - } - - bool checkFromTrilogyDisc(nod::DiscBase& disc, const std::string& regstr, - const std::vector& args, std::vector& reps) override { - std::vector mp3args; - std::vector feargs; - if (args.size()) { - /* Needs filter */ - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 3, "mp3")) { - doMP3 = true; - mp3args.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - mp3args.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - - for (const std::string& arg : args) { - std::string lowerArg = arg; - hecl::ToLower(lowerArg); - if (!lowerArg.compare(0, 2, "fe")) { - doMPTFE = true; - feargs.reserve(args.size()); - size_t slashPos = arg.find('/'); - if (slashPos == std::string::npos) - slashPos = arg.find('\\'); - if (slashPos != std::string::npos) - feargs.emplace_back(std::string(arg.begin() + slashPos + 1, arg.end())); - } - } - } else { - doMP3 = true; - doMPTFE = true; - } - - if (!doMP3 && !doMPTFE) - return false; - - nod::IPartition* partition = disc.getDataPartition(); - nod::Node& root = partition->getFSTRoot(); - - /* MP3 extract */ - while (doMP3) { - nod::Node::DirectoryIterator dolIt = root.find("rs5mp3_p.dol"); - if (dolIt == root.end()) { - doMP3 = false; - break; - } - - std::unique_ptr dolBuf = dolIt->getBuf(); - const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19; - - if (!buildInfo) { - doMP3 = false; - break; - } - - /* We don't want no stinking demo dammit */ - if (!strcmp(buildInfo, "Build v3.068 3/2/2006 14:55:13")) { - doMP3 = false; - break; - } - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "MP3"; - rep.desc = "Metroid Prime 3 " + regstr; - - m_version = std::string(buildInfo); - rep.desc += " (" + m_version + ")"; - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator mp3It = root.find("MP3"); - if (mp3It == root.end()) { - doMP3 = false; - break; - } - buildPaks(*mp3It, mp3args, rep, false); - break; - } - - /* MPT Frontend extract */ - while (doMPTFE) { - nod::Node::DirectoryIterator dolIt = root.find("rs5fe_p.dol"); - if (dolIt == root.end()) { - doMPTFE = false; - break; - } - - std::unique_ptr dolBuf = dolIt->getBuf(); - const char* buildInfo = (char*)memmem(dolBuf.get(), dolIt->size(), "MetroidBuildInfo", 16) + 19; - - /* Root Report */ - ExtractReport& rep = reps.emplace_back(); - rep.name = "fe"; - rep.desc = "Metroid Prime Trilogy Frontend " + regstr; - if (buildInfo) { - std::string buildStr(buildInfo); - rep.desc += " (" + buildStr + ")"; - } - - /* Iterate PAKs and build level options */ - nod::Node::DirectoryIterator feIt = root.find("fe"); - if (feIt == root.end()) { - doMPTFE = false; - break; - } - buildPaks(*feIt, feargs, rep, true); - break; - } - - return doMP3 || doMPTFE; - } - - bool extractFromDisc(nod::DiscBase& disc, bool force, const hecl::MultiProgressPrinter& progress) override { - std::string currentTarget; - size_t nodeCount = 0; - int prog = 0; - nod::ExtractionContext ctx = {force, [&](std::string_view name, float) { - progress.print(currentTarget, name, prog / (float)nodeCount); - }}; - if (doMP3) { - m_workPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_pakRouter.build(m_paks, - [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - progress.startNewLine(); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - m_outPath = {outPath, "files/MP3"}; - m_outPath.makeDirChain(true); - - currentTarget = "MP3 Root"; - progress.print(currentTarget.c_str(), "", 0.0); - prog = 0; - - nodeCount = m_nonPaks.size(); - // TODO: Make this more granular - for (const nod::Node* node : m_nonPaks) { - node->extractToDirectory(m_outPath.getAbsolutePath(), ctx); - prog++; - } - ctx.progressCB = nullptr; - - progress.print(currentTarget.c_str(), "", 1.0); - progress.startNewLine(); - - hecl::ClientProcess process; - for (std::pair& pair : m_orderedPaks) { - DNAMP3::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - auto pakName = std::string(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - m_pakRouter.extractResources(pak, force, btok, - [&progress, &pakName](const char* substr, float factor) { - progress.print(pakName, substr, factor); - }); - }); - } - - process.waitUntilComplete(); - } - - if (doMPTFE) { - m_feWorkPath.makeDir(); - - progress.startNewLine(); - progress.print("Indexing PAKs", "", 0.0); - m_fePakRouter.build( - m_fePaks, [&progress](float factor) { progress.print("Indexing PAKs", "", factor); }); - progress.print("Indexing PAKs", "", 1.0); - progress.startNewLine(); - - hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), "out"); - outPath.makeDir(); - disc.getDataPartition()->extractSysFiles(outPath.getAbsolutePath(), ctx); - m_feOutPath = {outPath, "files/fe"}; - m_feOutPath.makeDirChain(true); - - currentTarget = "fe Root"; - progress.print(currentTarget.c_str(), "", 0.0); - prog = 0; - nodeCount = m_feNonPaks.size(); - - // TODO: Make this more granular - for (const nod::Node* node : m_feNonPaks) { - node->extractToDirectory(m_feOutPath.getAbsolutePath(), ctx); - prog++; - } - progress.print(currentTarget.c_str(), "", 1.0); - progress.startNewLine(); - - hecl::ClientProcess process; - for (auto& pair : m_feOrderedPaks) { - DNAMP3::PAKBridge& pak = *pair.second; - if (!pak.m_doExtract) - continue; - - std::string pakName(pak.getName()); - process.addLambdaTransaction([this, &progress, &pak, pakName, force](hecl::blender::Token& btok) { - m_fePakRouter.extractResources(pak, force, btok, - [&progress, &pakName](const char* substr, float factor) { - progress.print(pakName, substr, factor); - }); - }); - } - - process.waitUntilComplete(); - } - - /* Generate Texture Cache containing meta data for every texture file */ - if (doMP3) { - hecl::ProjectPath noAramPath(m_workPath, "URDE"); - TextureCache::Generate(m_pakRouter, m_project, noAramPath); - } - if (doMPTFE) { - hecl::ProjectPath noAramPath(m_feWorkPath, "URDE"); - TextureCache::Generate(m_fePakRouter, m_project, noAramPath); - } - /* Write version data */ - if (doMP3) { - WriteVersionInfo(m_project, m_outPath); - } - if (doMPTFE) { - WriteVersionInfo(m_project, m_feOutPath); - } - return true; - } - - const hecl::Database::DataSpecEntry& getOriginalSpec() const override { return SpecEntMP3; } - - const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const override { return SpecEntMP3ORIG; } - - hecl::ProjectPath getWorking(class UniqueID64& id) override { return m_pakRouter.getWorking(id); } - - bool checkPathPrefix(const hecl::ProjectPath& path) const override { - return path.getRelativePath().compare(0, 4, "MP3/") == 0; - } - - bool validateYAMLDNAType(athena::io::IStreamReader& fp) const override { - if (athena::io::ValidateFromYAMLStream(fp)) - return true; - if (athena::io::ValidateFromYAMLStream(fp)) - return true; - if (athena::io::ValidateFromYAMLStream(fp)) - return true; - return false; - } - - metaforce::SObjectTag buildTagFromPath(const hecl::ProjectPath& path) const override { return {}; } - - void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookColMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArmature(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookPathMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin, - hecl::blender::Token& btok, FCookProgress progress) override {} - - void flattenDependenciesYAML(athena::io::IStreamReader& fin, std::vector& pathsOut) override {} - - void flattenDependenciesANCSYAML(athena::io::IStreamReader& fin, std::vector& pathsOut, - int charIdx) override {} - - void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {} - - void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress) override {} - - void cookMapArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override { - hecl::blender::MapArea mapa = ds.compileMapArea(); - ds.close(); - DNAMP3::MAPA::Cook(mapa, out); - progress("Done"); - } - - void cookMapUniverse(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, - hecl::blender::Token& btok, FCookProgress progress) override {} -}; - -hecl::Database::DataSpecEntry SpecEntMP3( - "MP3"sv, "Data specification for original Metroid Prime 3 engine"sv, ".pak"sv, - [](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> std::unique_ptr { - return std::make_unique(&SpecEntMP3, project, false); - }); - -hecl::Database::DataSpecEntry SpecEntMP3PC = { - "MP3-PC"sv, "Data specification for PC-optimized Metroid Prime 3 engine"sv, ".upak"sv, - [](hecl::Database::Project& project, - hecl::Database::DataSpecTool tool) -> std::unique_ptr { - if (tool != hecl::Database::DataSpecTool::Extract) - return std::make_unique(&SpecEntMP3PC, project, true); - return nullptr; - }}; - -hecl::Database::DataSpecEntry SpecEntMP3ORIG = { - "MP3-ORIG"sv, "Data specification for unmodified Metroid Prime 3 resources"sv, {}, {}}; - -} // namespace DataSpec diff --git a/NESEmulator/CMakeLists.txt b/NESEmulator/CMakeLists.txt index c7e17ef23..92fcfbf15 100644 --- a/NESEmulator/CMakeLists.txt +++ b/NESEmulator/CMakeLists.txt @@ -1,5 +1,5 @@ file(GLOB MAPPER_SRCS ../extern/fixNES/mapper/*.c) -add_library(NESEmulator CNESEmulator.hpp CNESEmulator.cpp CNESShader.hpp CNESShader.cpp malloc.h +add_library(NESEmulator CNESEmulator.hpp CNESEmulator.cpp malloc.h apu.c ../extern/fixNES/audio_fds.c ../extern/fixNES/audio_mmc5.c ../extern/fixNES/audio_vrc6.c ../extern/fixNES/audio_vrc7.c ../extern/fixNES/audio_n163.c ../extern/fixNES/audio_s5b.c ../extern/fixNES/cpu.c ppu.c ../extern/fixNES/mem.c ../extern/fixNES/input.c ../extern/fixNES/mapper.c @@ -10,8 +10,8 @@ target_include_directories(NESEmulator PRIVATE ${CMAKE_SOURCE_DIR}/extern PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_compile_definitions(NESEmulator PRIVATE COL_32BIT=1 COL_TEX_BSWAP=1) -target_link_libraries(NESEmulator boo hecl-full RuntimeCommon ${HECL_APPLICATION_REPS_TARGETS_LIST}) +target_link_libraries(NESEmulator RuntimeCommon) if (NOT MSVC) target_compile_options(NESEmulator PRIVATE -Wno-implicit-fallthrough -Wno-format -Wno-pointer-compare -Wno-memset-elt-size) -endif () \ No newline at end of file +endif () diff --git a/NESEmulator/CNESEmulator.cpp b/NESEmulator/CNESEmulator.cpp index cb84aee4f..f28ac81ab 100644 --- a/NESEmulator/CNESEmulator.cpp +++ b/NESEmulator/CNESEmulator.cpp @@ -1,5 +1,4 @@ #include "CNESEmulator.hpp" -#include "CNESShader.hpp" #include "CGameState.hpp" #include "Input/CFinalInput.hpp" #include "logvisor/logvisor.hpp" @@ -260,36 +259,36 @@ void CNESEmulator::InitializeEmulator() { // mainLoopRuns = nesPAL ? DOTS*ppuCycleTimer : DOTS*ppuCycleTimer; // mainLoopPos = mainLoopRuns; - CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - // Nearest-neighbor FTW! - m_texture = ctx.newDynamicTexture(VISIBLE_DOTS, linesToDraw, boo::TextureFormat::RGBA8, - boo::TextureClampMode::ClampToEdgeNearest); - if (ctx.platform() == boo::IGraphicsDataFactory::Platform::OpenGL) { - Vert verts[4] = { - {{-1.f, -1.f, 0.f}, {0.f, 1.f}}, - {{-1.f, 1.f, 0.f}, {0.f, 0.f}}, - {{1.f, -1.f, 0.f}, {1.f, 1.f}}, - {{1.f, 1.f, 0.f}, {1.f, 0.f}}, - }; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4); - } else { - Vert verts[4] = { - {{-1.f, 1.f, 0.f}, {0.f, 1.f}}, - {{-1.f, -1.f, 0.f}, {0.f, 0.f}}, - {{1.f, 1.f, 0.f}, {1.f, 1.f}}, - {{1.f, -1.f, 0.f}, {1.f, 0.f}}, - }; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4); - } - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - m_shadBind = CNESShader::BuildShaderDataBinding(ctx, m_vbo, m_uniBuf, m_texture); - return true; - } BooTrace); +// CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { +// // Nearest-neighbor FTW! +// m_texture = ctx.newDynamicTexture(VISIBLE_DOTS, linesToDraw, boo::TextureFormat::RGBA8, +// boo::TextureClampMode::ClampToEdgeNearest); +// if (ctx.platform() == boo::IGraphicsDataFactory::Platform::OpenGL) { +// Vert verts[4] = { +// {{-1.f, -1.f, 0.f}, {0.f, 1.f}}, +// {{-1.f, 1.f, 0.f}, {0.f, 0.f}}, +// {{1.f, -1.f, 0.f}, {1.f, 1.f}}, +// {{1.f, 1.f, 0.f}, {1.f, 0.f}}, +// }; +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4); +// } else { +// Vert verts[4] = { +// {{-1.f, 1.f, 0.f}, {0.f, 1.f}}, +// {{-1.f, -1.f, 0.f}, {0.f, 0.f}}, +// {{1.f, 1.f, 0.f}, {1.f, 1.f}}, +// {{1.f, -1.f, 0.f}, {1.f, 0.f}}, +// }; +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts, sizeof(Vert), 4); +// } +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// m_shadBind = CNESShader::BuildShaderDataBinding(ctx, m_vbo, m_uniBuf, m_texture); +// return true; +// } BooTrace); // double useFreq = 223740; double useFreq = apuGetFrequency(); - m_booVoice = CAudioSys::GetVoiceEngine()->allocateNewStereoVoice(useFreq, this); - m_booVoice->start(); + //m_booVoice = CAudioSys::GetVoiceEngine()->allocateNewStereoVoice(useFreq, this); + //m_booVoice->start(); uint32_t apuBufSz = apuGetMaxBufSize(); m_audioBufBlock.reset(new u8[apuBufSz * NUM_AUDIO_BUFFERS]); memset(m_audioBufBlock.get(), 0, apuBufSz * NUM_AUDIO_BUFFERS); @@ -302,8 +301,8 @@ void CNESEmulator::InitializeEmulator() { void CNESEmulator::DeinitializeEmulator() { // printf("\n"); emuRenderFrame = false; - m_booVoice->stop(); - m_booVoice.reset(); + //m_booVoice->stop(); + //m_booVoice.reset(); apuDeinitBufs(); if (emuNesROM != NULL) { if (!nesEmuNSFPlayback && (audioExpansion & EXP_FDS)) { @@ -346,63 +345,63 @@ CNESEmulator::~CNESEmulator() { } int CNESEmulator::audioUpdate() { - int origProcBufs = m_procBufs; - - uint8_t* data = apuGetBuf(); - if (data != NULL && m_procBufs) { - uint32_t apuBufSz = apuGetMaxBufSize(); - uint32_t remBytes = apuGetBufSize(); - while (remBytes != 0) { - size_t thisBytes = std::min(remBytes, apuBufSz - m_posInHeadBuf); - memmove(m_audioBufs[m_headBuf] + m_posInHeadBuf, data, thisBytes); - data += thisBytes; - m_posInHeadBuf += thisBytes; - if (m_posInHeadBuf == apuBufSz) { - m_posInHeadBuf = 0; - --m_procBufs; - ++m_headBuf; - if (m_headBuf == NUM_AUDIO_BUFFERS) - m_headBuf = 0; - // printf("PUSH\n"); - } - remBytes -= thisBytes; - } - } - - // if (!origProcBufs) - // printf("OVERRUN\n"); - - return origProcBufs; +// int origProcBufs = m_procBufs; +// +// uint8_t* data = apuGetBuf(); +// if (data != NULL && m_procBufs) { +// uint32_t apuBufSz = apuGetMaxBufSize(); +// uint32_t remBytes = apuGetBufSize(); +// while (remBytes != 0) { +// size_t thisBytes = std::min(remBytes, apuBufSz - m_posInHeadBuf); +// memmove(m_audioBufs[m_headBuf] + m_posInHeadBuf, data, thisBytes); +// data += thisBytes; +// m_posInHeadBuf += thisBytes; +// if (m_posInHeadBuf == apuBufSz) { +// m_posInHeadBuf = 0; +// --m_procBufs; +// ++m_headBuf; +// if (m_headBuf == NUM_AUDIO_BUFFERS) +// m_headBuf = 0; +// // printf("PUSH\n"); +// } +// remBytes -= thisBytes; +// } +// } +// +// // if (!origProcBufs) +// // printf("OVERRUN\n"); +// +// return origProcBufs; } static constexpr uint32_t AudioFrameSz = 2 * sizeof(int16_t); -size_t CNESEmulator::supplyAudio(boo::IAudioVoice& voice, size_t frames, int16_t* data) { - uint32_t remFrames = uint32_t(frames); - while (remFrames) { - if (m_posInTailBuf == apuGetMaxBufSize()) { - ++m_tailBuf; - if (m_tailBuf == NUM_AUDIO_BUFFERS) - m_tailBuf = 0; - m_posInTailBuf = 0; - ++m_procBufs; - // printf("POP\n"); - } - - if (m_procBufs == NUM_AUDIO_BUFFERS) { - memset(data, 0, remFrames * AudioFrameSz); - // printf("UNDERRUN\n"); - return frames; - } - - size_t copySz = std::min(apuGetMaxBufSize() - m_posInTailBuf, remFrames * AudioFrameSz); - memmove(data, m_audioBufs[m_tailBuf] + m_posInTailBuf, copySz); - data += copySz / sizeof(int16_t); - m_posInTailBuf += copySz; - remFrames -= copySz / AudioFrameSz; - } - return frames; -} +//size_t CNESEmulator::supplyAudio(boo::IAudioVoice& voice, size_t frames, int16_t* data) { +// uint32_t remFrames = uint32_t(frames); +// while (remFrames) { +// if (m_posInTailBuf == apuGetMaxBufSize()) { +// ++m_tailBuf; +// if (m_tailBuf == NUM_AUDIO_BUFFERS) +// m_tailBuf = 0; +// m_posInTailBuf = 0; +// ++m_procBufs; +// // printf("POP\n"); +// } +// +// if (m_procBufs == NUM_AUDIO_BUFFERS) { +// memset(data, 0, remFrames * AudioFrameSz); +// // printf("UNDERRUN\n"); +// return frames; +// } +// +// size_t copySz = std::min(apuGetMaxBufSize() - m_posInTailBuf, remFrames * AudioFrameSz); +// memmove(data, m_audioBufs[m_tailBuf] + m_posInTailBuf, copySz); +// data += copySz / sizeof(int16_t); +// m_posInTailBuf += copySz; +// remFrames -= copySz / AudioFrameSz; +// } +// return frames; +//} void CNESEmulator::NesEmuMainLoop(bool forceDraw) { // int start = GetTickCount(); @@ -413,7 +412,8 @@ void CNESEmulator::NesEmuMainLoop(bool forceDraw) { emuMainTimesSkipped++; #endif // printf("LC RENDER: %d\n", loopCount); - m_texture->load(textureImage, visibleImg); + // TODO TODO +// m_texture->load(textureImage, visibleImg); emuRenderFrame = false; break; } @@ -604,12 +604,12 @@ void CNESEmulator::ProcessUserInput(const CFinalInput& input, int) { if (GetPasswordEntryState() != EPasswordEntryState::NotPasswordScreen) { // Don't swap A/B - inValReads[BUTTON_A] = input.DA() || input.DSpecialKey(boo::ESpecialKey::Enter) || - input.DMouseButton(boo::EMouseButton::Primary); - inValReads[BUTTON_B] = input.DB() || input.DSpecialKey(boo::ESpecialKey::Esc); + inValReads[BUTTON_A] = input.DA() || input.DSpecialKey(ESpecialKey::Enter) || + input.DMouseButton(EMouseButton::Primary); + inValReads[BUTTON_B] = input.DB() || input.DSpecialKey(ESpecialKey::Esc); } else { // Prime controls (B jumps, A shoots) - inValReads[BUTTON_B] = input.DA() || input.DY() || input.DMouseButton(boo::EMouseButton::Primary); + inValReads[BUTTON_B] = input.DA() || input.DY() || input.DMouseButton(EMouseButton::Primary); inValReads[BUTTON_A] = input.DB() || input.DX() || input.DKey(' '); } @@ -617,8 +617,8 @@ void CNESEmulator::ProcessUserInput(const CFinalInput& input, int) { inValReads[BUTTON_DOWN] = input.DDPDown() || input.DLADown(); inValReads[BUTTON_LEFT] = input.DDPLeft() || input.DLALeft(); inValReads[BUTTON_RIGHT] = input.DDPRight() || input.DLARight(); - inValReads[BUTTON_SELECT] = input.DZ() || input.DKey('\t'); - inValReads[BUTTON_START] = input.DStart() || input.DSpecialKey(boo::ESpecialKey::Esc); + inValReads[BUTTON_SELECT] = input.DZ() || input.DSpecialKey(ESpecialKey::Tab); + inValReads[BUTTON_START] = input.DStart() || input.DSpecialKey(ESpecialKey::Esc); } bool CNESEmulator::CheckForGameOver(const u8* vram, u8* passwordOut) { @@ -766,14 +766,14 @@ void CNESEmulator::Draw(const zeus::CColor& mulColor, bool filtering) { if (!EmulatorInst) return; - float widthFac = NESAspect / g_Viewport.aspect; + float widthFac = NESAspect / CGraphics::GetViewportAspect(); Uniform uniform = {zeus::CMatrix4f{}, mulColor}; uniform.m_matrix[0][0] = widthFac; - m_uniBuf->load(&uniform, sizeof(Uniform)); - - CGraphics::SetShaderDataBinding(m_shadBind); - CGraphics::DrawArray(0, 4); +// m_uniBuf->load(&uniform, sizeof(Uniform)); +// +// CGraphics::SetShaderDataBinding(m_shadBind); +// CGraphics::DrawArray(0, 4); } void CNESEmulator::LoadPassword(const u8* state) { diff --git a/NESEmulator/CNESEmulator.hpp b/NESEmulator/CNESEmulator.hpp index 0dc4dd74f..32664b8ec 100644 --- a/NESEmulator/CNESEmulator.hpp +++ b/NESEmulator/CNESEmulator.hpp @@ -2,9 +2,9 @@ #include "RetroTypes.hpp" #include "zeus/CColor.hpp" -#include "boo/graphicsdev/IGraphicsDataFactory.hpp" -#include "boo/audiodev/IAudioVoice.hpp" +//#include "boo/graphicsdev/IGraphicsDataFactory.hpp" #include "zeus/CMatrix4f.hpp" +#include "Runtime/Graphics/CGraphics.hpp" namespace metaforce { struct CFinalInput; @@ -14,7 +14,7 @@ namespace MP1 { #define NUM_AUDIO_BUFFERS 4 -class CNESEmulator final : public boo::IAudioVoiceCallback { +class CNESEmulator final { public: enum class EPasswordEntryState { NotPasswordScreen, NotEntered, Entered }; @@ -34,10 +34,10 @@ private: zeus::CColor m_color; }; - boo::ObjToken m_texture; - boo::ObjToken m_uniBuf; - boo::ObjToken m_vbo; - boo::ObjToken m_shadBind; + GXTexObj m_texture; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_vbo; +// boo::ObjToken m_shadBind; std::unique_ptr m_audioBufBlock; u8* m_audioBufs[NUM_AUDIO_BUFFERS]; @@ -46,7 +46,7 @@ private: uint32_t m_procBufs = NUM_AUDIO_BUFFERS; uint32_t m_posInHeadBuf = 0; uint32_t m_posInTailBuf = 0; - boo::ObjToken m_booVoice; + //boo::ObjToken m_booVoice; // void* x4_loadBuf; // void* x8_rom; @@ -81,8 +81,8 @@ public: EPasswordEntryState GetPasswordEntryState() const { return x34_passwordEntryState; } int audioUpdate(); - void preSupplyAudio(boo::IAudioVoice& voice, double dt) {} - size_t supplyAudio(boo::IAudioVoice& voice, size_t frames, int16_t* data); + //void preSupplyAudio(boo::IAudioVoice& voice, double dt) {} + //size_t supplyAudio(boo::IAudioVoice& voice, size_t frames, int16_t* data); }; } // namespace MP1 diff --git a/NESEmulator/CNESShader.cpp b/NESEmulator/CNESShader.cpp deleted file mode 100644 index c7d57e2fb..000000000 --- a/NESEmulator/CNESShader.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "CNESShader.hpp" -#include "Graphics/CGraphics.hpp" -#include "hecl/Pipeline.hpp" - -namespace metaforce::MP1 { - -boo::ObjToken CNESShader::g_Pipeline; - -void CNESShader::Initialize() { g_Pipeline = hecl::conv->convert(Shader_CNESShader{}); } - -boo::ObjToken CNESShader::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, - boo::ObjToken vbo, - boo::ObjToken uniBuf, - boo::ObjToken tex) { - boo::ObjToken bufs[] = {uniBuf.get()}; - boo::PipelineStage stages[] = {boo::PipelineStage::Vertex}; - boo::ObjToken texs[] = {tex.get()}; - return ctx.newShaderDataBinding(g_Pipeline, vbo.get(), nullptr, nullptr, 1, bufs, stages, nullptr, nullptr, 1, texs, - nullptr, nullptr); -} - -void CNESShader::Shutdown() { g_Pipeline.reset(); } - -} // namespace metaforce::MP1 diff --git a/NESEmulator/CNESShader.hpp b/NESEmulator/CNESShader.hpp deleted file mode 100644 index 1fa513b63..000000000 --- a/NESEmulator/CNESShader.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "boo/graphicsdev/IGraphicsDataFactory.hpp" - -namespace metaforce::MP1 { - -class CNESShader { -public: - static void Initialize(); - static void Shutdown(); - - static boo::ObjToken BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, - boo::ObjToken vbo, - boo::ObjToken uniBuf, - boo::ObjToken tex); - - static boo::ObjToken g_Pipeline; -}; - -} // namespace metaforce::MP1 diff --git a/README.md b/README.md index af421c1e1..94314f74a 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,30 @@ -## Metaforce -#### Formerly known as URDE +## Metaforce [![Build Status]][actions] [![Discord Badge]][discord] -**Status:** Metroid Prime 1 In-Game (all retail GC & Wii versions) +[Build Status]: https://github.com/AxioDL/metaforce/actions/workflows/build.yml/badge.svg +[actions]: https://github.com/AxioDL/metaforce/actions +[Discord Badge]: https://dcbadge.vercel.app/api/server/AMBVFuf?style=flat +[discord]: https://discord.gg/AMBVFuf -**Official Discord Channel:** https://discord.gg/AMBVFuf +A reverse-engineered, native reimplementation of Metroid Prime. + +This project is currently in **alpha** state. +Builds are currently unavailable while the project undergoes large changes. + +Separately, a [matching decompilation](https://github.com/PrimeDecomp/prime) of Metroid Prime is currently underway. Contributions are welcome. +Progress on the decompilation benefits Metaforce with bug fixes and new implementations. ![Metaforce screenshot](assets/metaforce-screen1.png) -### Download -This project is currently in **Alpha** state, so expect bugs. -Builds available at [https://releases.axiodl.com](https://releases.axiodl.com). - ### Platform Support -* Windows 10 (64-bit, D3D11 / Vulkan) +* Windows 10+ (64-bit, D3D12 / Vulkan / OpenGL) * macOS 10.15+ (Metal) -* Linux (Vulkan) +* Linux (Vulkan / OpenGL) * Follow [this guide](https://github.com/lutris/docs/blob/master/InstallingDrivers.md) to set up Vulkan & appropriate drivers for your distro. -### Usage (GUI) +### Usage Windows: -- Open `metaforce-gui.exe` +- Open `metaforce.exe` macOS: - Open `Metaforce.app` @@ -29,26 +33,7 @@ Linux: - Ensure AppImage is marked as executable: `chmod +x Metaforce-*.AppImage` - Open `Metaforce-*.AppImage` -### CLI usage (GC versions) - -* Extract ISO: `hecl extract [path].iso -o mp1` - * `mp1` can be substituted with the directory name of your choice -* Repackage game for Metaforce: `cd mp1; hecl package` -* Run Metaforce: `metaforce mp1/out` - -### CLI usage (Wii versions) - -**IMPORTANT**: Trilogy main menu currently doesn't work, and requires the `--warp 1 0` command line arguments to get in-game. - -NFS files dumped from Metroid Prime Trilogy on Wii U VC can be used directly without converting to ISO. - -* Extract ISO or NFS: `hecl extract [path].[iso/nfs] -o mpt` - * `mpt` can be substituted with the directory name of your choice -* Repackage game for Metaforce: `cd mpt; hecl package MP1` - * The `MP1` parameter is important here. -* Run Metaforce: `metaforce mpt/out --warp 1 0` - -#### Metaforce options (non-exhaustive) +#### CLI options (non-exhaustive) * `-l`: Enable console logging * `--warp [worldid] [areaid]`: Warp to a specific world/area. Example: `--warp 2 2` @@ -75,7 +60,7 @@ NFS files dumped from Metroid Prime Trilogy on Wii U VC can be used directly wit 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 \ libudev-dev libpng-dev libncurses5-dev cmake libx11-xcb-dev python3 python-is-python3 \ - qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libclang-dev + libclang-dev libfreetype-dev libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev ``` * Optional Ubuntu 22.04+ packages (currently only needed for amuse-gui, can be ignored) ``` @@ -83,12 +68,11 @@ NFS files dumped from Metroid Prime Trilogy on Wii U VC can be used directly wit ``` * Arch Linux packages ``` - base-devel cmake ninja llvm vulkan-headers python3 qt6 clang lld alsa-lib libpulse libxrandr + base-devel cmake ninja llvm vulkan-headers python python-markupsafe clang lld alsa-lib libpulse libxrandr freetype2 ``` * Fedora packages ``` - cmake vulkan-headers ninja-build clang-devel llvm-devel libpng-devel qt6-qtbase-devel - qt6-linguist qt6-qttools-devel qt6-qtscxml-devel qt6-qtsvg-devel qt6-qt5compat-devel + cmake vulkan-headers ninja-build clang-devel llvm-devel libpng-devel ``` * It's also important that you install the developer tools and libraries ``` @@ -155,21 +139,3 @@ cmake -G Xcode ../metaforce ``` Then open `metaforce.xcodeproj` - -#### Optional Debug Models -We provide custom debug models for use to visualize certain aspects of the game such as lighting, in order to use -these models you may download them from https://axiodl.com/files/debug_models.zip and extract to `MP1/URDE` in an -existing HECL project (assuming paths are relative), then run the following command: - -```sh -hecl package MP1/URDE -``` -This will cook and package the debug models and will automatically enable rendering of lights in a debug build of Metaforce. - -### Blender Known Issues -On Windows it is known that paths >240 characters will cause blender to fail while attempting to open/create a file, causing hecl to stall. -We currently do not have a good fix for this issue, however a workaround is to place hecl near the root of your directory tree -and executing from there e.g: -`D:\HECLProjects\` -Another work around is to install a version of python that matches the one blender ships with and renaming the python directory in the blender directory to `python.bak`. -This will force blender to use the system's python if it's available and will not have the same path limitation diff --git a/README.msan.md b/README.msan.md deleted file mode 100644 index 60bce969c..000000000 --- a/README.msan.md +++ /dev/null @@ -1,57 +0,0 @@ -## Instrumenting URDE with MemorySanitizer - -*For Linux and OpenGL only.* - -To enable checking for uninitialized memory accesses with -[MemorySanitizer](https://clang.llvm.org/docs/MemorySanitizer.html), pass -`-DURDE_MSAN=On` to the CMake command line. -URDE and boo will conditionally disable certain features when MemorySanitizer -is enabled. Audio will not be processed in order to avoid the significant -CPU expense required for mixing. Disabling audio also avoids the need to -track allocations made by PulseAudio. Additionally, DBus functionality is -disabled to avoid tracking its allocations. - -MemorySanitizer ideally requires all code in the process be compiled for -instrumentation. In practice this is not easy since several system and -multimedia libraries are dynamically linked by URDE. -Two key system additions/modifications are required to successfully instrument. - -### libc++ - -The C++ runtime has numerous instances of memory allocation. The easiest way -to ensure these are instrumented is to build libc++ and libc++abi with -MemorySanitizer enabled. Follow -[these instructions](https://github.com/google/sanitizers/wiki/MemorySanitizerBootstrappingClang) -up to the "Build libc++ and libc++abi with MemorySanitizer" step. -Once built, install them onto your system. - -### Mesa - -*Tested with Radeon SI only. Might work with Intel and Nouveau as well.* - -There is not much to do with URDE in the absence of a graphics acceleration -library. Unfortunately, Mesa is a beast of a library that does not handle -MemorySanitizer instrumentation well. As an alternative, boo uses MSan's -API to contextually disable memory tracking when frequently-used OpenGL -functions are called. - -Unfortunately, the Radeon SI driver (and probably others) spin up a work -queue thread that URDE has no visibility of. Memory allocations in this -thread will generate an unmanageable quantity of reports. Mesa has a convenient -thread entry implementing a generic work queue for drivers to make use of. - -`#include ` and add the following code to the beginning of -`util_queue_thread_func` in `src/util/u_queue.c`: -```cpp -typedef void (*msan_function)(void); -msan_function func = dlsym(RTLD_NEXT, "__msan_scoped_disable_interceptor_checks"); -if (!func) - func = dlsym(RTLD_DEFAULT, "__msan_scoped_disable_interceptor_checks"); -if (func) - func(); -``` - -Graphics driver processing should now be totally silent. There will likely -still be a large quantity of reports during application launch and exit, -but once the actual URDE mainloop begins processing, reports should be mostly -limited to the game code itself. diff --git a/Runtime/Audio/CAudioGroupSet.cpp b/Runtime/Audio/CAudioGroupSet.cpp index 83ca2f65a..8041d43ab 100644 --- a/Runtime/Audio/CAudioGroupSet.cpp +++ b/Runtime/Audio/CAudioGroupSet.cpp @@ -3,19 +3,19 @@ #include namespace metaforce { - +/* amuse::AudioGroupData CAudioGroupSet::LoadData() { const auto readU32 = [](const u8* ptr) { uint32_t value; std::memcpy(&value, ptr, sizeof(value)); - return hecl::SBig(value); + return SBig(value); }; - athena::io::MemoryReader r(m_buffer.get(), INT32_MAX); - x10_baseName = r.readString(); - x20_name = r.readString(); + CMemoryInStream r(m_buffer.get(), INT32_MAX, CMemoryInStream::EOwnerShip::NotOwned); + x10_baseName = r.Get(); + x20_name = r.Get(); - u8* buf = m_buffer.get() + r.position(); + u8* buf = m_buffer.get() + r.GetReadPosition(); const uint32_t poolLen = readU32(buf); unsigned char* pool = buf + 4; buf += poolLen + 4; @@ -30,8 +30,8 @@ amuse::AudioGroupData CAudioGroupSet::LoadData() { return {proj, projLen, pool, poolLen, sdir, sdirLen, samp, sampLen, amuse::GCNDataTag{}}; } - -CAudioGroupSet::CAudioGroupSet(std::unique_ptr&& in) : m_buffer(std::move(in)), m_data(LoadData()) {} +*/ +CAudioGroupSet::CAudioGroupSet(std::unique_ptr&& in) : m_buffer(std::move(in)) {} CFactoryFnReturn FAudioGroupSetDataFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef) { diff --git a/Runtime/Audio/CAudioGroupSet.hpp b/Runtime/Audio/CAudioGroupSet.hpp index 4bbaf333e..54960fa06 100644 --- a/Runtime/Audio/CAudioGroupSet.hpp +++ b/Runtime/Audio/CAudioGroupSet.hpp @@ -5,11 +5,11 @@ #include "Runtime/CFactoryMgr.hpp" #include "Runtime/CToken.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/IObj.hpp" #include "Runtime/RetroTypes.hpp" -#include +//#include namespace metaforce { @@ -17,12 +17,12 @@ class CAudioGroupSet { std::unique_ptr m_buffer; std::string x10_baseName; std::string x20_name; - amuse::AudioGroupData m_data; - amuse::AudioGroupData LoadData(); +// amuse::AudioGroupData m_data; +// amuse::AudioGroupData LoadData(); public: explicit CAudioGroupSet(std::unique_ptr&& in); - const amuse::AudioGroupData& GetAudioGroupData() const { return m_data; } + //const amuse::AudioGroupData& GetAudioGroupData() const { return m_data; } std::string_view GetName() const { return x20_name; } }; diff --git a/Runtime/Audio/CAudioSys.cpp b/Runtime/Audio/CAudioSys.cpp index 49298644c..84f9ffefc 100644 --- a/Runtime/Audio/CAudioSys.cpp +++ b/Runtime/Audio/CAudioSys.cpp @@ -69,16 +69,12 @@ void CAudioSys::SysUnloadAudioGroupSet(std::string_view name) { bool CAudioSys::SysIsGroupSetLoaded(std::string_view name) { return FindGroupSet(name).operator bool(); } void CAudioSys::SysAddGroupIntoAmuse(std::string_view name) { - if (auto set = FindGroupSet(name)) - AddAudioGroup(set->GetAudioGroupData()); } void CAudioSys::SysRemoveGroupFromAmuse(std::string_view name) { - if (auto set = FindGroupSet(name)) - RemoveAudioGroup(set->GetAudioGroupData()); } -void CAudioSys::_UpdateVolume() { GetAmuseEngine().setVolume(s_MasterVol * s_SfxVol); } +void CAudioSys::_UpdateVolume() { } void CAudioSys::SysSetVolume(u8 volume) { s_MasterVol = volume / 127.f; diff --git a/Runtime/Audio/CAudioSys.hpp b/Runtime/Audio/CAudioSys.hpp index 31ef27484..5c3503d66 100644 --- a/Runtime/Audio/CAudioSys.hpp +++ b/Runtime/Audio/CAudioSys.hpp @@ -4,8 +4,8 @@ #include "Runtime/GCNTypes.hpp" #include "Runtime/RetroTypes.hpp" -#include -#include +//#include +//#include #include namespace metaforce { @@ -21,8 +21,6 @@ public: private: static CAudioSys* g_SharedSys; - boo::IAudioVoiceEngine* m_voiceEngine; - amuse::Engine m_engine; static void _UpdateVolume(); public: @@ -38,16 +36,11 @@ public: bool x28_important; // Can't be allocated over, regardless of priority u8 x29_prio; }; - CAudioSys(boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend, u8, u8, u8, u8, u32) - : m_voiceEngine(voiceEngine), m_engine(backend) { + CAudioSys(u8, u8, u8, u8, u32) { g_SharedSys = this; } ~CAudioSys() { g_SharedSys = nullptr; } - static void AddAudioGroup(const amuse::AudioGroupData& data) { g_SharedSys->m_engine.addAudioGroup(data); } - static void RemoveAudioGroup(const amuse::AudioGroupData& data) { g_SharedSys->m_engine.removeAudioGroup(data); } - static boo::IAudioVoiceEngine* GetVoiceEngine() { return g_SharedSys->m_voiceEngine; } - static amuse::Engine& GetAmuseEngine() { return g_SharedSys->m_engine; } static void SetSurroundMode(ESurroundModes mode) {} static TLockedToken FindGroupSet(std::string_view name); static std::string_view SysGetGroupSetName(CAssetId id); diff --git a/Runtime/Audio/CMidiManager.cpp b/Runtime/Audio/CMidiManager.cpp index 14332d621..6fb4888f5 100644 --- a/Runtime/Audio/CMidiManager.cpp +++ b/Runtime/Audio/CMidiManager.cpp @@ -1,5 +1,7 @@ #include "Runtime/Audio/CMidiManager.hpp" +#include "Runtime/Streams/CInputStream.hpp" + namespace metaforce { std::unordered_set CMidiManager::m_MidiWrappers = {}; @@ -10,14 +12,14 @@ void CMidiManager::StopAll() { } void CMidiManager::Stop(const CMidiHandle& handle, float fadeTime) { - handle->GetAudioSysHandle()->stopSong(fadeTime); - m_MidiWrappers.erase(handle); +// handle->GetAudioSysHandle()->stopSong(fadeTime); +// m_MidiWrappers.erase(handle); } std::unordered_set::iterator CMidiManager::Stop(std::unordered_set::iterator handle, float fadeTime) { - const CMidiHandle& h = *handle; - h->GetAudioSysHandle()->stopSong(fadeTime); +// const CMidiHandle& h = *handle; +// h->GetAudioSysHandle()->stopSong(fadeTime); return m_MidiWrappers.erase(handle); } @@ -27,21 +29,21 @@ CMidiHandle CMidiManager::Play(const CMidiData& data, float fadeTime, bool stopE it = Stop(it, fadeTime); CMidiHandle handle = *m_MidiWrappers.insert(std::make_shared()).first; - handle->SetAudioSysHandle( - CAudioSys::GetAmuseEngine().seqPlay(data.GetGroupId(), data.GetSetupId(), data.GetArrData())); - handle->GetAudioSysHandle()->setVolume(volume, fadeTime); - handle->SetSongId(data.GetSetupId()); +// handle->SetAudioSysHandle( +// CAudioSys::GetAmuseEngine().seqPlay(data.GetGroupId(), data.GetSetupId(), data.GetArrData())); +// handle->GetAudioSysHandle()->setVolume(volume, fadeTime); +// handle->SetSongId(data.GetSetupId()); return handle; } CMidiManager::CMidiData::CMidiData(CInputStream& in) { - in.readUint32Big(); - x0_setupId = in.readUint32Big(); - x2_groupId = in.readUint32Big(); - x4_agscId = in.readUint32Big(); - u32 length = in.readUint32Big(); + in.ReadLong(); + x0_setupId = in.ReadLong(); + x2_groupId = in.ReadLong(); + x4_agscId = in.Get(); + u32 length = in.ReadLong(); x8_arrData.reset(new u8[length]); - in.readUBytesToBuf(x8_arrData.get(), length); + in.ReadBytes(reinterpret_cast(x8_arrData.get()), length); } CFactoryFnReturn FMidiDataFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& parms, diff --git a/Runtime/Audio/CMidiManager.hpp b/Runtime/Audio/CMidiManager.hpp index 1114cb8c6..73110d0c7 100644 --- a/Runtime/Audio/CMidiManager.hpp +++ b/Runtime/Audio/CMidiManager.hpp @@ -23,14 +23,14 @@ public: }; class CMidiWrapper { - amuse::ObjToken x0_sequencer; + //amuse::ObjToken x0_sequencer; // CSfxHandle x4_handle; u16 x8_songId; bool xa_available = true; public: - amuse::ObjToken GetAudioSysHandle() const { return x0_sequencer; } - void SetAudioSysHandle(amuse::ObjToken sequencer) { x0_sequencer = std::move(sequencer); } + //amuse::ObjToken GetAudioSysHandle() const { return x0_sequencer; } + //void SetAudioSysHandle(amuse::ObjToken sequencer) { x0_sequencer = std::move(sequencer); } // const CSfxHandle& GetManagerHandle() const { return x4_handle; } // void SetMidiHandle(const CSfxHandle& handle) { x4_handle = handle; } bool IsAvailable() const { return xa_available; } diff --git a/Runtime/Audio/CSfxManager.cpp b/Runtime/Audio/CSfxManager.cpp index 8394782d4..ff41d4767 100644 --- a/Runtime/Audio/CSfxManager.cpp +++ b/Runtime/Audio/CSfxManager.cpp @@ -1,4 +1,5 @@ #include "Runtime/Audio/CSfxManager.hpp" +#include "Runtime/Streams/CInputStream.hpp" #include "Runtime/CSimplePool.hpp" @@ -6,23 +7,23 @@ namespace metaforce { static TLockedToken> mpSfxTranslationTableTok; std::vector* CSfxManager::mpSfxTranslationTable = nullptr; -static amuse::EffectReverbHiInfo s_ReverbHiQueued; -static amuse::EffectChorusInfo s_ChorusQueued; -static amuse::EffectReverbStdInfo s_ReverbStdQueued; -static amuse::EffectDelayInfo s_DelayQueued; - -static amuse::EffectReverbHi* s_ReverbHiState = nullptr; -static amuse::EffectChorus* s_ChorusState = nullptr; -static amuse::EffectReverbStd* s_ReverbStdState = nullptr; -static amuse::EffectDelay* s_DelayState = nullptr; +//static amuse::EffectReverbHiInfo s_ReverbHiQueued; +//static amuse::EffectChorusInfo s_ChorusQueued; +//static amuse::EffectReverbStdInfo s_ReverbStdQueued; +//static amuse::EffectDelayInfo s_DelayQueued; +// +//static amuse::EffectReverbHi* s_ReverbHiState = nullptr; +//static amuse::EffectChorus* s_ChorusState = nullptr; +//static amuse::EffectReverbStd* s_ReverbStdState = nullptr; +//static amuse::EffectDelay* s_DelayState = nullptr; CFactoryFnReturn FAudioTranslationTableFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, CObjectReference* selfRef) { std::unique_ptr> obj = std::make_unique>(); - u32 count = in.readUint32Big(); + u32 count = in.ReadLong(); obj->reserve(count); for (u32 i = 0; i < count; ++i) - obj->push_back(in.readUint16Big()); + obj->push_back(in.ReadShort()); return TToken>::GetIObjObjectFor(std::move(obj)); } @@ -35,7 +36,7 @@ bool CSfxManager::m_auxProcessingEnabled = false; float CSfxManager::m_reverbAmount = 1.f; CSfxManager::EAuxEffect CSfxManager::m_activeEffect = CSfxManager::EAuxEffect::None; CSfxManager::EAuxEffect CSfxManager::m_nextEffect = CSfxManager::EAuxEffect::None; -amuse::ObjToken CSfxManager::m_listener; +//amuse::ObjToken CSfxManager::m_listener; u16 CSfxManager::kMaxPriority; u16 CSfxManager::kMedPriority; @@ -53,27 +54,27 @@ bool CSfxManager::LoadTranslationTable(CSimplePool* pool, const SObjectTag* tag) } bool CSfxManager::CSfxWrapper::IsPlaying() const { - if (CBaseSfxWrapper::IsPlaying() && x1c_voiceHandle) - return x1c_voiceHandle->state() == amuse::VoiceState::Playing; +// if (CBaseSfxWrapper::IsPlaying() && x1c_voiceHandle) +// return x1c_voiceHandle->state() == amuse::VoiceState::Playing; return false; } void CSfxManager::CSfxWrapper::Play() { - x1c_voiceHandle = CAudioSys::GetAmuseEngine().fxStart(x18_sfxId, x20_vol, x22_pan); - if (x1c_voiceHandle) { - if (CSfxManager::IsAuxProcessingEnabled() && UseAcoustics()) - x1c_voiceHandle->setReverbVol(m_reverbAmount); - SetPlaying(true); - } +// x1c_voiceHandle = CAudioSys::GetAmuseEngine().fxStart(x18_sfxId, x20_vol, x22_pan); +// if (x1c_voiceHandle) { +// if (CSfxManager::IsAuxProcessingEnabled() && UseAcoustics()) +// x1c_voiceHandle->setReverbVol(m_reverbAmount); +// SetPlaying(true); +// } x24_ready = false; } void CSfxManager::CSfxWrapper::Stop() { - if (x1c_voiceHandle) { - x1c_voiceHandle->keyOff(); - SetPlaying(false); - x1c_voiceHandle.reset(); - } +// if (x1c_voiceHandle) { +// x1c_voiceHandle->keyOff(); +// SetPlaying(false); +// x1c_voiceHandle.reset(); +// } } bool CSfxManager::CSfxWrapper::Ready() { @@ -85,25 +86,25 @@ bool CSfxManager::CSfxWrapper::Ready() { u16 CSfxManager::CSfxWrapper::GetSfxId() const { return x18_sfxId; } void CSfxManager::CSfxWrapper::UpdateEmitterSilent() { - if (x1c_voiceHandle) - x1c_voiceHandle->setVolume(1.f / 127.f); +// if (x1c_voiceHandle) +// x1c_voiceHandle->setVolume(1.f / 127.f); } void CSfxManager::CSfxWrapper::UpdateEmitter() { - if (x1c_voiceHandle) - x1c_voiceHandle->setVolume(x20_vol); +// if (x1c_voiceHandle) +// x1c_voiceHandle->setVolume(x20_vol); } void CSfxManager::CSfxWrapper::SetReverb(float rev) { - if (x1c_voiceHandle && IsAuxProcessingEnabled() && UseAcoustics()) - x1c_voiceHandle->setReverbVol(rev); +// if (x1c_voiceHandle && IsAuxProcessingEnabled() && UseAcoustics()) +// x1c_voiceHandle->setReverbVol(rev); } bool CSfxManager::CSfxEmitterWrapper::IsPlaying() const { if (IsLooped()) return CBaseSfxWrapper::IsPlaying(); - if (CBaseSfxWrapper::IsPlaying() && x50_emitterHandle) - return x50_emitterHandle->getVoice()->state() == amuse::VoiceState::Playing; +// if (CBaseSfxWrapper::IsPlaying() && x50_emitterHandle) +// return x50_emitterHandle->getVoice()->state() == amuse::VoiceState::Playing; return false; } @@ -113,23 +114,23 @@ void CSfxManager::CSfxEmitterWrapper::Play() { else x1a_reverb = 0.f; - zeus::simd_floats pos(x24_parmData.x0_pos.mSimd); - zeus::simd_floats dir(x24_parmData.xc_dir.mSimd); - x50_emitterHandle = CAudioSys::GetAmuseEngine().addEmitter( - pos.data(), dir.data(), x24_parmData.x18_maxDist, x24_parmData.x1c_distComp, x24_parmData.x24_sfxId, - x24_parmData.x27_minVol, x24_parmData.x26_maxVol, (x24_parmData.x20_flags & 0x8) != 0); - - if (x50_emitterHandle) - SetPlaying(true); +// zeus::simd_floats pos(x24_parmData.x0_pos.mSimd); +// zeus::simd_floats dir(x24_parmData.xc_dir.mSimd); +// x50_emitterHandle = CAudioSys::GetAmuseEngine().addEmitter( +// pos.data(), dir.data(), x24_parmData.x18_maxDist, x24_parmData.x1c_distComp, x24_parmData.x24_sfxId, +// x24_parmData.x27_minVol, x24_parmData.x26_maxVol, (x24_parmData.x20_flags & 0x8) != 0); +// +// if (x50_emitterHandle) +// SetPlaying(true); x54_ready = false; } void CSfxManager::CSfxEmitterWrapper::Stop() { - if (x50_emitterHandle) { - x50_emitterHandle->getVoice()->keyOff(); - SetPlaying(false); - x50_emitterHandle.reset(); - } +// if (x50_emitterHandle) { +// x50_emitterHandle->getVoice()->keyOff(); +// SetPlaying(false); +// x50_emitterHandle.reset(); +// } } bool CSfxManager::CSfxEmitterWrapper::Ready() { @@ -153,22 +154,22 @@ CSfxManager::ESfxAudibility CSfxManager::CSfxEmitterWrapper::GetAudible(const ze u16 CSfxManager::CSfxEmitterWrapper::GetSfxId() const { return x24_parmData.x24_sfxId; } void CSfxManager::CSfxEmitterWrapper::UpdateEmitterSilent() { - if (x50_emitterHandle) { - zeus::simd_floats pos(x24_parmData.x0_pos.mSimd); - zeus::simd_floats dir(x24_parmData.xc_dir.mSimd); - x50_emitterHandle->setVectors(pos.data(), dir.data()); - x50_emitterHandle->setMaxVol(1.f / 127.f); - } +// if (x50_emitterHandle) { +// zeus::simd_floats pos(x24_parmData.x0_pos.mSimd); +// zeus::simd_floats dir(x24_parmData.xc_dir.mSimd); +// x50_emitterHandle->setVectors(pos.data(), dir.data()); +// x50_emitterHandle->setMaxVol(1.f / 127.f); +// } x55_cachedMaxVol = x24_parmData.x26_maxVol; } void CSfxManager::CSfxEmitterWrapper::UpdateEmitter() { - if (x50_emitterHandle) { - zeus::simd_floats pos(x24_parmData.x0_pos.mSimd); - zeus::simd_floats dir(x24_parmData.xc_dir.mSimd); - x50_emitterHandle->setVectors(pos.data(), dir.data()); - x50_emitterHandle->setMaxVol(x55_cachedMaxVol); - } +// if (x50_emitterHandle) { +// zeus::simd_floats pos(x24_parmData.x0_pos.mSimd); +// zeus::simd_floats dir(x24_parmData.xc_dir.mSimd); +// x50_emitterHandle->setVectors(pos.data(), dir.data()); +// x50_emitterHandle->setMaxVol(x55_cachedMaxVol); +// } } void CSfxManager::CSfxEmitterWrapper::SetReverb(float rev) { @@ -237,26 +238,26 @@ void CSfxManager::TurnOffChannel(ESfxChannels chan) { void CSfxManager::AddListener(ESfxChannels channel, const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CVector3f& heading, const zeus::CVector3f& up, float frontRadius, float surroundRadius, float soundSpeed, u32 flags /* 0x1 for doppler */, float vol) { - if (m_listener) - CAudioSys::GetAmuseEngine().removeListener(m_listener.get()); - zeus::simd_floats p(pos.mSimd); - zeus::simd_floats d(dir.mSimd); - zeus::simd_floats h(heading.mSimd); - zeus::simd_floats u(up.mSimd); - m_listener = CAudioSys::GetAmuseEngine().addListener(p.data(), d.data(), h.data(), u.data(), frontRadius, - surroundRadius, soundSpeed, vol); +// if (m_listener) +// CAudioSys::GetAmuseEngine().removeListener(m_listener.get()); +// zeus::simd_floats p(pos.mSimd); +// zeus::simd_floats d(dir.mSimd); +// zeus::simd_floats h(heading.mSimd); +// zeus::simd_floats u(up.mSimd); +// m_listener = CAudioSys::GetAmuseEngine().addListener(p.data(), d.data(), h.data(), u.data(), frontRadius, +// surroundRadius, soundSpeed, vol); } void CSfxManager::UpdateListener(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CVector3f& heading, const zeus::CVector3f& up, float vol) { - if (m_listener) { - zeus::simd_floats p(pos.mSimd); - zeus::simd_floats d(dir.mSimd); - zeus::simd_floats h(heading.mSimd); - zeus::simd_floats u(up.mSimd); - m_listener->setVectors(p.data(), d.data(), h.data(), u.data()); - m_listener->setVolume(vol); - } +// if (m_listener) { +// zeus::simd_floats p(pos.mSimd); +// zeus::simd_floats d(dir.mSimd); +// zeus::simd_floats h(heading.mSimd); +// zeus::simd_floats u(up.mSimd); +// m_listener->setVectors(p.data(), d.data(), h.data(), u.data()); +// m_listener->setVolume(vol); +// } } s16 CSfxManager::GetRank(CBaseSfxWrapper* sfx) { @@ -303,10 +304,10 @@ void CSfxManager::PitchBend(const CSfxHandle& handle, float pitch) { return; if (!handle->IsPlaying()) CSfxManager::Update(0.f); - if (handle->IsPlaying()) { - m_doUpdate = true; - handle->GetVoice()->setPitchWheel(pitch); - } +// if (handle->IsPlaying()) { +// m_doUpdate = true; +// handle->GetVoice()->setPitchWheel(pitch); +// } } void CSfxManager::SfxVolume(const CSfxHandle& handle, float vol) { @@ -316,15 +317,15 @@ void CSfxManager::SfxVolume(const CSfxHandle& handle, float vol) { CSfxWrapper& wrapper = static_cast(*handle); wrapper.SetVolume(vol); } - if (handle->IsPlaying()) - handle->GetVoice()->setVolume(vol); +// if (handle->IsPlaying()) +// handle->GetVoice()->setVolume(vol); } void CSfxManager::SfxSpan(const CSfxHandle& handle, float span) { if (!handle) return; - if (handle->IsPlaying()) - handle->GetVoice()->setSurroundPan(span); +// if (handle->IsPlaying()) +// handle->GetVoice()->setSurroundPan(span); } u16 CSfxManager::TranslateSFXID(u16 id) { @@ -379,16 +380,16 @@ void CSfxManager::UpdateEmitter(const CSfxHandle& handle, const zeus::CVector3f& float maxVol) { if (!handle || !handle->IsEmitter() || !handle->IsPlaying()) return; - m_doUpdate = true; - CSfxEmitterWrapper& emitter = static_cast(*handle); - emitter.GetEmitterData().x0_pos = pos; - emitter.GetEmitterData().xc_dir = dir; - emitter.GetEmitterData().x26_maxVol = maxVol; - amuse::Emitter& h = *emitter.GetHandle(); - zeus::simd_floats p(pos.mSimd); - zeus::simd_floats d(dir.mSimd); - h.setVectors(p.data(), d.data()); - h.setMaxVol(maxVol); +// m_doUpdate = true; +// CSfxEmitterWrapper& emitter = static_cast(*handle); +// emitter.GetEmitterData().x0_pos = pos; +// emitter.GetEmitterData().xc_dir = dir; +// emitter.GetEmitterData().x26_maxVol = maxVol; +// amuse::Emitter& h = *emitter.GetHandle(); +// zeus::simd_floats p(pos.mSimd); +// zeus::simd_floats d(dir.mSimd); +// h.setVectors(p.data(), d.data()); +// h.setMaxVol(maxVol); } CSfxHandle CSfxManager::AddEmitter(u16 id, const zeus::CVector3f& pos, const zeus::CVector3f& dir, bool useAcoustics, @@ -458,84 +459,84 @@ void CSfxManager::EnableAuxCallback() { if (m_activeEffect != EAuxEffect::None) DisableAuxCallback(); - auto studio = CAudioSys::GetAmuseEngine().getDefaultStudio(); - amuse::Submix& smix = studio->getAuxA(); - - m_activeEffect = m_nextEffect; - switch (m_activeEffect) { - case EAuxEffect::ReverbHi: - s_ReverbHiState = &smix.makeReverbHi(s_ReverbHiQueued); - break; - case EAuxEffect::Chorus: - s_ChorusState = &smix.makeChorus(s_ChorusQueued); - break; - case EAuxEffect::ReverbStd: - s_ReverbStdState = &smix.makeReverbStd(s_ReverbStdQueued); - break; - case EAuxEffect::Delay: - s_DelayState = &smix.makeDelay(s_DelayQueued); - break; - default: - break; - } +// auto studio = CAudioSys::GetAmuseEngine().getDefaultStudio(); +// amuse::Submix& smix = studio->getAuxA(); +// +// m_activeEffect = m_nextEffect; +// switch (m_activeEffect) { +// case EAuxEffect::ReverbHi: +// s_ReverbHiState = &smix.makeReverbHi(s_ReverbHiQueued); +// break; +// case EAuxEffect::Chorus: +// s_ChorusState = &smix.makeChorus(s_ChorusQueued); +// break; +// case EAuxEffect::ReverbStd: +// s_ReverbStdState = &smix.makeReverbStd(s_ReverbStdQueued); +// break; +// case EAuxEffect::Delay: +// s_DelayState = &smix.makeDelay(s_DelayQueued); +// break; +// default: +// break; +// } m_auxProcessingEnabled = true; } -void CSfxManager::PrepareDelayCallback(const amuse::EffectDelayInfo& info) { - DisableAuxProcessing(); - s_DelayQueued = info; - m_nextEffect = EAuxEffect::Delay; - if (m_reverbAmount == 0.f) - EnableAuxCallback(); -} - -void CSfxManager::PrepareReverbStdCallback(const amuse::EffectReverbStdInfo& info) { - DisableAuxProcessing(); - s_ReverbStdQueued = info; - m_nextEffect = EAuxEffect::ReverbStd; - if (m_reverbAmount == 0.f) - EnableAuxCallback(); -} - -void CSfxManager::PrepareChorusCallback(const amuse::EffectChorusInfo& info) { - DisableAuxProcessing(); - s_ChorusQueued = info; - m_nextEffect = EAuxEffect::Chorus; - if (m_reverbAmount == 0.f) - EnableAuxCallback(); -} - -void CSfxManager::PrepareReverbHiCallback(const amuse::EffectReverbHiInfo& info) { - DisableAuxProcessing(); - s_ReverbHiQueued = info; - m_nextEffect = EAuxEffect::ReverbHi; - if (m_reverbAmount == 0.f) - EnableAuxCallback(); -} +//void CSfxManager::PrepareDelayCallback(const amuse::EffectDelayInfo& info) { +// DisableAuxProcessing(); +// s_DelayQueued = info; +// m_nextEffect = EAuxEffect::Delay; +// if (m_reverbAmount == 0.f) +// EnableAuxCallback(); +//} +// +//void CSfxManager::PrepareReverbStdCallback(const amuse::EffectReverbStdInfo& info) { +// DisableAuxProcessing(); +// s_ReverbStdQueued = info; +// m_nextEffect = EAuxEffect::ReverbStd; +// if (m_reverbAmount == 0.f) +// EnableAuxCallback(); +//} +// +//void CSfxManager::PrepareChorusCallback(const amuse::EffectChorusInfo& info) { +// DisableAuxProcessing(); +// s_ChorusQueued = info; +// m_nextEffect = EAuxEffect::Chorus; +// if (m_reverbAmount == 0.f) +// EnableAuxCallback(); +//} +// +//void CSfxManager::PrepareReverbHiCallback(const amuse::EffectReverbHiInfo& info) { +// DisableAuxProcessing(); +// s_ReverbHiQueued = info; +// m_nextEffect = EAuxEffect::ReverbHi; +// if (m_reverbAmount == 0.f) +// EnableAuxCallback(); +//} void CSfxManager::DisableAuxCallback() { - auto studio = CAudioSys::GetAmuseEngine().getDefaultStudio(); - studio->getAuxA().clearEffects(); - - switch (m_activeEffect) { - case EAuxEffect::ReverbHi: - s_ReverbHiState = nullptr; - break; - case EAuxEffect::Chorus: - s_ChorusState = nullptr; - break; - case EAuxEffect::ReverbStd: - s_ReverbStdState = nullptr; - break; - case EAuxEffect::Delay: - s_DelayState = nullptr; - break; - default: - break; - } - - m_activeEffect = EAuxEffect::None; +// auto studio = CAudioSys::GetAmuseEngine().getDefaultStudio(); +// studio->getAuxA().clearEffects(); +// +// switch (m_activeEffect) { +// case EAuxEffect::ReverbHi: +// s_ReverbHiState = nullptr; +// break; +// case EAuxEffect::Chorus: +// s_ChorusState = nullptr; +// break; +// case EAuxEffect::ReverbStd: +// s_ReverbStdState = nullptr; +// break; +// case EAuxEffect::Delay: +// s_DelayState = nullptr; +// break; +// default: +// break; +// } +// +// m_activeEffect = EAuxEffect::None; } void CSfxManager::DisableAuxProcessing() { diff --git a/Runtime/Audio/CSfxManager.hpp b/Runtime/Audio/CSfxManager.hpp index 9c237c302..8435194ff 100644 --- a/Runtime/Audio/CSfxManager.hpp +++ b/Runtime/Audio/CSfxManager.hpp @@ -5,7 +5,7 @@ #include #include -#include "DNAMP1/SFX/SFX.h" +#include "SFX/SFX.h" #include "Runtime/RetroTypes.hpp" #include "Runtime/Audio/CAudioSys.hpp" @@ -90,7 +90,7 @@ public: virtual void Stop() = 0; virtual bool Ready() = 0; virtual ESfxAudibility GetAudible(const zeus::CVector3f&) = 0; - virtual amuse::ObjToken GetVoice() const = 0; + //virtual amuse::ObjToken GetVoice() const = 0; virtual u16 GetSfxId() const = 0; virtual void UpdateEmitterSilent() = 0; virtual void UpdateEmitter() = 0; @@ -116,7 +116,7 @@ public: class CSfxEmitterWrapper : public CBaseSfxWrapper { float x1a_reverb = 0.0f; CAudioSys::C3DEmitterParmData x24_parmData; - amuse::ObjToken x50_emitterHandle; + //amuse::ObjToken x50_emitterHandle; bool x54_ready = true; float x55_cachedMaxVol = 0.0f; @@ -126,14 +126,14 @@ public: void Stop() override; bool Ready() override; ESfxAudibility GetAudible(const zeus::CVector3f&) override; - amuse::ObjToken GetVoice() const override { return x50_emitterHandle->getVoice(); } + //amuse::ObjToken GetVoice() const override { return x50_emitterHandle->getVoice(); } u16 GetSfxId() const override; void UpdateEmitterSilent() override; void UpdateEmitter() override; void SetReverb(float rev) override; CAudioSys::C3DEmitterParmData& GetEmitterData() { return x24_parmData; } - amuse::ObjToken GetHandle() const { return x50_emitterHandle; } + //amuse::ObjToken GetHandle() const { return x50_emitterHandle; } CSfxEmitterWrapper(bool looped, s16 prio, const CAudioSys::C3DEmitterParmData& data, /*const CSfxHandle& handle,*/ bool useAcoustics, TAreaId area) @@ -144,7 +144,7 @@ public: class CSfxWrapper : public CBaseSfxWrapper { u16 x18_sfxId; - amuse::ObjToken x1c_voiceHandle; + //amuse::ObjToken x1c_voiceHandle; float x20_vol; float x22_pan; bool x24_ready = true; @@ -155,7 +155,7 @@ public: void Stop() override; bool Ready() override; ESfxAudibility GetAudible(const zeus::CVector3f&) override { return ESfxAudibility::Aud3; } - amuse::ObjToken GetVoice() const override { return x1c_voiceHandle; } +// amuse::ObjToken GetVoice() const override { return x1c_voiceHandle; } u16 GetSfxId() const override; void UpdateEmitterSilent() override; void UpdateEmitter() override; @@ -178,7 +178,7 @@ public: static float m_reverbAmount; static EAuxEffect m_activeEffect; static EAuxEffect m_nextEffect; - static amuse::ObjToken m_listener; + //static amuse::ObjToken m_listener; static u16 kMaxPriority; static u16 kMedPriority; @@ -222,10 +222,10 @@ public: static void StopAndRemoveAllEmitters(); static void DisableAuxCallback(); static void EnableAuxCallback(); - static void PrepareDelayCallback(const amuse::EffectDelayInfo& info); - static void PrepareReverbStdCallback(const amuse::EffectReverbStdInfo& info); - static void PrepareChorusCallback(const amuse::EffectChorusInfo& info); - static void PrepareReverbHiCallback(const amuse::EffectReverbHiInfo& info); +// static void PrepareDelayCallback(const amuse::EffectDelayInfo& info); +// static void PrepareReverbStdCallback(const amuse::EffectReverbStdInfo& info); +// static void PrepareChorusCallback(const amuse::EffectChorusInfo& info); +// static void PrepareReverbHiCallback(const amuse::EffectReverbHiInfo& info); static void DisableAuxProcessing(); static void SetActiveAreas(const rstl::reserved_vector& areas); diff --git a/Runtime/Audio/CStaticAudioPlayer.cpp b/Runtime/Audio/CStaticAudioPlayer.cpp index d8c34c743..b85a2e24a 100644 --- a/Runtime/Audio/CStaticAudioPlayer.cpp +++ b/Runtime/Audio/CStaticAudioPlayer.cpp @@ -7,37 +7,37 @@ namespace metaforce { #define RSF_BUFFER_SIZE 0x20000 -CStaticAudioPlayer::CStaticAudioPlayer(boo::IAudioVoiceEngine& engine, std::string_view path, int loopStart, - int loopEnd) -: x0_path(path) -, x1c_loopStartSamp(loopStart & 0xfffffffe) -, x20_loopEndSamp(loopEnd & 0xfffffffe) -, m_voiceCallback(*this) -, m_voice(engine.allocateNewStereoVoice(32000, &m_voiceCallback)) { - // These are mixed directly into boo voice engine instead - // x28_dmaLeft.reset(new u8[640]); - // x30_dmaRight.reset(new u8[640]); - - CDvdFile file(path); - x10_rsfRem = file.Length(); - x14_rsfLength = x10_rsfRem; - - u32 bufCount = (x10_rsfRem + RSF_BUFFER_SIZE - 1) / RSF_BUFFER_SIZE; - x48_buffers.reserve(bufCount); - x38_dvdRequests.reserve(bufCount); - - for (int remBytes = x10_rsfRem; remBytes > 0; remBytes -= RSF_BUFFER_SIZE) { - u32 thisSz = RSF_BUFFER_SIZE; - if (remBytes < RSF_BUFFER_SIZE) - thisSz = ROUND_UP_32(remBytes); - - x48_buffers.emplace_back(new u8[thisSz]); - x38_dvdRequests.push_back(file.AsyncRead(x48_buffers.back().get(), thisSz)); - } - - g72x_init_state(&x58_leftState); - g72x_init_state(&x8c_rightState); -} +//CStaticAudioPlayer::CStaticAudioPlayer(boo::IAudioVoiceEngine& engine, std::string_view path, int loopStart, +// int loopEnd) +//: x0_path(path) +//, x1c_loopStartSamp(loopStart & 0xfffffffe) +//, x20_loopEndSamp(loopEnd & 0xfffffffe) +//, m_voiceCallback(*this) +//, m_voice(engine.allocateNewStereoVoice(32000, &m_voiceCallback)) { +// // These are mixed directly into boo voice engine instead +// // x28_dmaLeft.reset(new u8[640]); +// // x30_dmaRight.reset(new u8[640]); +// +// CDvdFile file(path); +// x10_rsfRem = file.Length(); +// x14_rsfLength = x10_rsfRem; +// +// u32 bufCount = (x10_rsfRem + RSF_BUFFER_SIZE - 1) / RSF_BUFFER_SIZE; +// x48_buffers.reserve(bufCount); +// x38_dvdRequests.reserve(bufCount); +// +// for (int remBytes = x10_rsfRem; remBytes > 0; remBytes -= RSF_BUFFER_SIZE) { +// u32 thisSz = RSF_BUFFER_SIZE; +// if (remBytes < RSF_BUFFER_SIZE) +// thisSz = ROUND_UP_32(remBytes); +// +// x48_buffers.emplace_back(new u8[thisSz]); +// x38_dvdRequests.push_back(file.AsyncRead(x48_buffers.back().get(), thisSz)); +// } +// +// g72x_init_state(&x58_leftState); +// g72x_init_state(&x8c_rightState); +//} bool CStaticAudioPlayer::IsReady() { if (x38_dvdRequests.size()) diff --git a/Runtime/Audio/CStaticAudioPlayer.hpp b/Runtime/Audio/CStaticAudioPlayer.hpp index 0625b68ca..fb39fe3c8 100644 --- a/Runtime/Audio/CStaticAudioPlayer.hpp +++ b/Runtime/Audio/CStaticAudioPlayer.hpp @@ -10,8 +10,8 @@ #include "g721.h" -#include -#include +//#include +//#include namespace metaforce { class IDvdRequest; @@ -41,8 +41,8 @@ class CStaticAudioPlayer { val = 32767; return val; } - - struct AudioVoiceCallback : boo::IAudioVoiceCallback { +/* + struct AudioVoiceCallback { CStaticAudioPlayer& m_parent; void preSupplyAudio(boo::IAudioVoice&, double) override {} size_t supplyAudio(boo::IAudioVoice& voice, size_t frames, int16_t* data) override { @@ -56,20 +56,20 @@ class CStaticAudioPlayer { explicit AudioVoiceCallback(CStaticAudioPlayer& p) : m_parent(p) {} } m_voiceCallback; boo::ObjToken m_voice; - +*/ public: - CStaticAudioPlayer(boo::IAudioVoiceEngine& engine, std::string_view path, int loopStart, int loopEnd); - CStaticAudioPlayer(std::string_view path, int loopStart, int loopEnd) - : CStaticAudioPlayer(*CAudioSys::GetVoiceEngine(), path, loopStart, loopEnd) {} +// CStaticAudioPlayer(boo::IAudioVoiceEngine& engine, std::string_view path, int loopStart, int loopEnd); +// CStaticAudioPlayer(std::string_view path, int loopStart, int loopEnd) +// : CStaticAudioPlayer(*CAudioSys::GetVoiceEngine(), path, loopStart, loopEnd) {} bool IsReady(); void DecodeMonoAndMix(s16* bufOut, u32 numSamples, u32 cur, u32 loopEndCur, u32 loopStartCur, int vol, g72x_state& state, std::optional& loopState) const; void Decode(s16* bufOut, u32 numSamples); void SetVolume(float vol) { xc0_volume = zeus::clamp(0.f, vol, 1.f) * 32768.f; } - - void StartMixing() { m_voice->start(); } - void StopMixing() { m_voice->stop(); } +// +// void StartMixing() { m_voice->start(); } +// void StopMixing() { m_voice->stop(); } }; } // namespace metaforce diff --git a/Runtime/Audio/CStreamAudioManager.cpp b/Runtime/Audio/CStreamAudioManager.cpp index 810c52822..6c6248cb6 100644 --- a/Runtime/Audio/CStreamAudioManager.cpp +++ b/Runtime/Audio/CStreamAudioManager.cpp @@ -11,7 +11,7 @@ #include #include -#include +//#include namespace metaforce { class CDSPStreamManager; @@ -54,7 +54,7 @@ struct SDSPStreamInfo { explicit SDSPStreamInfo(const CDSPStreamManager& stream); }; -struct SDSPStream : boo::IAudioVoiceCallback { +struct SDSPStream { bool x0_active; bool x1_oneshot; s32 x4_ownerId; @@ -155,91 +155,91 @@ struct SDSPStream : boo::IAudioVoiceCallback { s16 m_prev1 = 0; s16 m_prev2 = 0; - void preSupplyAudio(boo::IAudioVoice&, double) override {} +// void preSupplyAudio(boo::IAudioVoice&, double) override {} - unsigned decompressChunk(unsigned readToSample, int16_t*& data) { - unsigned startSamp = m_curSample; +// unsigned decompressChunk(unsigned readToSample, int16_t*& data) { +// unsigned startSamp = m_curSample; +// +// auto sampDiv = std::div(int(m_curSample), int(14)); +// if (sampDiv.rem) { +// unsigned samps = DSPDecompressFrameRanged(data, xd4_ringBuffer.get() + sampDiv.quot * 8, x10_info.x1c_coef, +// &m_prev1, &m_prev2, unsigned(sampDiv.rem), readToSample - m_curSample); +// m_curSample += samps; +// data += samps; +// ++sampDiv.quot; +// } +// +// while (m_curSample < readToSample) { +// unsigned samps = DSPDecompressFrame(data, xd4_ringBuffer.get() + sampDiv.quot * 8, x10_info.x1c_coef, &m_prev1, +// &m_prev2, readToSample - m_curSample); +// m_curSample += samps; +// data += samps; +// ++sampDiv.quot; +// } +// +// return m_curSample - startSamp; +// } - auto sampDiv = std::div(int(m_curSample), int(14)); - if (sampDiv.rem) { - unsigned samps = DSPDecompressFrameRanged(data, xd4_ringBuffer.get() + sampDiv.quot * 8, x10_info.x1c_coef, - &m_prev1, &m_prev2, unsigned(sampDiv.rem), readToSample - m_curSample); - m_curSample += samps; - data += samps; - ++sampDiv.quot; - } - - while (m_curSample < readToSample) { - unsigned samps = DSPDecompressFrame(data, xd4_ringBuffer.get() + sampDiv.quot * 8, x10_info.x1c_coef, &m_prev1, - &m_prev2, readToSample - m_curSample); - m_curSample += samps; - data += samps; - ++sampDiv.quot; - } - - return m_curSample - startSamp; - } - - size_t supplyAudio(boo::IAudioVoice&, size_t frames, int16_t* data) override { - if (!x0_active) { - memset(data, 0, frames * 2); - return frames; - } - - if (xe8_silent) { - StopStream(); - memset(data, 0, frames * 2); - return frames; - } - - unsigned halfRingSamples = xdc_ringSamples / 2; - - size_t remFrames = frames; - while (remFrames) { - if (xec_readState != 2 || (xe0_curBuffer == 0 && m_curSample >= halfRingSamples)) { - if (!BufferStream()) { - memset(data, 0, remFrames * 2); - return frames; - } - } - - unsigned readToSample = - std::min(m_curSample + unsigned(remFrames), (m_curSample / halfRingSamples + 1) * halfRingSamples); - - if (!x10_info.x10_loopFlag) { - m_totalSamples += remFrames; - size_t fileSamples = x10_info.xc_adpcmBytes * 14 / 8; - if (m_totalSamples >= fileSamples) { - size_t leftover = m_totalSamples - fileSamples; - readToSample -= leftover; - remFrames -= leftover; - memset(data + remFrames, 0, leftover * 2); - StopStream(); - } - } - - unsigned leftoverSamples = 0; - if (readToSample > xdc_ringSamples) { - leftoverSamples = readToSample - xdc_ringSamples; - readToSample = xdc_ringSamples; - } - - remFrames -= decompressChunk(readToSample, data); - - if (leftoverSamples) { - BufferStream(); - m_curSample = 0; - remFrames -= decompressChunk(leftoverSamples, data); - } - } - - return frames; - } - boo::ObjToken m_booVoice; +// size_t supplyAudio(boo::IAudioVoice&, size_t frames, int16_t* data) override { +// if (!x0_active) { +// memset(data, 0, frames * 2); +// return frames; +// } +// +// if (xe8_silent) { +// StopStream(); +// memset(data, 0, frames * 2); +// return frames; +// } +// +// unsigned halfRingSamples = xdc_ringSamples / 2; +// +// size_t remFrames = frames; +// while (remFrames) { +// if (xec_readState != 2 || (xe0_curBuffer == 0 && m_curSample >= halfRingSamples)) { +// if (!BufferStream()) { +// memset(data, 0, remFrames * 2); +// return frames; +// } +// } +// +// unsigned readToSample = +// std::min(m_curSample + unsigned(remFrames), (m_curSample / halfRingSamples + 1) * halfRingSamples); +// +// if (!x10_info.x10_loopFlag) { +// m_totalSamples += remFrames; +// size_t fileSamples = x10_info.xc_adpcmBytes * 14 / 8; +// if (m_totalSamples >= fileSamples) { +// size_t leftover = m_totalSamples - fileSamples; +// readToSample -= leftover; +// remFrames -= leftover; +// memset(data + remFrames, 0, leftover * 2); +// StopStream(); +// } +// } +// +// unsigned leftoverSamples = 0; +// if (readToSample > xdc_ringSamples) { +// leftoverSamples = readToSample - xdc_ringSamples; +// readToSample = xdc_ringSamples; +// } +// +// remFrames -= decompressChunk(readToSample, data); +// +// if (leftoverSamples) { +// BufferStream(); +// m_curSample = 0; +// remFrames -= decompressChunk(leftoverSamples, data); +// } +// } +// +// return frames; +// } +// boo::ObjToken m_booVoice; void DoAllocateStream() { xd4_ringBuffer.reset(new u8[0x11DC0]); - m_booVoice = CAudioSys::GetVoiceEngine()->allocateNewMonoVoice(32000.0, this); + //m_booVoice = CAudioSys::GetVoiceEngine()->allocateNewMonoVoice(32000.0, this); } static void Initialize() { @@ -259,18 +259,18 @@ struct SDSPStream : boo::IAudioVoiceCallback { } static void FreeAllStreams() { - for (auto& stream : g_Streams) { - stream.m_booVoice.reset(); - stream.x0_active = false; - for (auto& request : stream.m_readReqs) { - if (request) { - request->PostCancelRequest(); - request.reset(); - } - } - stream.xd4_ringBuffer.reset(); - stream.m_file = std::nullopt; - } +// for (auto& stream : g_Streams) { +// stream.m_booVoice.reset(); +// stream.x0_active = false; +// for (auto& request : stream.m_readReqs) { +// if (request) { +// request->PostCancelRequest(); +// request.reset(); +// } +// } +// stream.xd4_ringBuffer.reset(); +// stream.m_file = std::nullopt; +// } } static s32 PickFreeStream(SDSPStream*& streamOut, bool oneshot) { @@ -302,27 +302,27 @@ struct SDSPStream : boo::IAudioVoiceCallback { } void UpdateStreamVolume(float vol) { - x4c_vol = vol; - if (!x0_active || xe8_silent) { - return; - } - std::array coefs{}; - coefs[size_t(boo::AudioChannel::FrontLeft)] = m_leftgain * vol; - coefs[size_t(boo::AudioChannel::FrontRight)] = m_rightgain * vol; - m_booVoice->setMonoChannelLevels(nullptr, coefs.data(), true); +// x4c_vol = vol; +// if (!x0_active || xe8_silent) { +// return; +// } +// std::array coefs{}; +// coefs[size_t(boo::AudioChannel::FrontLeft)] = m_leftgain * vol; +// coefs[size_t(boo::AudioChannel::FrontRight)] = m_rightgain * vol; +// m_booVoice->setMonoChannelLevels(nullptr, coefs.data(), true); } static void UpdateVolume(s32 id, float vol) { - s32 idx = FindStreamIdx(id); - if (idx == -1) - return; - - SDSPStream& stream = g_Streams[idx]; - stream.UpdateStreamVolume(vol); - if (SDSPStream* left = stream.x8_stereoLeft) - left->UpdateStreamVolume(vol); - if (SDSPStream* right = stream.xc_companionRight) - right->UpdateStreamVolume(vol); +// s32 idx = FindStreamIdx(id); +// if (idx == -1) +// return; +// +// SDSPStream& stream = g_Streams[idx]; +// stream.UpdateStreamVolume(vol); +// if (SDSPStream* left = stream.x8_stereoLeft) +// left->UpdateStreamVolume(vol); +// if (SDSPStream* right = stream.xc_companionRight) +// right->UpdateStreamVolume(vol); } void SilenceStream() { @@ -330,7 +330,7 @@ struct SDSPStream : boo::IAudioVoiceCallback { return; } constexpr std::array coefs{}; - m_booVoice->setMonoChannelLevels(nullptr, coefs.data(), true); + //m_booVoice->setMonoChannelLevels(nullptr, coefs.data(), true); xe8_silent = true; x0_active = false; } @@ -350,7 +350,7 @@ struct SDSPStream : boo::IAudioVoiceCallback { void StopStream() { x0_active = false; - m_booVoice->stop(); + //m_booVoice->stop(); m_file = std::nullopt; } @@ -427,8 +427,8 @@ struct SDSPStream : boo::IAudioVoiceCallback { m_prev1 = 0; m_prev2 = 0; memset(xd4_ringBuffer.get(), 0, 0x11DC0); - m_booVoice->resetSampleRate(info.x4_sampleRate); - m_booVoice->start(); + //m_booVoice->resetSampleRate(info.x4_sampleRate); + //m_booVoice->start(); UpdateStreamVolume(vol); } @@ -810,12 +810,12 @@ std::array CDSPStreamManager::g_Streams{}; SDSPStreamInfo::SDSPStreamInfo(const CDSPStreamManager& stream) { x0_fileName = stream.x60_fileName.c_str(); - x4_sampleRate = hecl::SBig(stream.x0_header.x8_sample_rate); - xc_adpcmBytes = (hecl::SBig(stream.x0_header.x4_num_nibbles) / 2) & 0x7FFFFFE0; + x4_sampleRate = SBig(stream.x0_header.x8_sample_rate); + xc_adpcmBytes = (SBig(stream.x0_header.x4_num_nibbles) / 2) & 0x7FFFFFE0; if (stream.x0_header.xc_loop_flag) { - u32 loopStartNibble = hecl::SBig(stream.x0_header.x10_loop_start_nibble); - u32 loopEndNibble = hecl::SBig(stream.x0_header.x14_loop_end_nibble); + u32 loopStartNibble = SBig(stream.x0_header.x10_loop_start_nibble); + u32 loopEndNibble = SBig(stream.x0_header.x14_loop_end_nibble); x10_loopFlag = true; x14_loopStartByte = (loopStartNibble / 2) & 0x7FFFFFE0; x18_loopEndByte = std::min((loopEndNibble / 2) & 0x7FFFFFE0, xc_adpcmBytes); @@ -826,8 +826,8 @@ SDSPStreamInfo::SDSPStreamInfo(const CDSPStreamManager& stream) { } for (int i = 0; i < 8; ++i) { - x1c_coef[i][0] = hecl::SBig(stream.x0_header.x1c_coef[i][0]); - x1c_coef[i][1] = hecl::SBig(stream.x0_header.x1c_coef[i][1]); + x1c_coef[i][0] = SBig(stream.x0_header.x1c_coef[i][0]); + x1c_coef[i][1] = SBig(stream.x0_header.x1c_coef[i][1]); } } diff --git a/DataSpec/DNAMP1/SFX/Atomic.h b/Runtime/Audio/SFX/Atomic.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Atomic.h rename to Runtime/Audio/SFX/Atomic.h diff --git a/DataSpec/DNAMP1/SFX/BetaBeetle.h b/Runtime/Audio/SFX/BetaBeetle.h similarity index 100% rename from DataSpec/DNAMP1/SFX/BetaBeetle.h rename to Runtime/Audio/SFX/BetaBeetle.h diff --git a/DataSpec/DNAMP1/SFX/Bird.h b/Runtime/Audio/SFX/Bird.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Bird.h rename to Runtime/Audio/SFX/Bird.h diff --git a/DataSpec/DNAMP1/SFX/BloodFlower.h b/Runtime/Audio/SFX/BloodFlower.h similarity index 100% rename from DataSpec/DNAMP1/SFX/BloodFlower.h rename to Runtime/Audio/SFX/BloodFlower.h diff --git a/DataSpec/DNAMP1/SFX/Burrower.h b/Runtime/Audio/SFX/Burrower.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Burrower.h rename to Runtime/Audio/SFX/Burrower.h diff --git a/DataSpec/DNAMP1/SFX/ChozoGhost.h b/Runtime/Audio/SFX/ChozoGhost.h similarity index 100% rename from DataSpec/DNAMP1/SFX/ChozoGhost.h rename to Runtime/Audio/SFX/ChozoGhost.h diff --git a/DataSpec/DNAMP1/SFX/ChubbWeed.h b/Runtime/Audio/SFX/ChubbWeed.h similarity index 100% rename from DataSpec/DNAMP1/SFX/ChubbWeed.h rename to Runtime/Audio/SFX/ChubbWeed.h diff --git a/DataSpec/DNAMP1/SFX/CineBoots.h b/Runtime/Audio/SFX/CineBoots.h similarity index 100% rename from DataSpec/DNAMP1/SFX/CineBoots.h rename to Runtime/Audio/SFX/CineBoots.h diff --git a/DataSpec/DNAMP1/SFX/CineGeneral.h b/Runtime/Audio/SFX/CineGeneral.h similarity index 100% rename from DataSpec/DNAMP1/SFX/CineGeneral.h rename to Runtime/Audio/SFX/CineGeneral.h diff --git a/DataSpec/DNAMP1/SFX/CineGun.h b/Runtime/Audio/SFX/CineGun.h similarity index 100% rename from DataSpec/DNAMP1/SFX/CineGun.h rename to Runtime/Audio/SFX/CineGun.h diff --git a/DataSpec/DNAMP1/SFX/CineMorphball.h b/Runtime/Audio/SFX/CineMorphball.h similarity index 100% rename from DataSpec/DNAMP1/SFX/CineMorphball.h rename to Runtime/Audio/SFX/CineMorphball.h diff --git a/DataSpec/DNAMP1/SFX/CineSuit.h b/Runtime/Audio/SFX/CineSuit.h similarity index 100% rename from DataSpec/DNAMP1/SFX/CineSuit.h rename to Runtime/Audio/SFX/CineSuit.h diff --git a/DataSpec/DNAMP1/SFX/CineVisor.h b/Runtime/Audio/SFX/CineVisor.h similarity index 100% rename from DataSpec/DNAMP1/SFX/CineVisor.h rename to Runtime/Audio/SFX/CineVisor.h diff --git a/DataSpec/DNAMP1/SFX/Crater.h b/Runtime/Audio/SFX/Crater.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Crater.h rename to Runtime/Audio/SFX/Crater.h diff --git a/DataSpec/DNAMP1/SFX/Crystallite.h b/Runtime/Audio/SFX/Crystallite.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Crystallite.h rename to Runtime/Audio/SFX/Crystallite.h diff --git a/DataSpec/DNAMP1/SFX/Drones.h b/Runtime/Audio/SFX/Drones.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Drones.h rename to Runtime/Audio/SFX/Drones.h diff --git a/DataSpec/DNAMP1/SFX/EliteSpacePirate.h b/Runtime/Audio/SFX/EliteSpacePirate.h similarity index 100% rename from DataSpec/DNAMP1/SFX/EliteSpacePirate.h rename to Runtime/Audio/SFX/EliteSpacePirate.h diff --git a/DataSpec/DNAMP1/SFX/FireFlea.h b/Runtime/Audio/SFX/FireFlea.h similarity index 100% rename from DataSpec/DNAMP1/SFX/FireFlea.h rename to Runtime/Audio/SFX/FireFlea.h diff --git a/DataSpec/DNAMP1/SFX/Flaaghra.h b/Runtime/Audio/SFX/Flaaghra.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Flaaghra.h rename to Runtime/Audio/SFX/Flaaghra.h diff --git a/DataSpec/DNAMP1/SFX/FlickerBat.h b/Runtime/Audio/SFX/FlickerBat.h similarity index 100% rename from DataSpec/DNAMP1/SFX/FlickerBat.h rename to Runtime/Audio/SFX/FlickerBat.h diff --git a/DataSpec/DNAMP1/SFX/FlyingPirate.h b/Runtime/Audio/SFX/FlyingPirate.h similarity index 100% rename from DataSpec/DNAMP1/SFX/FlyingPirate.h rename to Runtime/Audio/SFX/FlyingPirate.h diff --git a/DataSpec/DNAMP1/SFX/FrontEnd.h b/Runtime/Audio/SFX/FrontEnd.h similarity index 100% rename from DataSpec/DNAMP1/SFX/FrontEnd.h rename to Runtime/Audio/SFX/FrontEnd.h diff --git a/DataSpec/DNAMP1/SFX/GagantuanBeatle.h b/Runtime/Audio/SFX/GagantuanBeatle.h similarity index 100% rename from DataSpec/DNAMP1/SFX/GagantuanBeatle.h rename to Runtime/Audio/SFX/GagantuanBeatle.h diff --git a/DataSpec/DNAMP1/SFX/Gnats.h b/Runtime/Audio/SFX/Gnats.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Gnats.h rename to Runtime/Audio/SFX/Gnats.h diff --git a/DataSpec/DNAMP1/SFX/Gryzbee.h b/Runtime/Audio/SFX/Gryzbee.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Gryzbee.h rename to Runtime/Audio/SFX/Gryzbee.h diff --git a/DataSpec/DNAMP1/SFX/IceCrack.h b/Runtime/Audio/SFX/IceCrack.h similarity index 100% rename from DataSpec/DNAMP1/SFX/IceCrack.h rename to Runtime/Audio/SFX/IceCrack.h diff --git a/DataSpec/DNAMP1/SFX/IceWorld.h b/Runtime/Audio/SFX/IceWorld.h similarity index 100% rename from DataSpec/DNAMP1/SFX/IceWorld.h rename to Runtime/Audio/SFX/IceWorld.h diff --git a/DataSpec/DNAMP1/SFX/InjuredPirates.h b/Runtime/Audio/SFX/InjuredPirates.h similarity index 100% rename from DataSpec/DNAMP1/SFX/InjuredPirates.h rename to Runtime/Audio/SFX/InjuredPirates.h diff --git a/DataSpec/DNAMP1/SFX/IntroBoss.h b/Runtime/Audio/SFX/IntroBoss.h similarity index 100% rename from DataSpec/DNAMP1/SFX/IntroBoss.h rename to Runtime/Audio/SFX/IntroBoss.h diff --git a/DataSpec/DNAMP1/SFX/IntroWorld.h b/Runtime/Audio/SFX/IntroWorld.h similarity index 100% rename from DataSpec/DNAMP1/SFX/IntroWorld.h rename to Runtime/Audio/SFX/IntroWorld.h diff --git a/DataSpec/DNAMP1/SFX/JellyZap.h b/Runtime/Audio/SFX/JellyZap.h similarity index 100% rename from DataSpec/DNAMP1/SFX/JellyZap.h rename to Runtime/Audio/SFX/JellyZap.h diff --git a/DataSpec/DNAMP1/SFX/LavaWorld.h b/Runtime/Audio/SFX/LavaWorld.h similarity index 100% rename from DataSpec/DNAMP1/SFX/LavaWorld.h rename to Runtime/Audio/SFX/LavaWorld.h diff --git a/DataSpec/DNAMP1/SFX/Magdolite.h b/Runtime/Audio/SFX/Magdolite.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Magdolite.h rename to Runtime/Audio/SFX/Magdolite.h diff --git a/DataSpec/DNAMP1/SFX/Metaree.h b/Runtime/Audio/SFX/Metaree.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Metaree.h rename to Runtime/Audio/SFX/Metaree.h diff --git a/DataSpec/DNAMP1/SFX/Metroid.h b/Runtime/Audio/SFX/Metroid.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Metroid.h rename to Runtime/Audio/SFX/Metroid.h diff --git a/DataSpec/DNAMP1/SFX/MetroidPrime.h b/Runtime/Audio/SFX/MetroidPrime.h similarity index 100% rename from DataSpec/DNAMP1/SFX/MetroidPrime.h rename to Runtime/Audio/SFX/MetroidPrime.h diff --git a/DataSpec/DNAMP1/SFX/MinesWorld.h b/Runtime/Audio/SFX/MinesWorld.h similarity index 100% rename from DataSpec/DNAMP1/SFX/MinesWorld.h rename to Runtime/Audio/SFX/MinesWorld.h diff --git a/DataSpec/DNAMP1/SFX/Misc.h b/Runtime/Audio/SFX/Misc.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Misc.h rename to Runtime/Audio/SFX/Misc.h diff --git a/DataSpec/DNAMP1/SFX/MiscSamus.h b/Runtime/Audio/SFX/MiscSamus.h similarity index 100% rename from DataSpec/DNAMP1/SFX/MiscSamus.h rename to Runtime/Audio/SFX/MiscSamus.h diff --git a/DataSpec/DNAMP1/SFX/OmegaPirate.h b/Runtime/Audio/SFX/OmegaPirate.h similarity index 100% rename from DataSpec/DNAMP1/SFX/OmegaPirate.h rename to Runtime/Audio/SFX/OmegaPirate.h diff --git a/DataSpec/DNAMP1/SFX/OverWorld.h b/Runtime/Audio/SFX/OverWorld.h similarity index 100% rename from DataSpec/DNAMP1/SFX/OverWorld.h rename to Runtime/Audio/SFX/OverWorld.h diff --git a/DataSpec/DNAMP1/SFX/Parasite.h b/Runtime/Audio/SFX/Parasite.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Parasite.h rename to Runtime/Audio/SFX/Parasite.h diff --git a/DataSpec/DNAMP1/SFX/Phazon.h b/Runtime/Audio/SFX/Phazon.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Phazon.h rename to Runtime/Audio/SFX/Phazon.h diff --git a/DataSpec/DNAMP1/SFX/PhazonGun.h b/Runtime/Audio/SFX/PhazonGun.h similarity index 100% rename from DataSpec/DNAMP1/SFX/PhazonGun.h rename to Runtime/Audio/SFX/PhazonGun.h diff --git a/DataSpec/DNAMP1/SFX/PuddleSpore.h b/Runtime/Audio/SFX/PuddleSpore.h similarity index 100% rename from DataSpec/DNAMP1/SFX/PuddleSpore.h rename to Runtime/Audio/SFX/PuddleSpore.h diff --git a/DataSpec/DNAMP1/SFX/PuddleToad.h b/Runtime/Audio/SFX/PuddleToad.h similarity index 100% rename from DataSpec/DNAMP1/SFX/PuddleToad.h rename to Runtime/Audio/SFX/PuddleToad.h diff --git a/DataSpec/DNAMP1/SFX/Puffer.h b/Runtime/Audio/SFX/Puffer.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Puffer.h rename to Runtime/Audio/SFX/Puffer.h diff --git a/DataSpec/DNAMP1/SFX/ReactorDoor.h b/Runtime/Audio/SFX/ReactorDoor.h similarity index 100% rename from DataSpec/DNAMP1/SFX/ReactorDoor.h rename to Runtime/Audio/SFX/ReactorDoor.h diff --git a/DataSpec/DNAMP1/SFX/Ridley.h b/Runtime/Audio/SFX/Ridley.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Ridley.h rename to Runtime/Audio/SFX/Ridley.h diff --git a/DataSpec/DNAMP1/SFX/Ripper.h b/Runtime/Audio/SFX/Ripper.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Ripper.h rename to Runtime/Audio/SFX/Ripper.h diff --git a/DataSpec/DNAMP1/SFX/RuinsWorld.h b/Runtime/Audio/SFX/RuinsWorld.h similarity index 100% rename from DataSpec/DNAMP1/SFX/RuinsWorld.h rename to Runtime/Audio/SFX/RuinsWorld.h diff --git a/DataSpec/DNAMP1/SFX/SFX.h b/Runtime/Audio/SFX/SFX.h similarity index 100% rename from DataSpec/DNAMP1/SFX/SFX.h rename to Runtime/Audio/SFX/SFX.h diff --git a/DataSpec/DNAMP1/SFX/SamusShip.h b/Runtime/Audio/SFX/SamusShip.h similarity index 100% rename from DataSpec/DNAMP1/SFX/SamusShip.h rename to Runtime/Audio/SFX/SamusShip.h diff --git a/DataSpec/DNAMP1/SFX/Scarab.h b/Runtime/Audio/SFX/Scarab.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Scarab.h rename to Runtime/Audio/SFX/Scarab.h diff --git a/DataSpec/DNAMP1/SFX/Seedling.h b/Runtime/Audio/SFX/Seedling.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Seedling.h rename to Runtime/Audio/SFX/Seedling.h diff --git a/DataSpec/DNAMP1/SFX/SheeGoth.h b/Runtime/Audio/SFX/SheeGoth.h similarity index 100% rename from DataSpec/DNAMP1/SFX/SheeGoth.h rename to Runtime/Audio/SFX/SheeGoth.h diff --git a/DataSpec/DNAMP1/SFX/SnakeWeed.h b/Runtime/Audio/SFX/SnakeWeed.h similarity index 100% rename from DataSpec/DNAMP1/SFX/SnakeWeed.h rename to Runtime/Audio/SFX/SnakeWeed.h diff --git a/DataSpec/DNAMP1/SFX/Sova.h b/Runtime/Audio/SFX/Sova.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Sova.h rename to Runtime/Audio/SFX/Sova.h diff --git a/DataSpec/DNAMP1/SFX/SpacePirate.h b/Runtime/Audio/SFX/SpacePirate.h similarity index 100% rename from DataSpec/DNAMP1/SFX/SpacePirate.h rename to Runtime/Audio/SFX/SpacePirate.h diff --git a/DataSpec/DNAMP1/SFX/SpankWeed.h b/Runtime/Audio/SFX/SpankWeed.h similarity index 100% rename from DataSpec/DNAMP1/SFX/SpankWeed.h rename to Runtime/Audio/SFX/SpankWeed.h diff --git a/DataSpec/DNAMP1/SFX/Thardus.h b/Runtime/Audio/SFX/Thardus.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Thardus.h rename to Runtime/Audio/SFX/Thardus.h diff --git a/DataSpec/DNAMP1/SFX/TheEnd.h b/Runtime/Audio/SFX/TheEnd.h similarity index 100% rename from DataSpec/DNAMP1/SFX/TheEnd.h rename to Runtime/Audio/SFX/TheEnd.h diff --git a/DataSpec/DNAMP1/SFX/Torobyte.h b/Runtime/Audio/SFX/Torobyte.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Torobyte.h rename to Runtime/Audio/SFX/Torobyte.h diff --git a/DataSpec/DNAMP1/SFX/Triclops.h b/Runtime/Audio/SFX/Triclops.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Triclops.h rename to Runtime/Audio/SFX/Triclops.h diff --git a/DataSpec/DNAMP1/SFX/Turret.h b/Runtime/Audio/SFX/Turret.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Turret.h rename to Runtime/Audio/SFX/Turret.h diff --git a/DataSpec/DNAMP1/SFX/UI.h b/Runtime/Audio/SFX/UI.h similarity index 100% rename from DataSpec/DNAMP1/SFX/UI.h rename to Runtime/Audio/SFX/UI.h diff --git a/DataSpec/DNAMP1/SFX/WarWasp.h b/Runtime/Audio/SFX/WarWasp.h similarity index 100% rename from DataSpec/DNAMP1/SFX/WarWasp.h rename to Runtime/Audio/SFX/WarWasp.h diff --git a/DataSpec/DNAMP1/SFX/Weapons.h b/Runtime/Audio/SFX/Weapons.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Weapons.h rename to Runtime/Audio/SFX/Weapons.h diff --git a/DataSpec/DNAMP1/SFX/ZZZ.h b/Runtime/Audio/SFX/ZZZ.h similarity index 100% rename from DataSpec/DNAMP1/SFX/ZZZ.h rename to Runtime/Audio/SFX/ZZZ.h diff --git a/DataSpec/DNAMP1/SFX/Zoomer.h b/Runtime/Audio/SFX/Zoomer.h similarity index 100% rename from DataSpec/DNAMP1/SFX/Zoomer.h rename to Runtime/Audio/SFX/Zoomer.h diff --git a/DataSpec/DNAMP1/SFX/lumigek.h b/Runtime/Audio/SFX/lumigek.h similarity index 100% rename from DataSpec/DNAMP1/SFX/lumigek.h rename to Runtime/Audio/SFX/lumigek.h diff --git a/DataSpec/DNAMP1/SFX/test.h b/Runtime/Audio/SFX/test.h similarity index 100% rename from DataSpec/DNAMP1/SFX/test.h rename to Runtime/Audio/SFX/test.h diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index f863f1806..5f33b51de 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -490,7 +490,7 @@ void CAutoMapper::ProcessMapRotateInput(const CFinalInput& input, const CStateMa std::array dirs{}; bool mouseHeld = false; if (const auto& kbm = input.GetKBM()) { - if (kbm->m_mouseButtons[size_t(boo::EMouseButton::Primary)]) { + if (kbm->m_mouseButtons[size_t(EMouseButton::Primary)]) { mouseHeld = true; if (float(m_mouseDelta.x()) < 0.f) dirs[3] = -m_mouseDelta.x(); @@ -662,8 +662,7 @@ void CAutoMapper::ProcessMapPanInput(const CFinalInput& input, const CStateManag bool mouseHeld = false; if (const auto& kbm = input.GetKBM()) { - if (kbm->m_mouseButtons[size_t(boo::EMouseButton::Middle)] || - kbm->m_mouseButtons[size_t(boo::EMouseButton::Secondary)]) { + if (kbm->m_mouseButtons[size_t(EMouseButton::Middle)] || kbm->m_mouseButtons[size_t(EMouseButton::Secondary)]) { mouseHeld = true; if (float(m_mouseDelta.x()) < 0.f) right += -m_mouseDelta.x(); @@ -789,10 +788,10 @@ void CAutoMapper::SetShouldRotatingSoundBePlaying(bool shouldBePlaying) { void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, CStateManager& mgr) { zeus::CMatrix3f camRot = xa8_renderStates[0].x8_camOrientation.toTransform().buildMatrix3f(); if (x1bc_state == EAutoMapperState::MapScreen) { - if ((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter)) && x328_ == 0 && HasCurrentMapUniverseWorld()) + if ((input.PA() || input.PSpecialKey(ESpecialKey::Enter)) && x328_ == 0 && HasCurrentMapUniverseWorld()) BeginMapperStateTransition(EAutoMapperState::MapScreenUniverse, mgr); } else if (x1bc_state == EAutoMapperState::MapScreenUniverse && - (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter))) { + (input.PA() || input.PSpecialKey(ESpecialKey::Enter))) { const CMapUniverse::CMapWorldData& mapuWld = x8_mapu->GetMapWorldData(x9c_worldIdx); zeus::CVector3f pointLocal = mapuWld.GetWorldTransform().inverse() * xa8_renderStates[0].x20_areaPoint; if (mapuWld.GetWorldAssetId() != g_GameState->CurrentWorldAssetId()) { @@ -807,7 +806,7 @@ void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, CStateManager& } x2f4_aButtonPos = 0; - if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter)) + if (input.PA() || input.PSpecialKey(ESpecialKey::Enter)) x2f4_aButtonPos = 1; if (IsInPlayerControlState()) { @@ -821,7 +820,7 @@ void CAutoMapper::ProcessMapScreenInput(const CFinalInput& input, CStateManager& } else { m_mouseDelta = mouseCoord - *m_lastMouseCoord; m_lastMouseCoord.emplace(mouseCoord); - m_mouseDelta.x() *= g_Viewport.aspect; + m_mouseDelta.x() *= CGraphics::GetViewportAspect(); m_mouseDelta *= 100.f; } } @@ -902,14 +901,14 @@ std::pair CAutoMapper::FindClosestVisibleWorld(const zeus::CVector3f& } zeus::CVector2i CAutoMapper::GetMiniMapViewportSize() { - float scaleX = g_Viewport.x8_width / 640.f; - float scaleY = g_Viewport.xc_height / 480.f; + float scaleX = CGraphics::GetViewportWidth() / 640.f; + float scaleY = CGraphics::GetViewportHeight() / 480.f; return {int(scaleX * g_tweakAutoMapper->GetMiniMapViewportWidth()), int(scaleY * g_tweakAutoMapper->GetMiniMapViewportHeight())}; } zeus::CVector2i CAutoMapper::GetMapScreenViewportSize() { - return {int(g_Viewport.x8_width), int(g_Viewport.xc_height)}; + return {int(CGraphics::GetViewportWidth()), int(CGraphics::GetViewportHeight())}; } float CAutoMapper::GetMapAreaMaxDrawDepth(const CStateManager&, TAreaId aid) const { @@ -1084,7 +1083,8 @@ void CAutoMapper::ProcessControllerInput(const CFinalInput& input, CStateManager } } - if (input.PZ() || input.PKey('\t') || input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) { + if (input.PZ() || input.PSpecialKey(ESpecialKey::Tab) || input.PB() || + input.PSpecialKey(ESpecialKey::Esc)) { if (x328_ == 0) { if (CanLeaveMapScreenInternal(mgr)) { LeaveMapScreen(mgr); @@ -1170,7 +1170,7 @@ void CAutoMapper::Update(float dt, CStateManager& mgr) { x320_bottomPanePos = std::max(0.f, std::min(x320_bottomPanePos, 1.f)); if (x30c_basewidget_leftPane) { - float vpAspectRatio = std::max(1.78f, g_Viewport.aspect); + float vpAspectRatio = std::max(1.78f, CGraphics::GetViewportAspect()); x30c_basewidget_leftPane->SetLocalTransform( zeus::CTransform::Translate(x318_leftPanePos * vpAspectRatio * -9.f, 0.f, 0.f) * x30c_basewidget_leftPane->GetTransform()); @@ -1444,23 +1444,23 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo zeus::CColor modColor = g_tweakAutoMapper->GetMiniMapSamusModColor(); modColor.a() *= colorAlpha; CModelFlags flags(5, 0, 8 | 1, modColor); /* Depth GEqual */ - flags.m_extendedShader = EExtendedShader::DepthGEqualNoZWrite; + // flags.m_extendedShader = EExtendedShader::DepthGEqualNoZWrite; x30_miniMapSamus->Draw(flags); } if (IsInMapperState(EAutoMapperState::MapScreen)) { CAssetId wldMlvl = x24_world->IGetWorldAssetId(); const CMapWorld* mw = x24_world->IGetMapWorld(); - std::vector& hintBeaconFilters = m_hintBeaconFilters; - if (hintBeaconFilters.size() < x1f8_hintLocations.size()) { - hintBeaconFilters.reserve(x1f8_hintLocations.size()); - for (u32 i = hintBeaconFilters.size(); i < x1f8_hintLocations.size(); ++i) - hintBeaconFilters.emplace_back(EFilterType::Add, x3c_hintBeacon); - } +// std::vector& hintBeaconFilters = m_hintBeaconFilters; +// if (hintBeaconFilters.size() < x1f8_hintLocations.size()) { +// hintBeaconFilters.reserve(x1f8_hintLocations.size()); +// for (u32 i = hintBeaconFilters.size(); i < x1f8_hintLocations.size(); ++i) +// hintBeaconFilters.emplace_back(EFilterType::Add, x3c_hintBeacon); +// } auto locIt = x1f8_hintLocations.cbegin(); - auto filterIt = hintBeaconFilters.begin(); - for (; locIt != x1f8_hintLocations.cend(); ++locIt, ++filterIt) { +// auto filterIt = hintBeaconFilters.begin(); + for (; locIt != x1f8_hintLocations.cend(); ++locIt/*, ++filterIt*/) { const SAutoMapperHintLocation& loc = *locIt; - CTexturedQuadFilter& filter = *filterIt; +// CTexturedQuadFilter& filter = *filterIt; if (loc.x8_worldId != wldMlvl) continue; const CMapArea* mapa = mw->GetMapArea(loc.xc_areaId); @@ -1475,12 +1475,12 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo beaconAlpha = loc.x4_beaconAlpha; } if (beaconAlpha > 0.f) { - constexpr std::array verts{{ - {{-4.f, -8.f, 8.f}, {0.f, 1.f}}, - {{-4.f, -8.f, 0.f}, {0.f, 0.f}}, - {{4.f, -8.f, 8.f}, {1.f, 1.f}}, - {{4.f, -8.f, 0.f}, {1.f, 0.f}}, - }}; +// constexpr std::array verts{{ +// {{-4.f, -8.f, 8.f}, {0.f, 1.f}}, +// {{-4.f, -8.f, 0.f}, {0.f, 0.f}}, +// {{4.f, -8.f, 8.f}, {1.f, 1.f}}, +// {{4.f, -8.f, 0.f}, {1.f, 0.f}}, +// }}; float colorAlpha = beaconAlpha; if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) { } else { @@ -1489,7 +1489,8 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo colorAlpha *= mapAlpha; zeus::CColor color = zeus::skWhite; color.a() = colorAlpha; - filter.drawVerts(color, verts); + // TODO +// filter.drawVerts(color, verts); } } } @@ -1604,7 +1605,7 @@ CAssetId CAutoMapper::GetAreaHintDescriptionString(CAssetId mreaId) { } } } - return -1; + return {}; } void CAutoMapper::OnNewInGameGuiState(EInGameGuiState state, CStateManager& mgr) { diff --git a/Runtime/AutoMapper/CAutoMapper.hpp b/Runtime/AutoMapper/CAutoMapper.hpp index c564518a2..3b3685117 100644 --- a/Runtime/AutoMapper/CAutoMapper.hpp +++ b/Runtime/AutoMapper/CAutoMapper.hpp @@ -108,11 +108,11 @@ public: SAutoMapperHintStep(PanToArea, TAreaId areaId) : x0_type(Type::PanToArea), x4_areaId(areaId) {} SAutoMapperHintStep(PanToWorld, CAssetId worldId) : x0_type(Type::PanToWorld), x4_worldId(worldId) {} - SAutoMapperHintStep(SwitchToUniverse) : x0_type(Type::SwitchToUniverse), x4_worldId(0) {} + SAutoMapperHintStep(SwitchToUniverse) : x0_type(Type::SwitchToUniverse), x4_worldId(CAssetId()) {} SAutoMapperHintStep(SwitchToWorld, CAssetId worldId) : x0_type(Type::SwitchToWorld), x4_worldId(worldId) {} SAutoMapperHintStep(ShowBeacon, float val) : x0_type(Type::ShowBeacon), x4_float(val) {} - SAutoMapperHintStep(ZoomIn) : x0_type(Type::ZoomIn), x4_worldId(0) {} - SAutoMapperHintStep(ZoomOut) : x0_type(Type::ZoomOut), x4_worldId(0) {} + SAutoMapperHintStep(ZoomIn) : x0_type(Type::ZoomIn), x4_worldId(CAssetId()) {} + SAutoMapperHintStep(ZoomOut) : x0_type(Type::ZoomOut), x4_worldId(CAssetId()) {} }; struct SAutoMapperHintLocation { @@ -133,7 +133,6 @@ private: bool m_frmeInitialized = false; TLockedToken x30_miniMapSamus; TLockedToken x3c_hintBeacon; - std::vector m_hintBeaconFilters; rstl::reserved_vector, 5> x48_mapIcons; CAssetId x74_areaHintDescId; TLockedToken x78_areaHintDesc; @@ -181,8 +180,8 @@ private: std::optional m_lastMouseCoord; zeus::CVector2f m_mouseDelta; - boo::SScrollDelta m_lastAccumScroll; - boo::SScrollDelta m_mapScroll; + SScrollDelta m_lastAccumScroll; + SScrollDelta m_mapScroll; template static void SetResLockState(T& list, bool lock) { diff --git a/Runtime/AutoMapper/CMapArea.cpp b/Runtime/AutoMapper/CMapArea.cpp index 99362316f..7fd5283b2 100644 --- a/Runtime/AutoMapper/CMapArea.cpp +++ b/Runtime/AutoMapper/CMapArea.cpp @@ -3,12 +3,11 @@ #include #include -#include "Runtime/CResFactory.hpp" +#include "Runtime/AutoMapper/CMappableObject.hpp" #include "Runtime/CToken.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/AutoMapper/CMappableObject.hpp" -#include "Runtime/World/CGameArea.hpp" #include "Runtime/World/CWorld.hpp" +#include "Runtime/CBasics.hpp" namespace metaforce { constexpr std::array MinesPostTransforms{{ @@ -63,17 +62,17 @@ constexpr std::array MinesPostTransformIndices{ }; CMapArea::CMapArea(CInputStream& in, u32 size) -: x0_magic(in.readUint32()) -, x4_version(in.readUint32Big()) -, x8_(in.readUint32Big()) -, xc_visibilityMode(EVisMode(in.readUint32Big())) -, x10_box(zeus::CAABox::ReadBoundingBoxBig(in)) -, x28_mappableObjCount(in.readUint32Big()) -, x2c_vertexCount(in.readUint32Big()) -, x30_surfaceCount(in.readUint32Big()) +: x0_magic(in.ReadLong()) +, x4_version(in.ReadLong()) +, x8_(in.ReadLong()) +, xc_visibilityMode(EVisMode(in.ReadLong())) +, x10_box(in.Get()) +, x28_mappableObjCount(in.ReadLong()) +, x2c_vertexCount(in.ReadLong()) +, x30_surfaceCount(in.ReadLong()) , x34_size(size - 52) { x44_buf.reset(new u8[x34_size]); - in.readUBytesToBuf(x44_buf.get(), x34_size); + in.ReadBytes(x44_buf.get(), x34_size); PostConstruct(); } @@ -98,7 +97,7 @@ void CMapArea::PostConstruct() { float z; std::memcpy(&z, tmp + 8, sizeof(float)); - m_verts.emplace_back(hecl::SBig(x), hecl::SBig(y), hecl::SBig(z)); + m_verts.emplace_back(CBasics::SwapBytes(x), CBasics::SwapBytes(y), CBasics::SwapBytes(z)); tmp += 12; } @@ -108,43 +107,43 @@ void CMapArea::PostConstruct() { m_surfaces.emplace_back(x40_surfaceStart + j).PostConstruct(x44_buf.get(), index); } - CGraphics::CommitResources([this, &index](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size()); - m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size()); - - /* Only the map universe specifies Always; it draws a maximum of 1016 instances */ - size_t instCount = (xc_visibilityMode == EVisMode::Always) ? 1024 : 1; - - for (u32 i = 0; i < x30_surfaceCount; ++i) { - CMapAreaSurface& surf = m_surfaces[i]; - surf.m_instances.reserve(instCount); - for (u32 inst = 0; inst < instCount; ++inst) { - CMapAreaSurface::Instance& instance = surf.m_instances.emplace_back(ctx, m_vbo, m_ibo); - - athena::io::MemoryReader r(surf.x1c_outlineOffset, INT_MAX); - u32 outlineCount = r.readUint32Big(); - - std::vector& linePrims = instance.m_linePrims; - linePrims.reserve(outlineCount * 2); - for (u32 j = 0; j < 2; ++j) { - r.seek(4, athena::SeekOrigin::Begin); - for (u32 k = 0; k < outlineCount; ++k) { - const u32 count = r.readUint32Big(); - r.seek(count); - r.seekAlign4(); - linePrims.emplace_back(ctx, CLineRenderer::EPrimitiveMode::LineStrip, count, nullptr, false, false, true); - } - } - } - } - - for (u32 i = 0; i < x28_mappableObjCount; ++i) { - CMappableObject& mapObj = m_mappableObjects[i]; - if (CMappableObject::IsDoorType(mapObj.GetType())) - mapObj.CreateDoorSurface(ctx); - } - return true; - } BooTrace); +// CGraphics::CommitResources([this, &index](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size()); +// m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size()); +// +// /* Only the map universe specifies Always; it draws a maximum of 1016 instances */ +// size_t instCount = (xc_visibilityMode == EVisMode::Always) ? 1024 : 1; +// +// for (u32 i = 0; i < x30_surfaceCount; ++i) { +// CMapAreaSurface& surf = m_surfaces[i]; +// surf.m_instances.reserve(instCount); +// for (u32 inst = 0; inst < instCount; ++inst) { +// CMapAreaSurface::Instance& instance = surf.m_instances.emplace_back(ctx, m_vbo, m_ibo); +// +// athena::io::MemoryReader r(surf.x1c_outlineOffset, INT_MAX); +// u32 outlineCount = r.ReadLong(); +// +// std::vector& linePrims = instance.m_linePrims; +// linePrims.reserve(outlineCount * 2); +// for (u32 j = 0; j < 2; ++j) { +// r.seek(4, athena::SeekOrigin::Begin); +// for (u32 k = 0; k < outlineCount; ++k) { +// const u32 count = r.ReadLong(); +// r.seek(count); +// r.seekAlign4(); +// linePrims.emplace_back(ctx, CLineRenderer::EPrimitiveMode::LineStrip, count, nullptr, false, false, true); +// } +// } +// } +// } +// +// for (u32 i = 0; i < x28_mappableObjCount; ++i) { +// CMappableObject& mapObj = m_mappableObjects[i]; +// if (CMappableObject::IsDoorType(mapObj.GetType())) +// mapObj.CreateDoorSurface(ctx); +// } +// return true; +// } BooTrace); } bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const { @@ -181,11 +180,11 @@ const zeus::CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TArea } CMapArea::CMapAreaSurface::CMapAreaSurface(const void* surfBuf) { - athena::io::MemoryReader r(surfBuf, 32); - x0_normal = r.readVec3fBig(); - xc_centroid = r.readVec3fBig(); - x18_surfOffset = reinterpret_cast(uintptr_t(r.readUint32Big())); - x1c_outlineOffset = reinterpret_cast(uintptr_t(r.readUint32Big())); + CMemoryInStream r(surfBuf, 32, CMemoryInStream::EOwnerShip::NotOwned); + x0_normal = r.Get(); + xc_centroid = r.Get(); + x18_surfOffset = reinterpret_cast(uintptr_t(r.ReadLong())); + x1c_outlineOffset = reinterpret_cast(uintptr_t(r.ReadLong())); } void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& index) { @@ -195,63 +194,66 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& i m_primStart = index.size(); bool start = true; { - athena::io::MemoryReader r(x18_surfOffset, INT_MAX); - u32 primCount = r.readUint32Big(); + CMemoryInStream r(x18_surfOffset, INT_MAX, CMemoryInStream::EOwnerShip::NotOwned); + u32 primCount = r.ReadLong(); for (u32 i = 0; i < primCount; ++i) { - GX::Primitive prim = GX::Primitive(r.readUint32Big()); - u32 count = r.readUint32Big(); + GXPrimitive prim = GXPrimitive(r.ReadLong()); + u32 count = r.ReadLong(); switch (prim) { - case GX::Primitive::TRIANGLES: { + case GX_TRIANGLES: { for (u32 v = 0; v < count; v += 3) { if (!start) { index.push_back(index.back()); - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); index.push_back(index.back()); } else { - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); start = false; } - index.push_back(r.readUByte()); - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); + index.push_back(r.ReadUint8()); index.push_back(index.back()); } break; } - case GX::Primitive::TRIANGLESTRIP: { + case GX_TRIANGLESTRIP: { if (!start) { index.push_back(index.back()); - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); index.push_back(index.back()); } else { - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); start = false; } for (u32 v = 1; v < count; ++v) - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); if (count & 1) index.push_back(index.back()); break; } - case GX::Primitive::TRIANGLEFAN: { - u8 firstVert = r.readUByte(); + case GX_TRIANGLEFAN: { + u8 firstVert = r.ReadUint8(); if (!start) { index.push_back(index.back()); - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); } else { - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); index.push_back(index.back()); start = false; } for (u32 v = 1; v < count; ++v) { index.push_back(firstVert); - index.push_back(r.readUByte()); + index.push_back(r.ReadUint8()); } break; } default: break; } - r.seekAlign4(); + u32 pos = r.GetReadPosition(); + while (r.GetReadPosition() != ROUND_UP_4(pos)) { + r.ReadUint8(); + } } } m_primCount = index.size() - m_primStart; @@ -271,8 +273,10 @@ void CMapArea::CMapAreaSurface::Draw(const zeus::CVector3f* verts, const zeus::C if (lineColor.a()) { bool draw2 = lineWidth > 1.f; - athena::io::MemoryReader r(x1c_outlineOffset, INT_MAX); - u32 outlineCount = r.readUint32Big(); + u32 outlineCount = *reinterpret_cast(x1c_outlineOffset); +#if METAFORCE_TARGET_BYTE_ORDER == __ORDER_LITTLE_ENDIAN__ + outlineCount = CBasics::SwapBytes(outlineCount); +#endif std::vector& linePrims = instance.m_linePrims; zeus::CColor color = lineColor; @@ -282,16 +286,21 @@ void CMapArea::CMapAreaSurface::Draw(const zeus::CVector3f* verts, const zeus::C auto primIt = linePrims.begin(); for (u32 j = 0; j <= u32(draw2); ++j) { - r.seek(4, athena::SeekOrigin::Begin); + CMemoryInStream r(x1c_outlineOffset, INT_MAX, CMemoryInStream::EOwnerShip::NotOwned); + r.ReadLong(); for (u32 i = 0; i < outlineCount; ++i) { CLineRenderer& prim = *primIt++; prim.Reset(); - u32 count = r.readUint32Big(); + u32 count = r.ReadLong(); for (u32 v = 0; v < count; ++v) { - u8 idx = r.readUByte(); + u8 idx = r.ReadUint8(); prim.AddVertex(verts[idx], color, width); } - r.seekAlign4(); + + u32 pos = r.GetReadPosition(); + while (r.GetReadPosition() != ROUND_UP_4(pos)) { + r.ReadUint8(); + } prim.Render(); } width -= 1.f; diff --git a/Runtime/AutoMapper/CMapArea.hpp b/Runtime/AutoMapper/CMapArea.hpp index d426c5301..642ad0b97 100644 --- a/Runtime/AutoMapper/CMapArea.hpp +++ b/Runtime/AutoMapper/CMapArea.hpp @@ -3,13 +3,11 @@ #include #include -#include "Runtime/CResFactory.hpp" -#include "Runtime/RetroTypes.hpp" #include "Runtime/AutoMapper/CMappableObject.hpp" +#include "Runtime/CResFactory.hpp" #include "Runtime/Graphics/CLineRenderer.hpp" #include "Runtime/Graphics/Shaders/CMapSurfaceShader.hpp" - -#include +#include "Runtime/RetroTypes.hpp" #include #include @@ -29,9 +27,9 @@ public: struct Instance { CMapSurfaceShader m_surfacePrims; std::vector m_linePrims; - Instance(boo::IGraphicsDataFactory::Context& ctx, const boo::ObjToken& vbo, - const boo::ObjToken& ibo) - : m_surfacePrims(ctx, vbo, ibo) {} + Instance(std::vector vbo, + std::vector ibo) + : m_surfacePrims(vbo, ibo) {} Instance(Instance&&) = default; Instance& operator=(Instance&&) = default; }; @@ -65,8 +63,8 @@ private: u8* x40_surfaceStart; std::vector m_surfaces; std::unique_ptr x44_buf; - boo::ObjToken m_vbo; - boo::ObjToken m_ibo; +// boo::ObjToken m_vbo; +// boo::ObjToken m_ibo; public: explicit CMapArea(CInputStream& in, u32 size); diff --git a/Runtime/AutoMapper/CMapUniverse.cpp b/Runtime/AutoMapper/CMapUniverse.cpp index 84f68f034..329738b06 100644 --- a/Runtime/AutoMapper/CMapUniverse.cpp +++ b/Runtime/AutoMapper/CMapUniverse.cpp @@ -6,25 +6,25 @@ namespace metaforce { -CMapUniverse::CMapUniverse(CInputStream& in, u32 version) : x0_hexagonId(in.readUint32Big()) { +CMapUniverse::CMapUniverse(CInputStream& in, u32 version) : x0_hexagonId(in.Get()) { x4_hexagonToken = g_SimplePool->GetObj({FOURCC('MAPA'), x0_hexagonId}); - u32 count = in.readUint32Big(); + u32 count = in.ReadLong(); x10_worldDatas.reserve(count); for (u32 i = 0; i < count; ++i) x10_worldDatas.emplace_back(in, version); } CMapUniverse::CMapWorldData::CMapWorldData(CInputStream& in, u32 version) -: x0_label(in.readString()), x10_worldAssetId(in.readUint32Big()) { - x14_transform.read34RowMajor(in); - const u32 worldCount = in.readUint32Big(); +: x0_label(in.Get()), x10_worldAssetId(in) { + x14_transform = in.Get(); + const u32 worldCount = in.ReadLong(); x44_hexagonXfs.reserve(worldCount); for (u32 i = 0; i < worldCount; ++i) { - x44_hexagonXfs.emplace_back().read34RowMajor(in); + x44_hexagonXfs.emplace_back() = in.Get(); } if (version != 0) - x54_surfColorSelected.readRGBABig(in); + x54_surfColorSelected = in.Get(); else x54_surfColorSelected.fromRGBA32(255 | (u32(x10_worldAssetId.Value()) & 0xFFFFFF00)); @@ -115,8 +115,8 @@ void CMapUniverse::Draw(const CMapUniverseDrawParms& parms, const zeus::CVector3 } CFactoryFnReturn FMapUniverseFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&, CObjectReference*) { - in.readUint32Big(); - u32 version = in.readUint32Big(); + in.ReadLong(); + u32 version = in.ReadLong(); return TToken::GetIObjObjectFor(std::make_unique(in, version)); } diff --git a/Runtime/AutoMapper/CMapWorld.cpp b/Runtime/AutoMapper/CMapWorld.cpp index 2b3711bcd..612e15fd0 100644 --- a/Runtime/AutoMapper/CMapWorld.cpp +++ b/Runtime/AutoMapper/CMapWorld.cpp @@ -274,13 +274,13 @@ CMapWorld::CMapAreaData::CMapAreaData(CAssetId areaRes, EMapAreaList list, CMapA CMapWorld::CMapWorld(CInputStream& in) { x10_listHeads.resize(3); - in.readUint32Big(); - in.readUint32Big(); - u32 areaCount = in.readUint32Big(); + in.ReadLong(); + in.ReadLong(); + u32 areaCount = in.ReadLong(); x0_areas.reserve(areaCount); x20_traversed.resize(areaCount); for (u32 i = 0; i < areaCount; ++i) { - CAssetId mapaId = in.readUint32Big(); + CAssetId mapaId = in.Get(); x0_areas.emplace_back(mapaId, EMapAreaList::Unloaded, x0_areas.empty() ? nullptr : &x0_areas.back()); } x10_listHeads[2] = &x0_areas.back(); diff --git a/Runtime/AutoMapper/CMapWorldInfo.cpp b/Runtime/AutoMapper/CMapWorldInfo.cpp index 926259c6a..dfc4b5b2f 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.cpp +++ b/Runtime/AutoMapper/CMapWorldInfo.cpp @@ -5,52 +5,52 @@ namespace metaforce { -CMapWorldInfo::CMapWorldInfo(CBitStreamReader& reader, const CWorldSaveGameInfo& savw, CAssetId mlvlId) { +CMapWorldInfo::CMapWorldInfo(CInputStream& reader, const CWorldSaveGameInfo& savw, CAssetId mlvlId) { const CSaveWorldMemory& worldMem = g_MemoryCardSys->GetSaveWorldMemory(mlvlId); x4_visitedAreas.reserve((worldMem.GetAreaCount() + 31) / 32); for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { - const bool visited = reader.ReadEncoded(1) != 0; + const bool visited = reader.ReadBits(1) != 0; SetAreaVisited(i, visited); } x18_mappedAreas.reserve((worldMem.GetAreaCount() + 31) / 32); for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { - const bool mapped = reader.ReadEncoded(1) != 0; + const bool mapped = reader.ReadBits(1) != 0; SetIsMapped(i, mapped); } for (const auto& doorId : savw.GetDoors()) { - SetDoorVisited(doorId, reader.ReadEncoded(1) != 0); + SetDoorVisited(doorId, reader.ReadBits(1) != 0); } - x38_mapStationUsed = reader.ReadEncoded(1) != 0; + x38_mapStationUsed = reader.ReadBits(1) != 0; } -void CMapWorldInfo::PutTo(CBitStreamWriter& writer, const CWorldSaveGameInfo& savw, CAssetId mlvlId) const { +void CMapWorldInfo::PutTo(COutputStream& writer, const CWorldSaveGameInfo& savw, CAssetId mlvlId) const { const CSaveWorldMemory& worldMem = g_MemoryCardSys->GetSaveWorldMemory(mlvlId); for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { if (i < x0_visitedAreasAllocated) { - writer.WriteEncoded(u32(IsAreaVisited(i)), 1); + writer.WriteBits(u32(IsAreaVisited(i)), 1); } else { - writer.WriteEncoded(0, 1); + writer.WriteBits(0, 1); } } for (u32 i = 0; i < worldMem.GetAreaCount(); ++i) { if (i < x14_mappedAreasAllocated) { - writer.WriteEncoded(u32(IsMapped(i)), 1); + writer.WriteBits(u32(IsMapped(i)), 1); } else { - writer.WriteEncoded(0, 1); + writer.WriteBits(0, 1); } } for (const auto& doorId : savw.GetDoors()) { - writer.WriteEncoded(u32(IsDoorVisited(doorId)), 1); + writer.WriteBits(u32(IsDoorVisited(doorId)), 1); } - writer.WriteEncoded(u32(x38_mapStationUsed), 1); + writer.WriteBits(u32(x38_mapStationUsed), 1); } void CMapWorldInfo::SetDoorVisited(TEditorId eid, bool visited) { x28_visitedDoors[eid] = visited; } diff --git a/Runtime/AutoMapper/CMapWorldInfo.hpp b/Runtime/AutoMapper/CMapWorldInfo.hpp index 65dd5aaff..7e6fdf614 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.hpp +++ b/Runtime/AutoMapper/CMapWorldInfo.hpp @@ -3,7 +3,8 @@ #include #include -#include "Runtime/RetroTypes.hpp" +#include "RetroTypes.hpp" +#include "Runtime/Streams/IOStreams.hpp" namespace metaforce { class CWorldSaveGameInfo; @@ -18,8 +19,8 @@ class CMapWorldInfo { public: CMapWorldInfo() = default; - explicit CMapWorldInfo(CBitStreamReader& reader, const CWorldSaveGameInfo& saveWorld, CAssetId mlvlId); - void PutTo(CBitStreamWriter& writer, const CWorldSaveGameInfo& savw, CAssetId mlvlId) const; + explicit CMapWorldInfo(CInputStream& reader, const CWorldSaveGameInfo& saveWorld, CAssetId mlvlId); + void PutTo(COutputStream& writer, const CWorldSaveGameInfo& savw, CAssetId mlvlId) const; bool IsMapped(TAreaId aid) const; void SetIsMapped(TAreaId aid, bool mapped); void SetDoorVisited(TEditorId eid, bool val); diff --git a/Runtime/AutoMapper/CMappableObject.cpp b/Runtime/AutoMapper/CMappableObject.cpp index 48b55b92b..509dd14f7 100644 --- a/Runtime/AutoMapper/CMappableObject.cpp +++ b/Runtime/AutoMapper/CMappableObject.cpp @@ -1,8 +1,8 @@ #include "Runtime/AutoMapper/CMappableObject.hpp" +#include "Runtime/AutoMapper/CMapWorldInfo.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/CToken.hpp" -#include "Runtime/AutoMapper/CMapWorldInfo.hpp" #include "Runtime/Camera/CCameraFilter.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Graphics/CTexture.hpp" @@ -10,17 +10,17 @@ namespace metaforce { std::array CMappableObject::skDoorVerts{}; -constexpr std::array DoorIndices{ +std::array CMappableObject::skDoorIndices{ 6, 4, 2, 0, 3, 1, 7, 5, 1, 0, 5, 4, 7, 6, 3, 2, 3, 2, 1, 0, 5, 4, 7, 6, }; CMappableObject::CMappableObject(const void* buf) { - athena::io::MemoryReader r(buf, 64); - x0_type = EMappableObjectType(r.readUint32Big()); - x4_visibilityMode = EVisMode(r.readUint32Big()); - x8_objId = r.readUint32Big(); - xc_ = r.readUint32Big(); - x10_transform.read34RowMajor(r); + CMemoryInStream r(buf, 64); + x0_type = EMappableObjectType(r.ReadLong()); + x4_visibilityMode = EVisMode(r.ReadLong()); + x8_objId = r.ReadLong(); + xc_ = r.ReadLong(); + x10_transform = r.Get(); } zeus::CTransform CMappableObject::AdjustTransformForType() const { @@ -112,18 +112,19 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha SCOPED_GRAPHICS_DEBUG_GROUP("CMappableObject::Draw", zeus::skCyan); if (IsDoorType(x0_type)) { std::pair colors = GetDoorColors(curArea, mwInfo, alpha); - for (int s = 0; s < 6; ++s) { - DoorSurface& ds = *m_doorSurface; - ds.m_surface.draw(colors.first, s * 4, 4); - CLineRenderer& line = ds.m_outline; - const u32* baseIdx = &DoorIndices[s * 4]; - line.Reset(); - line.AddVertex(skDoorVerts[baseIdx[0]], colors.second, 1.f); - line.AddVertex(skDoorVerts[baseIdx[1]], colors.second, 1.f); - line.AddVertex(skDoorVerts[baseIdx[3]], colors.second, 1.f); - line.AddVertex(skDoorVerts[baseIdx[2]], colors.second, 1.f); - line.Render(); - } + // TODO +// for (int s = 0; s < 6; ++s) { +// DoorSurface& ds = *m_doorSurface; +// ds.m_surface.draw(colors.first, s * 4, 4); +// CLineRenderer& line = ds.m_outline; +// const u16* baseIdx = &skDoorIndices[s * 4]; +// line.Reset(); +// line.AddVertex(skDoorVerts[baseIdx[0]], colors.second, 1.f); +// line.AddVertex(skDoorVerts[baseIdx[1]], colors.second, 1.f); +// line.AddVertex(skDoorVerts[baseIdx[3]], colors.second, 1.f); +// line.AddVertex(skDoorVerts[baseIdx[2]], colors.second, 1.f); +// line.Render(); +// } } else { CAssetId iconRes; zeus::CColor iconColor = zeus::skWhite; @@ -166,33 +167,33 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo, float alpha iconColor.a() *= alpha; TLockedToken tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), iconRes}); - if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj()) { - m_texQuadFilter.emplace(EFilterType::Add, tex, CTexturedQuadFilter::ZTest::GEqual); - } +// if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj()) { + //m_texQuadFilter.emplace(EFilterType::Add, tex, CTexturedQuadFilter::ZTest::GEqual); +// } - constexpr std::array verts{{ - {{-2.6f, 0.f, 2.6f}, {0.f, 1.f}}, - {{-2.6f, 0.f, -2.6f}, {0.f, 0.f}}, - {{2.6f, 0.f, 2.6f}, {1.f, 1.f}}, - {{2.6f, 0.f, -2.6f}, {1.f, 0.f}}, - }}; - m_texQuadFilter->drawVerts(iconColor, verts); +// constexpr std::array verts{{ +// {{-2.6f, 0.f, 2.6f}, {0.f, 1.f}}, +// {{-2.6f, 0.f, -2.6f}, {0.f, 0.f}}, +// {{2.6f, 0.f, 2.6f}, {1.f, 1.f}}, +// {{2.6f, 0.f, -2.6f}, {1.f, 0.f}}, +// }}; + //m_texQuadFilter->drawVerts(iconColor, verts); } } void CMappableObject::DrawDoorSurface(int curArea, const CMapWorldInfo& mwInfo, float alpha, int surfIdx, bool needsVtxLoad) { std::pair colors = GetDoorColors(curArea, mwInfo, alpha); - DoorSurface& ds = *m_doorSurface; - ds.m_surface.draw(colors.first, surfIdx * 4, 4); - CLineRenderer& line = ds.m_outline; - const u32* baseIdx = &DoorIndices[surfIdx * 4]; - line.Reset(); - line.AddVertex(skDoorVerts[baseIdx[0]], colors.second, 1.f); - line.AddVertex(skDoorVerts[baseIdx[1]], colors.second, 1.f); - line.AddVertex(skDoorVerts[baseIdx[3]], colors.second, 1.f); - line.AddVertex(skDoorVerts[baseIdx[2]], colors.second, 1.f); - line.Render(); +// DoorSurface& ds = *m_doorSurface; +// ds.m_surface.draw(colors.first, surfIdx * 4, 4); +// CLineRenderer& line = ds.m_outline; +// const u16* baseIdx = &skDoorIndices[surfIdx * 4]; +// line.Reset(); +// line.AddVertex(skDoorVerts[baseIdx[0]], colors.second, 1.f); +// line.AddVertex(skDoorVerts[baseIdx[1]], colors.second, 1.f); +// line.AddVertex(skDoorVerts[baseIdx[3]], colors.second, 1.f); +// line.AddVertex(skDoorVerts[baseIdx[2]], colors.second, 1.f); +// line.Render(); } zeus::CVector3f CMappableObject::BuildSurfaceCenterPoint(int surfIdx) const { @@ -236,9 +237,6 @@ bool CMappableObject::IsVisibleToAutoMapper(bool worldVis, const CMapWorldInfo& } } -boo::ObjToken CMappableObject::g_doorVbo; -boo::ObjToken CMappableObject::g_doorIbo; - void CMappableObject::ReadAutoMapperTweaks(const ITweakAutoMapper& tweaks) { const zeus::CVector3f& center = tweaks.GetDoorCenter(); const zeus::simd_floats centerF(center.mSimd); @@ -254,15 +252,15 @@ void CMappableObject::ReadAutoMapperTweaks(const ITweakAutoMapper& tweaks) { doorVerts[6].assign(.2f * -centerF[2], centerF[1], 0.f); doorVerts[7].assign(.2f * -centerF[2], centerF[1], 2.f * centerF[0]); - CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx) { - g_doorVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, skDoorVerts.data(), 16, skDoorVerts.size()); - g_doorIbo = ctx.newStaticBuffer(boo::BufferUse::Index, DoorIndices.data(), 4, DoorIndices.size()); - return true; - } BooTrace); +// CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx) { +// g_doorVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, skDoorVerts.data(), 16, skDoorVerts.size()); +// g_doorIbo = ctx.newStaticBuffer(boo::BufferUse::Index, DoorIndices.data(), 4, DoorIndices.size()); +// return true; +// } BooTrace); } void CMappableObject::Shutdown() { - g_doorVbo.reset(); - g_doorIbo.reset(); +// g_doorVbo.reset(); +// g_doorIbo.reset(); } } // namespace metaforce diff --git a/Runtime/AutoMapper/CMappableObject.hpp b/Runtime/AutoMapper/CMappableObject.hpp index fd0b2df27..675e440a5 100644 --- a/Runtime/AutoMapper/CMappableObject.hpp +++ b/Runtime/AutoMapper/CMappableObject.hpp @@ -5,10 +5,9 @@ #include #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/RetroTypes.hpp" #include "Runtime/Graphics/CLineRenderer.hpp" #include "Runtime/Graphics/Shaders/CMapSurfaceShader.hpp" -#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" +#include "Runtime/RetroTypes.hpp" #include #include @@ -18,9 +17,6 @@ class CMapWorldInfo; class CStateManager; class CMappableObject { - static boo::ObjToken g_doorVbo; - static boo::ObjToken g_doorIbo; - public: enum class EMappableObjectType { BlueDoor = 0, @@ -54,6 +50,7 @@ public: private: static std::array skDoorVerts; + static std::array skDoorIndices; EMappableObjectType x0_type; EVisMode x4_visibilityMode; @@ -61,15 +58,14 @@ private: u32 xc_; zeus::CTransform x10_transform; - struct DoorSurface { - CMapSurfaceShader m_surface; - CLineRenderer m_outline; - explicit DoorSurface(boo::IGraphicsDataFactory::Context& ctx) - : m_surface(ctx, g_doorVbo, g_doorIbo) - , m_outline(ctx, CLineRenderer::EPrimitiveMode::LineLoop, 5, nullptr, false, false, true) {} - }; - std::optional m_doorSurface; - std::optional m_texQuadFilter; +// struct DoorSurface { +// CMapSurfaceShader m_surface; +// CLineRenderer m_outline; +// explicit DoorSurface() +// : m_surface(skDoorVerts, skDoorIndices) +// , m_outline(CLineRenderer::EPrimitiveMode::LineLoop, 5, {}, false, false, true) {} +// }; +// std::optional m_doorSurface; zeus::CTransform AdjustTransformForType() const; std::pair GetDoorColors(int idx, const CMapWorldInfo& mwInfo, float alpha) const; @@ -87,7 +83,7 @@ public: bool IsDoorConnectedToVisitedArea(const CStateManager&) const; bool IsVisibleToAutoMapper(bool worldVis, const CMapWorldInfo& mwInfo) const; bool GetIsSeen() const; - void CreateDoorSurface(boo::IGraphicsDataFactory::Context& ctx) { m_doorSurface.emplace(ctx); } +// void CreateDoorSurface() { m_doorSurface.emplace(); } static void ReadAutoMapperTweaks(const ITweakAutoMapper&); static bool GetTweakIsMapVisibilityCheat(); diff --git a/Runtime/CBasics.hpp b/Runtime/CBasics.hpp index 7e761fea0..508361231 100644 --- a/Runtime/CBasics.hpp +++ b/Runtime/CBasics.hpp @@ -1,8 +1,15 @@ #pragma once +#include #include #include -#include +#include +#include +#ifndef _WIN32 +#include +#else +struct _stat64; +#endif #include "Runtime/GCNTypes.hpp" @@ -26,6 +33,12 @@ struct OSCalendarTime { class CBasics { public: +#if _WIN32 + using Sstat = struct ::_stat64; +#else + using Sstat = struct stat; +#endif + static void Initialize(); static const u64 SECONDS_TO_2000; @@ -40,6 +53,22 @@ public: static OSCalendarTime ToCalendarTime(OSTime time) { return ToCalendarTime(FromWiiTime(time)); } static OSCalendarTime ToCalendarTime(std::chrono::system_clock::time_point time); + static u16 SwapBytes(u16 v); + static u32 SwapBytes(u32 v); + static u64 SwapBytes(u64 v); + static s16 SwapBytes(s16 v); + static s32 SwapBytes(s32 v); + static s64 SwapBytes(s64 v); + static float SwapBytes(float v); + static double SwapBytes(double s); + static void Swap2Bytes(u8* v); + static void Swap4Bytes(u8* v); + static void Swap8Bytes(u8* v); + static int RecursiveMakeDir(const char* dir); + static void MakeDir(const char* dir); + static bool IsDir(const char* path); + static bool IsFile(const char* path); + static int Stat(const char* path, Sstat* statOut); }; } // namespace metaforce diff --git a/Runtime/CBasicsPC.cpp b/Runtime/CBasicsPC.cpp index 36262e260..0d78f70f4 100644 --- a/Runtime/CBasicsPC.cpp +++ b/Runtime/CBasicsPC.cpp @@ -1,22 +1,40 @@ #ifndef _WIN32 -#include #include +#include #if __APPLE__ #include #endif -#else +#endif + +#include +#include +#include +#include +#include +#ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif -#include +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include +#ifndef _WIN32_IE +#define _WIN32_IE 0x0400 +#endif +#include +#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#endif #endif -#include -#include -#include - #include "Runtime/CBasics.hpp" +#include "Runtime/CStopwatch.hpp" + +#include + #if __APPLE__ static u64 MachToDolphinNum; static u64 MachToDolphinDenom; @@ -25,8 +43,9 @@ static LARGE_INTEGER PerfFrequency; #endif namespace metaforce { - +static logvisor::Module LogModule("metaforce::CBasics"); void CBasics::Initialize() { + CStopwatch::InitGlobalTimer(); #if __APPLE__ mach_timebase_info_data_t timebase; mach_timebase_info(&timebase); @@ -136,4 +155,223 @@ OSCalendarTime CBasics::ToCalendarTime(std::chrono::system_clock::time_point tim return ret; } +u16 CBasics::SwapBytes(u16 v) { + Swap2Bytes(reinterpret_cast(&v)); + return v; +} + +u32 CBasics::SwapBytes(u32 v) { + Swap4Bytes(reinterpret_cast(&v)); + return v; +} + +u64 CBasics::SwapBytes(u64 v) { + Swap8Bytes(reinterpret_cast(&v)); + return v; +} + +s16 CBasics::SwapBytes(s16 v) { + Swap2Bytes(reinterpret_cast(&v)); + return v; +} + +s32 CBasics::SwapBytes(s32 v) { + Swap4Bytes(reinterpret_cast(&v)); + return v; +} + +s64 CBasics::SwapBytes(s64 v) { + Swap8Bytes(reinterpret_cast(&v)); + return v; +} + +float CBasics::SwapBytes(float v) { + Swap4Bytes(reinterpret_cast(&v)); + return v; +} + +double CBasics::SwapBytes(double v) { + Swap8Bytes(reinterpret_cast(&v)); + return v; +} + +void CBasics::Swap2Bytes(u8* v) { + u16* val = reinterpret_cast(v); +#if __GNUC__ + *val = __builtin_bswap16(*val); +#elif _WIN32 + *val = _byteswap_ushort(*val); +#else + *val = (*val << 8) | ((*val >> 8) & 0xFF); +#endif +} + +void CBasics::Swap4Bytes(u8* v) { + u32* val = reinterpret_cast(v); +#if __GNUC__ + *val = __builtin_bswap32(*val); +#elif _WIN32 + *val = _byteswap_ulong(*val); +#else + *val = ((*val & 0x0000FFFF) << 16) | ((*val & 0xFFFF0000) >> 16) | ((*val & 0x00FF00FF) << 8) | + ((*val & 0xFF00FF00) >> 8); +#endif +} + +void CBasics::Swap8Bytes(u8* v) { + u64* val = reinterpret_cast(v); +#if __GNUC__ + *val = __builtin_bswap64(*val); +#elif _WIN32 + *val = _byteswap_uint64(*val); +#else + *val = ((val & 0xFF00000000000000ULL) >> 56) | ((val & 0x00FF000000000000ULL) >> 40) | + ((val & 0x0000FF0000000000ULL) >> 24) | ((val & 0x000000FF00000000ULL) >> 8) | + ((val & 0x00000000FF000000ULL) << 8) | ((val & 0x0000000000FF0000ULL) << 24) | + ((val & 0x000000000000FF00ULL) << 40) | ((val & 0x00000000000000FFULL) << 56); +#endif +} + +int CBasics::Stat(const char* path, Sstat* statOut) { +#if _WIN32 + size_t pos; + const nowide::wstackstring wpath(path); + const wchar_t* wpathP = wpath.get(); + for (pos = 0; pos < 3 && wpathP[pos] != L'\0'; ++pos) {} + if (pos == 2 && wpathP[1] == L':') { + wchar_t fixPath[4] = {wpathP[0], L':', L'/', L'\0'}; + return _wstat64(fixPath, statOut); + } + return _wstat64(wpath.get(), statOut); +#else + return stat(path, statOut); +#endif +} + +/* recursive mkdir */ +int CBasics::RecursiveMakeDir(const char* dir) { +#if _WIN32 + char tmp[1024]; + + /* copy path */ + std::strncpy(tmp, dir, std::size(tmp)); + const size_t len = std::strlen(tmp); + if (len >= std::size(tmp)) { + return -1; + } + + /* remove trailing slash */ + if (tmp[len - 1] == '/' || tmp[len - 1] == '\\') { + tmp[len - 1] = 0; + } + + /* recursive mkdir */ + char* p = nullptr; + Sstat sb; + for (p = tmp + 1; *p; p++) { + if (*p == '/' || *p == '\\') { + *p = 0; + /* test path */ + if (Stat(tmp, &sb) != 0) { + /* path does not exist - create directory */ + const nowide::wstackstring wtmp(tmp); + if (!CreateDirectoryW(wtmp.get(), nullptr)) { + return -1; + } + } else if (!S_ISDIR(sb.st_mode)) { + /* not a directory */ + return -1; + } + *p = '/'; + } + } + /* test path */ + if (Stat(tmp, &sb) != 0) { + /* path does not exist - create directory */ + const nowide::wstackstring wtmp(tmp); + if (!CreateDirectoryW(wtmp.get(), nullptr)) { + return -1; + } + } else if (!S_ISDIR(sb.st_mode)) { + /* not a directory */ + return -1; + } + return 0; +#else + char tmp[1024]; + + /* copy path */ + std::memset(tmp, 0, std::size(tmp)); + std::strncpy(tmp, dir, std::size(tmp) - 1); + const size_t len = std::strlen(tmp); + if (len >= std::size(tmp)) { + return -1; + } + + /* remove trailing slash */ + if (tmp[len - 1] == '/') { + tmp[len - 1] = 0; + } + + /* recursive mkdir */ + char* p = nullptr; + Sstat sb; + for (p = tmp + 1; *p; p++) { + if (*p == '/') { + *p = 0; + /* test path */ + if (Stat(tmp, &sb) != 0) { + /* path does not exist - create directory */ + if (mkdir(tmp, 0755) < 0) { + return -1; + } + } else if (!S_ISDIR(sb.st_mode)) { + /* not a directory */ + return -1; + } + *p = '/'; + } + } + /* test path */ + if (Stat(tmp, &sb) != 0) { + /* path does not exist - create directory */ + if (mkdir(tmp, 0755) < 0) { + return -1; + } + } else if (!S_ISDIR(sb.st_mode)) { + /* not a directory */ + return -1; + } + return 0; +#endif +} + +void CBasics::MakeDir(const char* dir) { +#if _WIN32 + HRESULT err; + const nowide::wstackstring wdir(dir); + if (!CreateDirectoryW(wdir.get(), NULL)) + if ((err = GetLastError()) != ERROR_ALREADY_EXISTS) + LogModule.report(logvisor::Fatal, FMT_STRING("MakeDir({})"), dir); +#else + if (mkdir(dir, 0755)) + if (errno != EEXIST) + LogModule.report(logvisor::Fatal, FMT_STRING("MakeDir({}): {}"), dir, strerror(errno)); +#endif +} + +bool CBasics::IsDir(const char* path) { + Sstat theStat; + Stat(path, &theStat); + + return S_ISDIR(theStat.st_mode); +} + +bool CBasics::IsFile(const char* path) { + Sstat theStat; + Stat(path, &theStat); + + return S_ISREG(theStat.st_mode); +} + } // namespace metaforce diff --git a/Runtime/CDependencyGroup.cpp b/Runtime/CDependencyGroup.cpp index bc6064eae..ae1391b86 100644 --- a/Runtime/CDependencyGroup.cpp +++ b/Runtime/CDependencyGroup.cpp @@ -5,7 +5,7 @@ namespace metaforce { CDependencyGroup::CDependencyGroup(CInputStream& in) { ReadFromStream(in); } void CDependencyGroup::ReadFromStream(CInputStream& in) { - u32 depCount = in.readUint32Big(); + u32 depCount = in.ReadLong(); x0_objectTags.reserve(depCount); for (u32 i = 0; i < depCount; i++) x0_objectTags.emplace_back(in); diff --git a/Runtime/CDvdFile.cpp b/Runtime/CDvdFile.cpp index e874686b6..297d8fb0c 100644 --- a/Runtime/CDvdFile.cpp +++ b/Runtime/CDvdFile.cpp @@ -7,67 +7,153 @@ namespace metaforce { -hecl::ProjectPath CDvdFile::m_DvdRoot; -std::unordered_map CDvdFile::m_caseInsensitiveMap; +std::unique_ptr CDvdFile::m_DvdRoot; +// std::unordered_map CDvdFile::m_caseInsensitiveMap; class CFileDvdRequest : public IDvdRequest { - std::shared_ptr m_reader; + std::shared_ptr m_reader; + uint64_t m_begin; + uint64_t m_size; + void* m_buf; u32 m_len; ESeekOrigin m_whence; int m_offset; + +#ifdef HAS_DVD_THREAD std::atomic_bool m_cancel = {false}; std::atomic_bool m_complete = {false}; +#else + bool m_cancel = false; + bool m_complete = false; +#endif std::function m_callback; public: ~CFileDvdRequest() override { CFileDvdRequest::PostCancelRequest(); } void WaitUntilComplete() override { +#ifdef HAS_DVD_THREAD while (!m_complete.load() && !m_cancel.load()) { std::unique_lock lk{CDvdFile::m_WaitMutex}; } +#else + if (!m_complete && !m_cancel) { + CDvdFile::DoWork(); + } +#endif + } + bool IsComplete() override { +#ifdef HAS_DVD_THREAD + return m_complete.load(); +#else + if (!m_complete) { + CDvdFile::DoWork(); + } + return m_complete; +#endif } - bool IsComplete() override { return m_complete.load(); } void PostCancelRequest() override { +#ifdef HAS_DVD_THREAD if (m_complete.load() || m_cancel.load()) { return; } std::unique_lock waitlk{CDvdFile::m_WaitMutex}; m_cancel.store(true); +#else + m_cancel = true; +#endif } [[nodiscard]] EMediaType GetMediaType() const override { return EMediaType::File; } CFileDvdRequest(CDvdFile& file, void* buf, u32 len, ESeekOrigin whence, int off, std::function&& cb) - : m_reader(file.m_reader), m_buf(buf), m_len(len), m_whence(whence), m_offset(off), m_callback(std::move(cb)) {} + : m_reader(file.m_reader) + , m_begin(file.m_begin) + , m_size(file.m_size) + , m_buf(buf) + , m_len(len) + , m_whence(whence) + , m_offset(off) + , m_callback(std::move(cb)) {} void DoRequest() { +#ifdef HAS_DVD_THREAD if (m_cancel.load()) { return; } - u32 readLen; +#else + if (m_cancel) { + return; + } +#endif + u32 readLen = 0; if (m_whence == ESeekOrigin::Cur && m_offset == 0) { - readLen = m_reader->readBytesToBuf(m_buf, m_len); + readLen = m_reader->read(m_buf, m_len); } else { - m_reader->seek(m_offset, athena::SeekOrigin(m_whence)); - readLen = m_reader->readBytesToBuf(m_buf, m_len); + int seek = 0; + int64_t offset = m_offset; + switch (m_whence) { + case ESeekOrigin::Begin: { + seek = SEEK_SET; + offset += int64_t(m_begin); + break; + } + case ESeekOrigin::End: { + seek = SEEK_SET; + offset += int64_t(m_begin) + int64_t(m_size); + break; + } + case ESeekOrigin::Cur: { + seek = SEEK_CUR; + break; + } + }; + m_reader->seek(offset, seek); + readLen = m_reader->read(m_buf, m_len); } if (m_callback) { m_callback(readLen); } +#ifdef HAS_DVD_THREAD m_complete.store(true); +#else + m_complete = true; +#endif } }; +#ifdef HAS_DVD_THREAD std::thread CDvdFile::m_WorkerThread; std::mutex CDvdFile::m_WorkerMutex; std::condition_variable CDvdFile::m_WorkerCV; std::mutex CDvdFile::m_WaitMutex; std::atomic_bool CDvdFile::m_WorkerRun = {false}; +#endif std::vector> CDvdFile::m_RequestQueue; +std::string CDvdFile::m_rootDirectory; +std::unique_ptr CDvdFile::m_dolBuf; + +CDvdFile::CDvdFile(std::string_view path) : x18_path(path) { + auto* node = ResolvePath(path); + if (node != nullptr && node->getKind() == nod::Node::Kind::File) { + m_reader = node->beginReadStream(); + m_begin = m_reader->position(); + m_size = node->size(); + } +} + +// single-threaded hack +void CDvdFile::DoWork() { + for (std::shared_ptr& req : m_RequestQueue) { + auto& concreteReq = static_cast(*req); + concreteReq.DoRequest(); + } + m_RequestQueue.clear(); +} void CDvdFile::WorkerProc() { +#ifdef HAS_DVD_THREAD logvisor::RegisterThreadName("CDvdFile"); OPTICK_THREAD("CDvdFile"); @@ -91,57 +177,105 @@ void CDvdFile::WorkerProc() { } m_WorkerCV.wait(lk); } +#endif } std::shared_ptr CDvdFile::AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off, std::function&& cb) { std::shared_ptr ret = std::make_shared(*this, buf, len, whence, off, std::move(cb)); +#ifdef HAS_DVD_THREAD std::unique_lock lk{m_WorkerMutex}; +#endif m_RequestQueue.emplace_back(ret); +#ifdef HAS_DVD_THREAD lk.unlock(); m_WorkerCV.notify_one(); +#endif return ret; } -hecl::ProjectPath CDvdFile::ResolvePath(std::string_view path) { - auto start = path.begin(); - while (*start == '/') { - ++start; +u32 CDvdFile::SyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int offset) { + int seek = 0; + switch (whence) { + case ESeekOrigin::Begin: { + seek = SEEK_SET; + offset += int64_t(m_begin); + break; } - std::string lowerChStr(start, path.end()); - std::transform(lowerChStr.begin(), lowerChStr.end(), lowerChStr.begin(), ::tolower); - auto search = m_caseInsensitiveMap.find(lowerChStr); - if (search == m_caseInsensitiveMap.end()) { - return {}; + case ESeekOrigin::End: { + seek = SEEK_SET; + offset += int64_t(m_begin) + int64_t(m_size); + break; } - return hecl::ProjectPath(m_DvdRoot, search->second); + case ESeekOrigin::Cur: { + seek = SEEK_CUR; + break; + } + }; + m_reader->seek(offset, seek); + return m_reader->read(buf, len); } -void CDvdFile::RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, std::string::size_type prefixLen) { - for (const auto& p : path.enumerateDir()) { - if (p.m_isDir) { - RecursiveBuildCaseInsensitiveMap(hecl::ProjectPath(path, p.m_name), prefixLen); +nod::Node* CDvdFile::ResolvePath(std::string_view path) { + if (!m_DvdRoot) { + return nullptr; + } + if (path.starts_with('/')) { + path.remove_prefix(1); + } + std::string prefixedPath; + if (!m_rootDirectory.empty()) { + prefixedPath = m_rootDirectory; + prefixedPath += '/'; + prefixedPath += path; + path = prefixedPath; + } + auto* node = &m_DvdRoot->getDataPartition()->getFSTRoot(); + while (node != nullptr && !path.empty()) { + std::string component; + auto end = path.find('/'); + if (end != std::string_view::npos) { + component = path.substr(0, end); + path.remove_prefix(component.size() + 1); } else { - hecl::ProjectPath ch(path, p.m_name); - std::string chStr(ch.getAbsolutePath().begin() + prefixLen, ch.getAbsolutePath().end()); - std::string lowerChStr(chStr); - hecl::ToLower(lowerChStr); - m_caseInsensitiveMap[lowerChStr] = chStr; + component = path; + path.remove_prefix(component.size()); + } + std::transform(component.begin(), component.end(), component.begin(), ::tolower); + auto* tmpNode = node; + node = nullptr; + for (auto& item : *tmpNode) { + const auto name = item.getName(); + if (std::equal(component.begin(), component.end(), name.begin(), name.end(), + [](char a, char b) { return a == tolower(b); })) { + node = &item; + break; + } } } + return node; } -void CDvdFile::Initialize(const hecl::ProjectPath& path) { - m_DvdRoot = path; - RecursiveBuildCaseInsensitiveMap(path, path.getAbsolutePath().length() + 1); +bool CDvdFile::Initialize(const std::string_view& path) { +#ifdef HAS_DVD_THREAD if (m_WorkerRun.load()) { - return; + return true; } +#endif + m_DvdRoot = nod::OpenDiscFromImage(path); + if (!m_DvdRoot) { + return false; + } + m_dolBuf = m_DvdRoot->getDataPartition()->getDOLBuf(); +#ifdef HAS_DVD_THREAD m_WorkerRun.store(true); m_WorkerThread = std::thread(WorkerProc); +#endif + return true; } void CDvdFile::Shutdown() { +#ifdef HAS_DVD_THREAD if (!m_WorkerRun.load()) { return; } @@ -150,7 +284,22 @@ void CDvdFile::Shutdown() { if (m_WorkerThread.joinable()) { m_WorkerThread.join(); } +#endif m_RequestQueue.clear(); } +SDiscInfo CDvdFile::DiscInfo() { + SDiscInfo out{}; + if (!m_DvdRoot) { + return out; + } + const auto& header = m_DvdRoot->getHeader(); + std::memcpy(out.gameId.data(), header.m_gameID, sizeof(header.m_gameID)); + out.version = header.m_discVersion; + out.gameTitle = header.m_gameTitle; + return out; +} + +void CDvdFile::SetRootDirectory(const std::string_view& rootDir) { m_rootDirectory = rootDir; } + } // namespace metaforce diff --git a/Runtime/CDvdFile.hpp b/Runtime/CDvdFile.hpp index f49018566..607c8ed65 100644 --- a/Runtime/CDvdFile.hpp +++ b/Runtime/CDvdFile.hpp @@ -11,7 +11,13 @@ #include "Runtime/GCNTypes.hpp" #include "Runtime/RetroTypes.hpp" -#include +//#include +#include +#include + +#ifndef EMSCRIPTEN +#define HAS_DVD_THREAD +#endif namespace metaforce { @@ -20,46 +26,61 @@ enum class ESeekOrigin { Begin = 0, Cur = 1, End = 2 }; struct DVDFileInfo; class IDvdRequest; +struct SDiscInfo { + std::array gameId; + uint8_t version; + std::string gameTitle; +}; + class CDvdFile { friend class CResLoader; friend class CFileDvdRequest; - static hecl::ProjectPath m_DvdRoot; - static std::unordered_map m_caseInsensitiveMap; + static std::unique_ptr m_DvdRoot; + // static std::unordered_map m_caseInsensitiveMap; +#ifdef HAS_DVD_THREAD static std::thread m_WorkerThread; static std::mutex m_WorkerMutex; static std::condition_variable m_WorkerCV; static std::mutex m_WaitMutex; static std::atomic_bool m_WorkerRun; +#endif static std::vector> m_RequestQueue; + static std::string m_rootDirectory; + static std::unique_ptr m_dolBuf; static void WorkerProc(); std::string x18_path; - std::shared_ptr m_reader; + std::shared_ptr m_reader; + uint64_t m_begin; + uint64_t m_size; - static hecl::ProjectPath ResolvePath(std::string_view path); - static void RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, std::string::size_type prefixLen); + static nod::Node* ResolvePath(std::string_view path); + // static void RecursiveBuildCaseInsensitiveMap(const hecl::ProjectPath& path, std::string::size_type prefixLen); public: - static void Initialize(const hecl::ProjectPath& path); + static bool Initialize(const std::string_view& path); + static SDiscInfo DiscInfo(); + static void SetRootDirectory(const std::string_view& rootDir); static void Shutdown(); + static u8* GetDolBuf() { return m_dolBuf.get(); } + static void DoWork(); - CDvdFile(std::string_view path) - : x18_path(path), m_reader(std::make_shared(ResolvePath(path).getAbsolutePath())) {} - operator bool() const { return m_reader->isOpen(); } - void UpdateFilePos(int pos) { m_reader->seek(pos, athena::SeekOrigin::Begin); } - static bool FileExists(std::string_view path) { return ResolvePath(path).isFile(); } - void CloseFile() { m_reader->close(); } + CDvdFile(std::string_view path); + operator bool() const { return m_reader.operator bool(); } + void UpdateFilePos(int pos) { m_reader->seek(pos, SEEK_SET); } + static bool FileExists(std::string_view path) { + nod::Node* node = ResolvePath(path); + return node != nullptr && node->getKind() == nod::Node::Kind::File; + } + void CloseFile() { m_reader.reset(); } std::shared_ptr AsyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int off, std::function&& cb = {}); - u32 SyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int offset) { - m_reader->seek(offset, athena::SeekOrigin(whence)); - return m_reader->readBytesToBuf(buf, len); - } + u32 SyncSeekRead(void* buf, u32 len, ESeekOrigin whence, int offset); std::shared_ptr AsyncRead(void* buf, u32 len, std::function&& cb = {}) { return AsyncSeekRead(buf, len, ESeekOrigin::Cur, 0, std::move(cb)); } - u32 SyncRead(void* buf, u32 len) { return m_reader->readBytesToBuf(buf, len); } - u64 Length() const { return m_reader->length(); } + u32 SyncRead(void* buf, u32 len) { return m_reader->read(buf, len); } + u64 Length() const { return m_size; } std::string_view GetPath() const { return x18_path; } }; } // namespace metaforce diff --git a/Runtime/CFactoryMgr.cpp b/Runtime/CFactoryMgr.cpp index 72fda9658..c140a039c 100644 --- a/Runtime/CFactoryMgr.cpp +++ b/Runtime/CFactoryMgr.cpp @@ -21,16 +21,16 @@ constexpr std::array TypeTable{ CFactoryFnReturn CFactoryMgr::MakeObject(const SObjectTag& tag, metaforce::CInputStream& in, const CVParamTransfer& paramXfer, CObjectReference* selfRef) { - auto search = m_factories.find(tag.type); - if (search == m_factories.end()) + auto search = x10_factories.find(tag.type); + if (search == x10_factories.end()) return {}; return search->second(tag, in, paramXfer, selfRef); } bool CFactoryMgr::CanMakeMemory(const metaforce::SObjectTag& tag) const { - auto search = m_memFactories.find(tag.type); - return search != m_memFactories.cend(); + auto search = x24_memFactories.find(tag.type); + return search != x24_memFactories.cend(); } CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::unique_ptr&& buf, int size, @@ -39,30 +39,34 @@ CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::u OPTICK_EVENT(); std::unique_ptr localBuf = std::move(buf); - const auto memFactoryIter = m_memFactories.find(tag.type); - if (memFactoryIter != m_memFactories.cend()) { + const auto memFactoryIter = x24_memFactories.find(tag.type); + if (memFactoryIter != x24_memFactories.cend()) { if (compressed) { - std::unique_ptr compRead = std::make_unique(localBuf.get(), size); - const u32 decompLen = compRead->readUint32Big(); + std::unique_ptr compRead = + std::make_unique(localBuf.get(), size, CMemoryInStream::EOwnerShip::NotOwned); + const u32 decompLen = compRead->ReadLong(); CZipInputStream r(std::move(compRead)); - std::unique_ptr decompBuf = r.readUBytes(decompLen); + std::unique_ptr decompBuf(new u8[decompLen]); + r.Get(decompBuf.get(), decompLen); return memFactoryIter->second(tag, std::move(decompBuf), decompLen, paramXfer, selfRef); } else { return memFactoryIter->second(tag, std::move(localBuf), size, paramXfer, selfRef); } } else { - const auto factoryIter = m_factories.find(tag.type); - if (factoryIter == m_factories.end()) { + const auto factoryIter = x10_factories.find(tag.type); + if (factoryIter == x10_factories.end()) { return {}; } if (compressed) { - std::unique_ptr compRead = std::make_unique(localBuf.get(), size); - compRead->readUint32Big(); + std::unique_ptr compRead = + std::make_unique(localBuf.get(), size, CMemoryInStream::EOwnerShip::NotOwned); + + compRead->ReadLong(); CZipInputStream r(std::move(compRead)); return factoryIter->second(tag, r, paramXfer, selfRef); } else { - CMemoryInStream r(localBuf.get(), size); + CMemoryInStream r(localBuf.get(), size, CMemoryInStream::EOwnerShip::NotOwned); return factoryIter->second(tag, r, paramXfer, selfRef); } } diff --git a/Runtime/CFactoryMgr.hpp b/Runtime/CFactoryMgr.hpp index 0f5b3e8b3..058203051 100644 --- a/Runtime/CFactoryMgr.hpp +++ b/Runtime/CFactoryMgr.hpp @@ -3,7 +3,7 @@ #include #include "Runtime/IFactory.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" namespace metaforce { @@ -12,8 +12,8 @@ class CVParamTransfer; class IObj; class CFactoryMgr { - std::unordered_map m_factories; - std::unordered_map m_memFactories; + std::unordered_map x10_factories; + std::unordered_map x24_memFactories; public: CFactoryFnReturn MakeObject(const SObjectTag& tag, metaforce::CInputStream& in, const CVParamTransfer& paramXfer, @@ -21,8 +21,8 @@ public: bool CanMakeMemory(const metaforce::SObjectTag& tag) const; CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag, std::unique_ptr&& buf, int size, bool compressed, const CVParamTransfer& paramXfer, CObjectReference* selfRef); - void AddFactory(FourCC key, FFactoryFunc func) { m_factories.insert_or_assign(key, std::move(func)); } - void AddFactory(FourCC key, FMemFactoryFunc func) { m_memFactories.insert_or_assign(key, std::move(func)); } + void AddFactory(FourCC key, FFactoryFunc func) { x10_factories.insert_or_assign(key, std::move(func)); } + void AddFactory(FourCC key, FMemFactoryFunc func) { x24_memFactories.insert_or_assign(key, std::move(func)); } enum class ETypeTable : u8 { CLSN, diff --git a/Runtime/CGameAllocator.cpp b/Runtime/CGameAllocator.cpp index 87f062408..71369a62d 100644 --- a/Runtime/CGameAllocator.cpp +++ b/Runtime/CGameAllocator.cpp @@ -1,7 +1,9 @@ #include "Runtime/CGameAllocator.hpp" +#include + namespace metaforce { -logvisor::Module AllocLog("metaforce::CGameAllocator"); +static logvisor::Module Log("metaforce::CGameAllocator"); #pragma GCC diagnostic ignored "-Wclass-memaccess" @@ -44,7 +46,7 @@ u8* CGameAllocator::Alloc(size_t len) { void CGameAllocator::Free(u8* ptr) { SChunkDescription* info = reinterpret_cast(ptr - sizeof(SChunkDescription)); if (info->magic != 0xE8E8E8E8 || info->sentinal != 0xEFEFEFEF) { - AllocLog.report(logvisor::Fatal, FMT_STRING("Invalid chunk description, memory corruption!")); + Log.report(logvisor::Fatal, FMT_STRING("Invalid chunk description, memory corruption!")); return; } diff --git a/Runtime/CGameHintInfo.cpp b/Runtime/CGameHintInfo.cpp index be625c576..822c183de 100644 --- a/Runtime/CGameHintInfo.cpp +++ b/Runtime/CGameHintInfo.cpp @@ -7,29 +7,29 @@ namespace metaforce { CGameHintInfo::CGameHintInfo(CInputStream& in, s32 version) { - u32 hintCount = in.readUint32Big(); + u32 hintCount = in.ReadLong(); x0_hints.reserve(hintCount); for (u32 i = 0; i < hintCount; ++i) x0_hints.emplace_back(in, version); } CGameHintInfo::CGameHint::CGameHint(CInputStream& in, s32 version) -: x0_name(in.readString()) -, x10_immediateTime(in.readFloatBig()) -, x14_normalTime(in.readFloatBig()) -, x18_stringId(in.readUint32Big()) -, x1c_textTime(3.f * float(version <= 0 ? 1 : in.readUint32Big())) { - u32 locationCount = in.readUint32Big(); +: x0_name(in.Get()) +, x10_immediateTime(in.ReadFloat()) +, x14_normalTime(in.ReadFloat()) +, x18_stringId(in.Get()) +, x1c_textTime(3.f * float(version <= 0 ? 1 : in.ReadLong())) { + u32 locationCount = in.ReadLong(); x20_locations.reserve(locationCount); for (u32 i = 0; i < locationCount; ++i) x20_locations.emplace_back(in, version); } CGameHintInfo::SHintLocation::SHintLocation(CInputStream& in, s32) -: x0_mlvlId(in.readUint32Big()) -, x4_mreaId(in.readUint32Big()) -, x8_areaId(in.readUint32Big()) -, xc_stringId(in.readUint32Big()) {} +: x0_mlvlId(in.Get()) +, x4_mreaId(in.Get()) +, x8_areaId(in.ReadLong()) +, xc_stringId(in.Get()) {} int CGameHintInfo::FindHintIndex(std::string_view str) { const std::vector& gameHints = g_MemoryCardSys->GetHints(); @@ -40,8 +40,8 @@ int CGameHintInfo::FindHintIndex(std::string_view str) { } CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&, CObjectReference*) { - in.readUint32Big(); - s32 version = in.readInt32Big(); + in.ReadLong(); + s32 version = in.ReadInt32(); return TToken::GetIObjObjectFor(std::make_unique(in, version)); } diff --git a/Runtime/CGameOptions.cpp b/Runtime/CGameOptions.cpp index 36d9adabb..8f6dbb68b 100644 --- a/Runtime/CGameOptions.cpp +++ b/Runtime/CGameOptions.cpp @@ -14,7 +14,7 @@ #include "Runtime/Graphics/CMoviePlayer.hpp" #include "Runtime/Input/CFinalInput.hpp" -#include +#include "ConsoleVariables/CVarManager.hpp" namespace metaforce { @@ -96,26 +96,26 @@ constexpr std::array, 5> GameOptionsRegist {0, nullptr}, }}; -CPersistentOptions::CPersistentOptions(CBitStreamReader& stream) { +CPersistentOptions::CPersistentOptions(CInputStream& stream) { for (u8& entry : x0_nesState) { - entry = stream.ReadEncoded(8); + entry = stream.ReadBits(8); } for (bool& entry : x68_) { - entry = stream.ReadEncoded(8) != 0; + entry = stream.ReadBits(8) != 0; } - xc0_frozenFpsCount = stream.ReadEncoded(2); - xc4_frozenBallCount = stream.ReadEncoded(2); - xc8_powerBombAmmoCount = stream.ReadEncoded(1); - xcc_logScanPercent = stream.ReadEncoded(7); - xd0_24_fusionLinked = stream.ReadEncoded(1) != 0; - xd0_25_normalModeBeat = stream.ReadEncoded(1) != 0; - xd0_26_hardModeBeat = stream.ReadEncoded(1) != 0; - xd0_27_fusionBeat = stream.ReadEncoded(1) != 0; + xc0_frozenFpsCount = stream.ReadBits(2); + xc4_frozenBallCount = stream.ReadBits(2); + xc8_powerBombAmmoCount = stream.ReadBits(1); + xcc_logScanPercent = stream.ReadBits(7); + xd0_24_fusionLinked = stream.ReadBits(1) != 0; + xd0_25_normalModeBeat = stream.ReadBits(1) != 0; + xd0_26_hardModeBeat = stream.ReadBits(1) != 0; + xd0_27_fusionBeat = stream.ReadBits(1) != 0; xd0_28_fusionSuitActive = false; - xd0_29_allItemsCollected = stream.ReadEncoded(1) != 0; - xbc_autoMapperKeyState = stream.ReadEncoded(2); + xd0_29_allItemsCollected = stream.ReadBits(1) != 0; + xbc_autoMapperKeyState = stream.ReadBits(2); const auto& memWorlds = g_MemoryCardSys->GetMemoryWorlds(); size_t cinematicCount = 0; @@ -128,7 +128,7 @@ CPersistentOptions::CPersistentOptions(CBitStreamReader& stream) { std::vector cinematicStates; cinematicStates.reserve(cinematicCount); for (size_t i = 0; i < cinematicCount; ++i) { - cinematicStates.push_back(stream.ReadEncoded(1) != 0); + cinematicStates.push_back(stream.ReadBits(1) != 0); } for (const auto& world : memWorlds) { @@ -142,25 +142,25 @@ CPersistentOptions::CPersistentOptions(CBitStreamReader& stream) { } } -void CPersistentOptions::PutTo(CBitStreamWriter& w) const { +void CPersistentOptions::PutTo(COutputStream& w) const { for (const u8 entry : x0_nesState) { - w.WriteEncoded(entry, 8); + w.WriteBits(entry, 8); } for (const bool entry : x68_) { - w.WriteEncoded(u32(entry), 8); + w.WriteBits(u32(entry), 8); } - w.WriteEncoded(xc0_frozenFpsCount, 2); - w.WriteEncoded(xc4_frozenBallCount, 2); - w.WriteEncoded(xc8_powerBombAmmoCount, 1); - w.WriteEncoded(xcc_logScanPercent, 7); - w.WriteEncoded(xd0_24_fusionLinked, 1); - w.WriteEncoded(xd0_25_normalModeBeat, 1); - w.WriteEncoded(xd0_26_hardModeBeat, 1); - w.WriteEncoded(xd0_27_fusionBeat, 1); - w.WriteEncoded(xd0_29_allItemsCollected, 1); - w.WriteEncoded(xbc_autoMapperKeyState, 2); + w.WriteBits(xc0_frozenFpsCount, 2); + w.WriteBits(xc4_frozenBallCount, 2); + w.WriteBits(xc8_powerBombAmmoCount, 1); + w.WriteBits(xcc_logScanPercent, 7); + w.WriteBits(xd0_24_fusionLinked, 1); + w.WriteBits(xd0_25_normalModeBeat, 1); + w.WriteBits(xd0_26_hardModeBeat, 1); + w.WriteBits(xd0_27_fusionBeat, 1); + w.WriteBits(xd0_29_allItemsCollected, 1); + w.WriteBits(xbc_autoMapperKeyState, 2); const auto& memWorlds = g_MemoryCardSys->GetMemoryWorlds(); for (const auto& world : memWorlds) { @@ -168,7 +168,7 @@ void CPersistentOptions::PutTo(CBitStreamWriter& w) const { g_SimplePool->GetObj(SObjectTag{FOURCC('SAVW'), world.second.GetSaveWorldAssetId()}); for (const auto& cineId : saveWorld->GetCinematics()) { - w.WriteEncoded(u32(GetCinematicState(world.first, cineId)), 1); + w.WriteBits(u32(GetCinematicState(world.first, cineId)), 1); } } } @@ -194,26 +194,26 @@ void CPersistentOptions::SetCinematicState(CAssetId mlvlId, TEditorId cineId, bo xac_cinematicStates.erase(existing); } -CGameOptions::CGameOptions(CBitStreamReader& stream) { +CGameOptions::CGameOptions(CInputStream& stream) { for (u8& entry : x0_) - entry = stream.ReadEncoded(8); + entry = stream.ReadBits(8); - x44_soundMode = CAudioSys::ESurroundModes(stream.ReadEncoded(2)); - x48_screenBrightness = stream.ReadEncoded(4); + x44_soundMode = CAudioSys::ESurroundModes(stream.ReadBits(2)); + x48_screenBrightness = stream.ReadBits(4); - x4c_screenXOffset = stream.ReadEncoded(6) - 30; - x50_screenYOffset = stream.ReadEncoded(6) - 30; - x54_screenStretch = stream.ReadEncoded(5) - 10; - x58_sfxVol = stream.ReadEncoded(7); - x5c_musicVol = stream.ReadEncoded(7); - x60_hudAlpha = stream.ReadEncoded(8); - x64_helmetAlpha = stream.ReadEncoded(8); + x4c_screenXOffset = stream.ReadBits(6) - 30; + x50_screenYOffset = stream.ReadBits(6) - 30; + x54_screenStretch = stream.ReadBits(5) - 10; + x58_sfxVol = stream.ReadBits(7); + x5c_musicVol = stream.ReadBits(7); + x60_hudAlpha = stream.ReadBits(8); + x64_helmetAlpha = stream.ReadBits(8); - x68_24_hudLag = stream.ReadEncoded(1) != 0; - x68_28_hintSystem = stream.ReadEncoded(1) != 0; - x68_25_invertY = stream.ReadEncoded(1) != 0; - x68_26_rumble = stream.ReadEncoded(1) != 0; - x68_27_swapBeamsControls = stream.ReadEncoded(1) != 0; + x68_24_hudLag = stream.ReadBits(1) != 0; + x68_28_hintSystem = stream.ReadBits(1) != 0; + x68_25_invertY = stream.ReadBits(1) != 0; + x68_26_rumble = stream.ReadBits(1) != 0; + x68_27_swapBeamsControls = stream.ReadBits(1) != 0; } void CGameOptions::ResetToDefaults() { @@ -235,26 +235,26 @@ void CGameOptions::ResetToDefaults() { EnsureSettings(); } -void CGameOptions::PutTo(CBitStreamWriter& writer) const { +void CGameOptions::PutTo(COutputStream& writer) const { for (const u8 entry : x0_) - writer.WriteEncoded(entry, 8); + writer.WriteBits(entry, 8); - writer.WriteEncoded(u32(x44_soundMode), 2); - writer.WriteEncoded(x48_screenBrightness, 4); + writer.WriteBits(u32(x44_soundMode), 2); + writer.WriteBits(x48_screenBrightness, 4); - writer.WriteEncoded(x4c_screenXOffset + 30, 6); - writer.WriteEncoded(x50_screenYOffset + 30, 6); - writer.WriteEncoded(x54_screenStretch + 10, 5); - writer.WriteEncoded(x58_sfxVol, 7); - writer.WriteEncoded(x5c_musicVol, 7); - writer.WriteEncoded(x60_hudAlpha, 8); - writer.WriteEncoded(x64_helmetAlpha, 8); + writer.WriteBits(x4c_screenXOffset + 30, 6); + writer.WriteBits(x50_screenYOffset + 30, 6); + writer.WriteBits(x54_screenStretch + 10, 5); + writer.WriteBits(x58_sfxVol, 7); + writer.WriteBits(x5c_musicVol, 7); + writer.WriteBits(x60_hudAlpha, 8); + writer.WriteBits(x64_helmetAlpha, 8); - writer.WriteEncoded(x68_24_hudLag, 1); - writer.WriteEncoded(x68_28_hintSystem, 1); - writer.WriteEncoded(x68_25_invertY, 1); - writer.WriteEncoded(x68_26_rumble, 1); - writer.WriteEncoded(x68_27_swapBeamsControls, 1); + writer.WriteBits(x68_24_hudLag, 1); + writer.WriteBits(x68_28_hintSystem, 1); + writer.WriteBits(x68_25_invertY, 1); + writer.WriteBits(x68_26_rumble, 1); + writer.WriteBits(x68_27_swapBeamsControls, 1); } CGameOptions::CGameOptions() @@ -287,7 +287,7 @@ void CGameOptions::ApplyGamma() { gammaT = gammaT * 0.5f + 0.5f; if (zeus::close_enough(gammaT, 1.f, 0.05f)) gammaT = 1.f; - CGraphics::g_BooFactory->setDisplayGamma(gammaT); +// CGraphics::g_BooFactory->setDisplayGamma(gammaT); } void CGameOptions::SetGamma(s32 value, bool apply) { @@ -384,19 +384,19 @@ void CGameOptions::SetControls(int controls) { } constexpr std::array, 5> CStickToDPadRemap{{ - {0x2A13C23E, 0xF13452F8}, - {0xA91A7703, 0xC042EC91}, - {0x12A12131, 0x5F556002}, - {0xA9798329, 0xB306E26F}, - {0xCD7B1ACA, 0x8ADA8184}, + {0x2A13C23Eu, 0xF13452F8u}, + {0xA91A7703u, 0xC042EC91u}, + {0x12A12131u, 0x5F556002u}, + {0xA9798329u, 0xB306E26Fu}, + {0xCD7B1ACAu, 0x8ADA8184u}, }}; constexpr std::array, 5> CStickOutlineToDPadRemap{{ - {0x1A29C0E6, 0xF13452F8}, - {0x5D9F9796, 0xC042EC91}, - {0x951546A8, 0x5F556002}, - {0x7946C4C5, 0xB306E26F}, - {0x409AA72E, 0x8ADA8184}, + {0x1A29C0E6u, 0xF13452F8u}, + {0x5D9F9796u, 0xC042EC91u}, + {0x951546A8u, 0x5F556002u}, + {0x7946C4C5u, 0xB306E26Fu}, + {0x409AA72Eu, 0x8ADA8184u}, }}; void CGameOptions::ResetControllerAssets(int controls) { @@ -446,7 +446,7 @@ void CGameOptions::TryRestoreDefaults(const CFinalInput& input, int category, in if (options.second[option].option != EGameOption::RestoreDefaults) return; - if (!forceRestore && !input.PA() && !input.PSpecialKey(boo::ESpecialKey::Enter)) + if (!forceRestore && !input.PA() && !input.PSpecialKey(ESpecialKey::Enter)) return; if (frontend) { @@ -579,14 +579,14 @@ int CGameOptions::GetOption(EGameOption option) { return 0; } -CHintOptions::CHintOptions(CBitStreamReader& stream) { +CHintOptions::CHintOptions(CInputStream& stream) { const auto& hints = g_MemoryCardSys->GetHints(); x0_hintStates.reserve(hints.size()); u32 hintIdx = 0; for ([[maybe_unused]] const auto& hint : hints) { - const auto state = EHintState(stream.ReadEncoded(2)); - const s32 timeBits = stream.ReadEncoded(32); + const auto state = EHintState(stream.ReadBits(2)); + const s32 timeBits = stream.ReadBits(32); float time; std::memcpy(&time, &timeBits, sizeof(s32)); if (state == EHintState::Zero) { @@ -602,14 +602,14 @@ CHintOptions::CHintOptions(CBitStreamReader& stream) { } } -void CHintOptions::PutTo(CBitStreamWriter& writer) const { +void CHintOptions::PutTo(COutputStream& writer) const { for (const SHintState& hint : x0_hintStates) { - writer.WriteEncoded(u32(hint.x0_state), 2); + writer.WriteBits(u32(hint.x0_state), 2); u32 timeBits; std::memcpy(&timeBits, &hint.x4_time, sizeof(timeBits)); - writer.WriteEncoded(timeBits, 32); + writer.WriteBits(timeBits, 32); } } diff --git a/Runtime/CGameOptions.hpp b/Runtime/CGameOptions.hpp index 84b7b2b07..c30ce87d3 100644 --- a/Runtime/CGameOptions.hpp +++ b/Runtime/CGameOptions.hpp @@ -66,7 +66,7 @@ class CPersistentOptions { public: CPersistentOptions() = default; - explicit CPersistentOptions(CBitStreamReader& stream); + explicit CPersistentOptions(CInputStream& stream); bool GetCinematicState(CAssetId mlvlId, TEditorId cineId) const; void SetCinematicState(CAssetId mlvlId, TEditorId cineId, bool state); @@ -93,7 +93,7 @@ public: bool GetShowPowerBombAmmoMessage() const { return xc8_powerBombAmmoCount != 1; } void IncrementPowerBombAmmoCount() { xc8_powerBombAmmoCount = std::min(1, xc8_powerBombAmmoCount + 1); } - void PutTo(CBitStreamWriter& w) const; + void PutTo(COutputStream& w) const; u8* GetNESState() { return x0_nesState.data(); } const u8* GetNESState() const { return x0_nesState.data(); } @@ -122,11 +122,11 @@ class CGameOptions { public: CGameOptions(); - explicit CGameOptions(CBitStreamReader& stream); + explicit CGameOptions(CInputStream& stream); void ResetToDefaults(); void InitSoundMode(); void EnsureSettings(); - void PutTo(CBitStreamWriter& writer) const; + void PutTo(COutputStream& writer) const; float TuneScreenBrightness() const; void SetScreenBrightness(s32 value, bool apply); @@ -189,8 +189,8 @@ private: public: CHintOptions() = default; - explicit CHintOptions(CBitStreamReader& stream); - void PutTo(CBitStreamWriter& writer) const; + explicit CHintOptions(CInputStream& stream); + void PutTo(COutputStream& writer) const; void SetNextHintTime(); void InitializeMemoryState(); const SHintState* GetCurrentDisplayedHint() const; diff --git a/Runtime/CGameOptionsTouchBar.cpp b/Runtime/CGameOptionsTouchBar.cpp deleted file mode 100644 index fc89bb8a5..000000000 --- a/Runtime/CGameOptionsTouchBar.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "Runtime/CGameOptionsTouchBar.hpp" - -namespace metaforce { - -CGameOptionsTouchBar::EAction CGameOptionsTouchBar::PopAction() { return EAction::None; } - -void CGameOptionsTouchBar::GetSelection(int& left, int& right, int& value) { - left = -1; - right = -1; - value = -1; -} - -void CGameOptionsTouchBar::SetSelection([[maybe_unused]] int left, [[maybe_unused]] int right, - [[maybe_unused]] int value) {} - -#ifndef __APPLE__ -std::unique_ptr NewGameOptionsTouchBar() { return std::make_unique(); } -#endif - -} // namespace metaforce diff --git a/Runtime/CGameOptionsTouchBar.hpp b/Runtime/CGameOptionsTouchBar.hpp deleted file mode 100644 index 832e0d4c3..000000000 --- a/Runtime/CGameOptionsTouchBar.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include - -namespace metaforce { - -class CGameOptionsTouchBar { -public: - enum class EAction { None, Back, Advance, ValueChange }; - - virtual ~CGameOptionsTouchBar() = default; - virtual EAction PopAction(); - virtual void GetSelection(int& left, int& right, int& value); - virtual void SetSelection(int left, int right, int value); -}; - -std::unique_ptr NewGameOptionsTouchBar(); - -} // namespace metaforce diff --git a/Runtime/CGameOptionsTouchBarMac.mm b/Runtime/CGameOptionsTouchBarMac.mm deleted file mode 100644 index 5c7a98722..000000000 --- a/Runtime/CGameOptionsTouchBarMac.mm +++ /dev/null @@ -1,260 +0,0 @@ -#include "CGameOptions.hpp" -#include "CGameOptionsTouchBar.hpp" -#include "GameGlobalObjects.hpp" -#include "GuiSys/CStringTable.hpp" -#include "MP1/MP1.hpp" -#include - -#if !__has_feature(objc_arc) -#error ARC Required -#endif - -static NSColor *BlueConfirm() { - return [NSColor colorWithSRGBRed:0 / 255.f green:130 / 255.f blue:215 / 255.f alpha:1.f]; -} - -@interface GameOptionsTouchBar : NSObject { -@public - metaforce::CStringTable *_pauseScreenStrg; - metaforce::CGameOptionsTouchBar::EAction _action; - std::pair _selection; - int _value, _pendingValue; -} -- (IBAction)onBack:(id)sender; -- (IBAction)onSlide:(id)sender; -- (IBAction)onSet0:(id)sender; -- (IBAction)onSet1:(id)sender; -- (IBAction)onSet2:(id)sender; -- (IBAction)onLeft:(id)sender; -- (IBAction)onRight:(id)sender; -@end - -@implementation GameOptionsTouchBar -- (NSTouchBar *)makeTouchBar { - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items = @[ @"optionsGroup" ]; - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - touchBar.principalItemIdentifier = @"optionsGroup"; - return touchBar; -} -- (NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier { - if ([identifier isEqualToString:@"optionsGroup"]) { - NSGroupTouchBarItem *item = [[NSGroupTouchBarItem alloc] initWithIdentifier:identifier]; - NSTouchBar *touchBar = [NSTouchBar new]; - touchBar.delegate = self; - id items; - if (_selection.first == -1) { - items = [NSMutableArray arrayWithCapacity:5]; - [items addObject:@"back"]; - for (int i = 0; i < 4; ++i) - [items addObject:[NSString stringWithFormat:@"left/%d", i]]; - } else if (_selection.second == -1) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - items = [NSMutableArray arrayWithCapacity:opt.first + 1]; - [items addObject:@"back"]; - for (int i = 0; i < opt.first; ++i) - [items addObject:[NSString stringWithFormat:@"right/%d", i]]; - } else { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - const metaforce::SGameOption &subopt = opt.second[_selection.second]; - if (subopt.type == metaforce::EOptionType::Float) - items = @[ @"back", @"value" ]; - else if (subopt.type == metaforce::EOptionType::DoubleEnum) - items = @[ @"back", @"label", @"double0", @"double1" ]; - else if (subopt.type == metaforce::EOptionType::TripleEnum) - items = @[ @"back", @"label", @"triple0", @"triple1", @"triple2" ]; - } - touchBar.customizationRequiredItemIdentifiers = items; - touchBar.defaultItemIdentifiers = items; - item.groupTouchBar = touchBar; - return item; - } else if ([identifier isEqualToString:@"back"]) { - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithImage:[NSImage imageNamed:NSImageNameTouchBarGoBackTemplate] - target:self - action:@selector(onBack:)]; - item.view = button; - return item; - } else if ([identifier isEqualToString:@"label"]) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - const metaforce::SGameOption &subopt = opt.second[_selection.second]; - - const char16_t *cStr = _pauseScreenStrg->GetString(subopt.stringId); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSTextField *label = [NSTextField labelWithString:[str stringByAppendingString:@":"]]; - item.view = label; - return item; - } else if ([identifier isEqualToString:@"value"]) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - const metaforce::SGameOption &subopt = opt.second[_selection.second]; - - const char16_t *cStr = _pauseScreenStrg->GetString(subopt.stringId); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSSliderTouchBarItem *item = [[NSSliderTouchBarItem alloc] initWithIdentifier:identifier]; - NSSlider *slider = [NSSlider sliderWithValue:_value - minValue:subopt.minVal - maxValue:subopt.maxVal - target:nil - action:nil]; - item.target = self; - item.action = @selector(onSlide:); - item.slider = slider; - item.label = str; - return item; - } else if ([identifier isEqualToString:@"double0"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(95); // Off - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)]; - if (_value == 0) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"double1"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(94); // On - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)]; - if (_value == 1) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"triple0"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(96); // Mono - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet0:)]; - if (_value == 0) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"triple1"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(97); // Stereo - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet1:)]; - if (_value == 1) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else if ([identifier isEqualToString:@"triple2"]) { - const char16_t *cStr = _pauseScreenStrg->GetString(98); // Dolby - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onSet2:)]; - if (_value == 2) - button.bezelColor = BlueConfirm(); - item.view = button; - return item; - } else { - NSArray *pc = [identifier pathComponents]; - if ([pc count] == 2) { - NSString *first = [pc objectAtIndex:0]; - if ([first isEqualToString:@"left"]) { - auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10); - const char16_t *cStr = _pauseScreenStrg->GetString(16 + idx); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onLeft:)]; - button.tag = idx; - item.view = button; - return item; - } else if ([first isEqualToString:@"right"]) { - const std::pair &opt = metaforce::GameOptionsRegistry[_selection.first]; - auto idx = strtoul([[pc objectAtIndex:1] UTF8String], nullptr, 10); - const metaforce::SGameOption &subopt = opt.second[idx]; - const char16_t *cStr = _pauseScreenStrg->GetString(subopt.stringId); - NSString *str = [NSString stringWithUTF8String:hecl::Char16ToUTF8(cStr).c_str()]; - - NSCustomTouchBarItem *item = [[NSCustomTouchBarItem alloc] initWithIdentifier:identifier]; - NSButton *button = [NSButton buttonWithTitle:str target:self action:@selector(onRight:)]; - button.tag = idx; - item.view = button; - return item; - } - } - } - return nil; -} -- (IBAction)onBack:(id)sender { - _action = metaforce::CGameOptionsTouchBar::EAction::Back; -} -- (IBAction)onSlide:(id)sender { - _pendingValue = [((NSSliderTouchBarItem *)sender).slider intValue]; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onSet0:(id)sender { - _pendingValue = 0; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onSet1:(id)sender { - _pendingValue = 1; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onSet2:(id)sender { - _pendingValue = 2; - _action = metaforce::CGameOptionsTouchBar::EAction::ValueChange; -} -- (IBAction)onLeft:(id)sender { - _selection.first = ((NSButton *)sender).tag; - _action = metaforce::CGameOptionsTouchBar::EAction::Advance; -} -- (IBAction)onRight:(id)sender { - _selection.second = ((NSButton *)sender).tag; - _action = metaforce::CGameOptionsTouchBar::EAction::Advance; -} -@end - -namespace metaforce { - -class CGameOptionsTouchBarMac : public CGameOptionsTouchBar { - TLockedToken m_pauseScreen; - GameOptionsTouchBar *m_touchBar; - bool m_initialized = false; - -public: - CGameOptionsTouchBarMac() { - m_pauseScreen = g_SimplePool->GetObj("STRG_PauseScreen"); - m_touchBar = [GameOptionsTouchBar new]; - m_touchBar->_pauseScreenStrg = m_pauseScreen.GetObj(); - m_touchBar->_selection = std::make_pair(-1, -1); - m_touchBar->_value = -1; - } - EAction PopAction() { - if (m_touchBar->_action != EAction::None) { - EAction action = m_touchBar->_action; - m_touchBar->_action = EAction::None; - return action; - } - return EAction::None; - } - void GetSelection(int &left, int &right, int &value) { - left = m_touchBar->_selection.first; - right = m_touchBar->_selection.second; - value = m_touchBar->_pendingValue; - } - void SetSelection(int left, int right, int value) { - if (m_initialized && left == m_touchBar->_selection.first && right == m_touchBar->_selection.second && - value == m_touchBar->_value) - return; - m_initialized = true; - m_touchBar->_selection = std::make_pair(left, right); - m_touchBar->_value = value; - g_Main->GetMainWindow()->setTouchBarProvider((__bridge_retained void *)m_touchBar); - } -}; - -std::unique_ptr NewGameOptionsTouchBar() { return std::make_unique(); } - -} diff --git a/Runtime/CGameState.cpp b/Runtime/CGameState.cpp index ccfbc9a6c..2da53fce2 100644 --- a/Runtime/CGameState.cpp +++ b/Runtime/CGameState.cpp @@ -4,7 +4,7 @@ #include "Runtime/CWorldSaveGameInfo.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/MP1/MP1.hpp" #include @@ -23,32 +23,32 @@ union BitsToDouble { double doub; }; -CScriptLayerManager::CScriptLayerManager(CBitStreamReader& reader, const CWorldSaveGameInfo& saveWorld) { - const u32 bitCount = reader.ReadEncoded(10); - x10_saveLayers.reserve(bitCount); +CScriptLayerManager::CScriptLayerManager(CInputStream& reader, const CWorldSaveGameInfo& saveWorld) { + const u32 bitCount = reader.ReadBits(10); + x10_saveLayers.Reserve(bitCount); for (u32 i = 0; i < bitCount; ++i) { - const bool bit = reader.ReadEncoded(1) != 0; + const bool bit = reader.ReadBits(1) != 0; if (bit) { - x10_saveLayers.setBit(i); + x10_saveLayers.SetBit(i); } else { - x10_saveLayers.unsetBit(i); + x10_saveLayers.UnsetBit(i); } } } -void CScriptLayerManager::PutTo(CBitStreamWriter& writer) const { +void CScriptLayerManager::PutTo(COutputStream& writer) const { u32 totalLayerCount = 0; for (size_t i = 0; i < x0_areaLayers.size(); ++i) { totalLayerCount += GetAreaLayerCount(s32(i)) - 1; } - writer.WriteEncoded(totalLayerCount, 10); + writer.WriteBits(totalLayerCount, 10); for (size_t i = 0; i < x0_areaLayers.size(); ++i) { const u32 count = GetAreaLayerCount(s32(i)); for (u32 l = 1; l < count; ++l) { - writer.WriteEncoded(IsLayerActive(s32(i), s32(l)), 1); + writer.WriteBits(static_cast(IsLayerActive(s32(i), s32(l))), 1); } } } @@ -59,19 +59,20 @@ void CScriptLayerManager::InitializeWorldLayers(const std::vector(); } -CWorldState::CWorldState(CBitStreamReader& reader, CAssetId mlvlId, const CWorldSaveGameInfo& saveWorld) -: x0_mlvlId(mlvlId) { - x4_areaId = TAreaId(reader.ReadEncoded(32)); - x10_desiredAreaAssetId = u32(reader.ReadEncoded(32)); +CWorldState::CWorldState(CInputStream& reader, CAssetId mlvlId, const CWorldSaveGameInfo& saveWorld) +: x0_mlvlId(mlvlId), x4_areaId(TAreaId(reader.ReadBits(32))), x10_desiredAreaAssetId(reader.ReadBits(32)) { x8_mailbox = std::make_shared(reader, saveWorld); xc_mapWorldInfo = std::make_shared(reader, saveWorld, mlvlId); x14_layerState = std::make_shared(reader, saveWorld); } -void CWorldState::PutTo(CBitStreamWriter& writer, const CWorldSaveGameInfo& savw) const { - writer.WriteEncoded(x4_areaId, 32); - writer.WriteEncoded(u32(x10_desiredAreaAssetId.Value()), 32); +void CWorldState::PutTo(COutputStream& writer, const CWorldSaveGameInfo& savw) const { + writer.WriteBits(x4_areaId, 32); + writer.WriteBits(u32(x10_desiredAreaAssetId.Value()), 32); x8_mailbox->PutTo(writer, savw); xc_mapWorldInfo->PutTo(writer, savw, x0_mlvlId); x14_layerState->PutTo(writer); } CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data) { - CBitStreamReader stream(data, 4096); + CMemoryInStream stream(data, 4096, CMemoryInStream::EOwnerShip::NotOwned); GameFileStateInfo ret; for (u32 i = 0; i < 128; i++) { - stream.ReadEncoded(8); + stream.ReadBits(8); } - ret.x14_timestamp = stream.ReadEncoded(32); + ret.x14_timestamp = stream.ReadBits(32); - ret.x20_hardMode = stream.ReadEncoded(1) != 0; - stream.ReadEncoded(1); - const CAssetId origMLVL = u32(stream.ReadEncoded(32)); + ret.x20_hardMode = stream.ReadBits(1) != 0; + stream.ReadBits(1); + const CAssetId origMLVL = u32(stream.ReadBits(32)); ret.x8_mlvlId = origMLVL; BitsToDouble conv; - conv.low = stream.ReadEncoded(32); - conv.high = stream.ReadEncoded(32); + conv.low = stream.ReadBits(32); + conv.high = stream.ReadBits(32); ret.x0_playTime = conv.doub; CPlayerState playerState(stream); @@ -122,7 +121,7 @@ CGameState::GameFileStateInfo CGameState::LoadGameFileState(const u8* data) { ret.xc_health = playerState.GetHealthInfo().GetHP(); u32 itemPercent; - if (origMLVL == 0x158EFE17) + if (origMLVL == 0x158EFE17u) itemPercent = 0; else itemPercent = playerState.CalculateItemCollectionRate() * 100 / playerState.GetPickupTotal(); @@ -148,24 +147,24 @@ CGameState::CGameState() { } } -CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx) : x20c_saveFileIdx(saveIdx) { +CGameState::CGameState(CInputStream& stream, u32 saveIdx) : x20c_saveFileIdx(saveIdx) { x9c_transManager = std::make_shared(); x228_24_hardMode = false; x228_25_initPowerupsAtFirstSpawn = true; for (bool& value : x0_) { - value = stream.ReadEncoded(8) != 0; + value = stream.ReadBits(8) != 0; } - stream.ReadEncoded(32); + stream.ReadBits(32); - x228_24_hardMode = stream.ReadEncoded(1) != 0; - x228_25_initPowerupsAtFirstSpawn = stream.ReadEncoded(1) != 0; - x84_mlvlId = u32(stream.ReadEncoded(32)); + x228_24_hardMode = stream.ReadBits(1) != 0; + x228_25_initPowerupsAtFirstSpawn = stream.ReadBits(1) != 0; + x84_mlvlId = u32(stream.ReadBits(32)); MP1::CMain::EnsureWorldPakReady(x84_mlvlId); BitsToDouble conv; - conv.low = stream.ReadEncoded(32); - conv.high = stream.ReadEncoded(32); + conv.low = stream.ReadBits(32); + conv.high = stream.ReadBits(32); xa0_playTime = conv.doub; x98_playerState = std::make_shared(stream); @@ -185,7 +184,7 @@ CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx) : x20c_saveFileIdx WriteBackupBuf(); } -void CGameState::ReadPersistentOptions(CBitStreamReader& r) { xa8_systemOptions = CPersistentOptions(r); } +void CGameState::ReadPersistentOptions(CInputStream& r) { xa8_systemOptions = r.Get(); } void CGameState::ImportPersistentOptions(const CPersistentOptions& opts) { if (opts.xd0_24_fusionLinked) @@ -212,24 +211,24 @@ void CGameState::ExportPersistentOptions(CPersistentOptions& opts) const { void CGameState::WriteBackupBuf() { x218_backupBuf.resize(940); - CBitStreamWriter w(x218_backupBuf.data(), 940); + CMemoryStreamOut w(x218_backupBuf.data(), 940); PutTo(w); } -void CGameState::PutTo(CBitStreamWriter& writer) { +void CGameState::PutTo(COutputStream& writer) { for (const bool value : x0_) { - writer.WriteEncoded(u32(value), 8); + writer.WriteBits(u32(value), 8); } - writer.WriteEncoded(CBasics::GetTime() / CBasics::TICKS_PER_SECOND, 32); - writer.WriteEncoded(x228_24_hardMode, 1); - writer.WriteEncoded(x228_25_initPowerupsAtFirstSpawn, 1); - writer.WriteEncoded(u32(x84_mlvlId.Value()), 32); + writer.WriteBits(CBasics::GetTime() / CBasics::TICKS_PER_SECOND, 32); + writer.WriteBits(x228_24_hardMode, 1); + writer.WriteBits(x228_25_initPowerupsAtFirstSpawn, 1); + writer.WriteBits(u32(x84_mlvlId.Value()), 32); BitsToDouble conv; conv.doub = xa0_playTime; - writer.WriteEncoded(conv.low, 32); - writer.WriteEncoded(conv.high, 32); + writer.WriteBits(conv.low, 32); + writer.WriteBits(conv.high, 32); x98_playerState->PutTo(writer); x17c_gameOptions.PutTo(writer); diff --git a/Runtime/CGameState.hpp b/Runtime/CGameState.hpp index 86bf1df80..a28719484 100644 --- a/Runtime/CGameState.hpp +++ b/Runtime/CGameState.hpp @@ -4,43 +4,106 @@ #include #include -#include "DataSpec/DNACommon/DNACommon.hpp" - +#include "Runtime/AutoMapper/CMapWorldInfo.hpp" #include "Runtime/CBasics.hpp" #include "Runtime/CGameOptions.hpp" #include "Runtime/CPlayerState.hpp" #include "Runtime/CScriptMailbox.hpp" -#include "Runtime/AutoMapper/CMapWorldInfo.hpp" #include "Runtime/World/CWorld.hpp" #include "Runtime/World/CWorldTransManager.hpp" namespace metaforce { class CSaveWorldMemory; +class WordBitmap { + std::vector x0_words; + size_t x10_bitCount = 0; + +public: + void Reserve(size_t bitCount) { x0_words.reserve((bitCount + 31) / 32); } + [[nodiscard]] size_t GetBitCount() const { return x10_bitCount; } + [[nodiscard]] bool GetBit(size_t idx) const { + size_t wordIdx = idx / 32; + if (wordIdx >= x0_words.size()) { + return false; + } + size_t wordCur = idx % 32; + return ((x0_words[wordIdx] >> wordCur) & 0x1) != 0u; + } + void SetBit(size_t idx) { + size_t wordIdx = idx / 32; + while (wordIdx >= x0_words.size()) { + x0_words.push_back(0); + } + size_t wordCur = idx % 32; + x0_words[wordIdx] |= (1 << wordCur); + x10_bitCount = std::max(x10_bitCount, idx + 1); + } + void UnsetBit(size_t idx) { + size_t wordIdx = idx / 32; + while (wordIdx >= x0_words.size()) { + x0_words.push_back(0); + } + size_t wordCur = idx % 32; + x0_words[wordIdx] &= ~(1 << wordCur); + x10_bitCount = std::max(x10_bitCount, idx + 1); + } + void Clear() { + x0_words.clear(); + x10_bitCount = 0; + } + + class Iterator { + friend class WordBitmap; + const WordBitmap& m_bmp; + size_t m_idx = 0; + Iterator(const WordBitmap& bmp, size_t idx) : m_bmp(bmp), m_idx(idx) {} + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = bool; + using difference_type = std::ptrdiff_t; + using pointer = bool*; + using reference = bool&; + + Iterator& operator++() { + ++m_idx; + return *this; + } + bool operator*() const { return m_bmp.GetBit(m_idx); } + bool operator!=(const Iterator& other) const { return m_idx != other.m_idx; } + }; + [[nodiscard]] Iterator begin() const { return Iterator(*this, 0); } + [[nodiscard]] Iterator end() const { return Iterator(*this, x10_bitCount); } +}; + class CScriptLayerManager { friend class CSaveWorldIntermediate; std::vector x0_areaLayers; - DataSpec::WordBitmap x10_saveLayers; + WordBitmap x10_saveLayers; public: CScriptLayerManager() = default; - CScriptLayerManager(CBitStreamReader& reader, const CWorldSaveGameInfo& saveWorld); + CScriptLayerManager(CInputStream& reader, const CWorldSaveGameInfo& saveWorld); - bool IsLayerActive(int areaIdx, int layerIdx) const { return ((x0_areaLayers[areaIdx].m_layerBits >> layerIdx) & 1); } + [[nodiscard]] bool IsLayerActive(int areaIdx, int layerIdx) const { + return ((x0_areaLayers[areaIdx].m_layerBits >> layerIdx) & 1) != 0u; + } void SetLayerActive(int areaIdx, int layerIdx, bool active) { - if (active) + if (active) { x0_areaLayers[areaIdx].m_layerBits |= uint64_t(1) << layerIdx; - else + } else { x0_areaLayers[areaIdx].m_layerBits &= ~(uint64_t(1) << layerIdx); + } } void InitializeWorldLayers(const std::vector& layers); - u32 GetAreaLayerCount(int areaIdx) const { return x0_areaLayers[areaIdx].m_layerCount; } - u32 GetAreaCount() const { return x0_areaLayers.size(); } + [[nodiscard]] u32 GetAreaLayerCount(int areaIdx) const { return x0_areaLayers[areaIdx].m_layerCount; } + [[nodiscard]] u32 GetAreaCount() const { return x0_areaLayers.size(); } - void PutTo(CBitStreamWriter& writer) const; + void PutTo(COutputStream& writer) const; }; class CWorldState { @@ -53,7 +116,7 @@ class CWorldState { public: explicit CWorldState(CAssetId id); - CWorldState(CBitStreamReader& reader, CAssetId mlvlId, const CWorldSaveGameInfo& saveWorld); + CWorldState(CInputStream& reader, CAssetId mlvlId, const CWorldSaveGameInfo& saveWorld); CAssetId GetWorldAssetId() const { return x0_mlvlId; } void SetAreaId(TAreaId aid) { x4_areaId = aid; } TAreaId GetCurrentAreaId() const { return x4_areaId; } @@ -62,7 +125,7 @@ public: const std::shared_ptr& Mailbox() const { return x8_mailbox; } const std::shared_ptr& MapWorldInfo() const { return xc_mapWorldInfo; } const std::shared_ptr& GetLayerState() const { return x14_layerState; } - void PutTo(CBitStreamWriter& writer, const CWorldSaveGameInfo& savw) const; + void PutTo(COutputStream& writer, const CWorldSaveGameInfo& savw) const; }; class CGameState { @@ -86,7 +149,7 @@ class CGameState { public: CGameState(); - CGameState(CBitStreamReader& stream, u32 saveIdx); + CGameState(CInputStream& stream, u32 saveIdx); void SetCurrentWorldId(CAssetId id); std::shared_ptr GetPlayerState() const { return x98_playerState; } std::shared_ptr GetWorldTransitionManager() const { return x9c_transManager; } @@ -100,7 +163,7 @@ public: CAssetId CurrentWorldAssetId() const { return x84_mlvlId; } void SetHardMode(bool v) { x228_24_hardMode = v; } bool GetHardMode() const { return x228_24_hardMode; } - void ReadPersistentOptions(CBitStreamReader& r); + void ReadPersistentOptions(CInputStream& r); void SetPersistentOptions(const CPersistentOptions& opts) { xa8_systemOptions = opts; } void ImportPersistentOptions(const CPersistentOptions& opts); void ExportPersistentOptions(CPersistentOptions& opts) const; @@ -111,7 +174,7 @@ public: void SetFileIdx(u32 idx) { x20c_saveFileIdx = idx; } void SetCardSerial(u64 serial) { x210_cardSerial = serial; } u64 GetCardSerial() const { return x210_cardSerial; } - void PutTo(CBitStreamWriter& writer); + void PutTo(COutputStream& writer); float GetHardModeDamageMultiplier() const; float GetHardModeWeaponMultiplier() const; void InitializeMemoryWorlds(); diff --git a/Runtime/CInfiniteLoopDetector.cpp b/Runtime/CInfiniteLoopDetector.cpp new file mode 100644 index 000000000..0d4c2b56c --- /dev/null +++ b/Runtime/CInfiniteLoopDetector.cpp @@ -0,0 +1,37 @@ +#include "Runtime/CInfiniteLoopDetector.hpp" +#include + +namespace metaforce { +namespace { +logvisor::Module Log("CInfiniteLoopDetector"); +std::chrono::system_clock::time_point g_WatchDog = std::chrono::system_clock::now(); +std::mutex g_mutex; +} // namespace + +CInfiniteLoopDetector::CInfiniteLoopDetector(int duration) +: m_duration(duration), m_futureObj(m_stopRequested.get_future()) {} + +bool CInfiniteLoopDetector::stopRequested() const { + return m_futureObj.wait_for(std::chrono::milliseconds(0)) != std::future_status::timeout; +} +void CInfiniteLoopDetector::run() { + std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); + while (!stopRequested()) { + if (std::chrono::duration_cast(std::chrono::system_clock::now() - start) > + std::chrono::milliseconds(m_duration)) { + std::lock_guard guard(g_mutex); + if (std::chrono::duration_cast(std::chrono::system_clock::now() - g_WatchDog) > + std::chrono::milliseconds(m_duration)) { + Log.report(logvisor::Fatal, FMT_STRING("INFINITE LOOP DETECTED!")); + } + } + } +} + +void CInfiniteLoopDetector::UpdateWatchDog(std::chrono::system_clock::time_point time) { + std::lock_guard guard(g_mutex); + g_WatchDog = time; +} + +void CInfiniteLoopDetector::stop() { m_stopRequested.set_value(); } +} // namespace metaforce diff --git a/Runtime/CInfiniteLoopDetector.hpp b/Runtime/CInfiniteLoopDetector.hpp new file mode 100644 index 000000000..92c89e1f0 --- /dev/null +++ b/Runtime/CInfiniteLoopDetector.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include +#include + +namespace metaforce { +class CInfiniteLoopDetector { + int m_duration = 0; + std::mutex m_mutex; + std::promise m_stopRequested; + std::future m_futureObj; + bool stopRequested() const; +public: + explicit CInfiniteLoopDetector(int duration=1000); + void run(); + void stop(); + static void UpdateWatchDog(std::chrono::system_clock::time_point WatchDog); +}; +} \ No newline at end of file diff --git a/Runtime/CMain.cpp b/Runtime/CMain.cpp index cb9f8703a..d4e7fa344 100644 --- a/Runtime/CMain.cpp +++ b/Runtime/CMain.cpp @@ -1,33 +1,41 @@ #include #include #include -#include - -#include "boo/boo.hpp" -#include "logvisor/logvisor.hpp" +#include #include "ImGuiEngine.hpp" #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/MP1/MP1.hpp" -#include "amuse/BooBackend.hpp" +#include "Runtime/ConsoleVariables/FileStoreManager.hpp" +#include "Runtime/ConsoleVariables/CVarManager.hpp" +#include "Runtime/CInfiniteLoopDetector.hpp" +//#include "amuse/BooBackend.hpp" + +#include "logvisor/logvisor.hpp" + +#ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include +#endif #include "../version.h" -//#include -//#pragma STDC FENV_ACCESS ON +// #include +// #pragma STDC FENV_ACCESS ON -/* Static reference to dataspec additions - * (used by MSVC to definitively link DataSpecs) */ -#include "DataSpecRegistry.hpp" +#include +#include +#include +#include using namespace std::literals; -static logvisor::Module AthenaLog("Athena"); -static void AthenaExc(athena::error::Level level, const char* file, const char*, int line, fmt::string_view fmt, - fmt::format_args args) { - AthenaLog.vreport(logvisor::Level(level), fmt, args); -} - class Limiter { using delta_clock = std::chrono::high_resolution_clock; using duration_t = std::chrono::nanoseconds; @@ -98,9 +106,7 @@ private: } while (count.QuadPart < end); } #else - void NanoSleep(const duration_t duration) { - std::this_thread::sleep_for(duration); - } + void NanoSleep(const duration_t duration) { std::this_thread::sleep_for(duration); } #endif }; @@ -143,252 +149,110 @@ static std::string CPUFeatureString(const zeus::CPUInfo& cpuInf) { return features; } -struct WindowCallback : boo::IWindowCallback { - friend struct Application; - +struct Application { private: - bool m_fullscreenToggleRequested = false; - boo::SWindowRect m_lastRect; - bool m_rectDirty = false; - bool m_windowInvalid = false; - ImGuiWindowCallback m_imguiCallback; - - void resized(const boo::SWindowRect& rect, bool sync) override { - m_lastRect = rect; - m_rectDirty = true; - m_imguiCallback.resized(rect, sync); - } - - void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override { - if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->mouseDown(coord, button, mods); - } - } - m_imguiCallback.mouseDown(coord, button, mods); - } - - void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) override { - if (g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->mouseUp(coord, button, mods); - } - } - m_imguiCallback.mouseUp(coord, button, mods); - } - - void mouseMove(const boo::SWindowCoord& coord) override { - if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->mouseMove(coord); - } - } - m_imguiCallback.mouseMove(coord); - } - - void mouseEnter(const boo::SWindowCoord& coord) override { m_imguiCallback.mouseEnter(coord); } - - void mouseLeave(const boo::SWindowCoord& coord) override { m_imguiCallback.mouseLeave(coord); } - - void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) override { - if (!ImGuiWindowCallback::m_mouseCaptured && g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->scroll(coord, scroll); - } - } - m_imguiCallback.scroll(coord, scroll); - } - - void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat) override { - if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->charKeyDown(charCode, mods, isRepeat); - } - } - m_imguiCallback.charKeyDown(charCode, mods, isRepeat); - } - - void charKeyUp(unsigned long charCode, boo::EModifierKey mods) override { - if (g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->charKeyUp(charCode, mods); - } - } - m_imguiCallback.charKeyUp(charCode, mods); - } - - void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat) override { - if (!ImGuiWindowCallback::m_keyboardCaptured && g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->specialKeyDown(key, mods, isRepeat); - } - } - if (True(mods & boo::EModifierKey::Alt)) { - if (key == boo::ESpecialKey::Enter) { - m_fullscreenToggleRequested = true; - } else if (key == boo::ESpecialKey::F4) { - m_windowInvalid = true; - } - } - m_imguiCallback.specialKeyDown(key, mods, isRepeat); - } - - void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods) override { - if (g_mainMP1) { - if (MP1::CGameArchitectureSupport* as = g_mainMP1->GetArchSupport()) { - as->specialKeyUp(key, mods); - } - } - m_imguiCallback.specialKeyUp(key, mods); - } - - void destroyed() override { m_windowInvalid = true; } -}; - -struct Application : boo::IApplicationCallback { -private: - std::shared_ptr m_window; - WindowCallback m_windowCallback; - hecl::Runtime::FileStoreManager& m_fileMgr; - hecl::CVarManager& m_cvarManager; - hecl::CVarCommons& m_cvarCommons; + int m_argc; + char** m_argv; + FileStoreManager& m_fileMgr; + CVarManager& m_cvarManager; + CVarCommons& m_cvarCommons; ImGuiConsole m_imGuiConsole; - std::string m_errorString; - boo::ObjToken m_renderTex; std::string m_deferredProject; - std::unique_ptr m_proj; - std::optional m_amuseAllocWrapper; - std::unique_ptr m_voiceEngine; - std::unique_ptr m_pipelineConv; + bool m_projectInitialized = false; + //std::optional m_amuseAllocWrapper; + //std::unique_ptr m_voiceEngine; Limiter m_limiter{}; - std::atomic_bool m_running = {true}; - bool m_noShaderWarmup = false; - bool m_imGuiInitialized = false; bool m_firstFrame = true; + bool m_fullscreenToggleRequested = false; + bool m_quitRequested = false; + bool m_lAltHeld = false; using delta_clock = std::chrono::high_resolution_clock; - std::chrono::time_point m_prevFrameTime; + delta_clock::time_point m_prevFrameTime; + + std::vector m_deferredControllers; // used to capture controllers added before CInputGenerator + // is built, i.e during initialization public: - Application(hecl::Runtime::FileStoreManager& fileMgr, hecl::CVarManager& cvarMgr, hecl::CVarCommons& cvarCmns) - : m_fileMgr(fileMgr), m_cvarManager(cvarMgr), m_cvarCommons(cvarCmns), m_imGuiConsole(cvarMgr, cvarCmns) {} + Application(int argc, char** argv, FileStoreManager& fileMgr, CVarManager& cvarMgr, CVarCommons& cvarCmns) + : m_argc(argc) + , m_argv(argv) + , m_fileMgr(fileMgr) + , m_cvarManager(cvarMgr) + , m_cvarCommons(cvarCmns) + , m_imGuiConsole(cvarMgr, cvarCmns) {} - int appMain(boo::IApplication* app) override { - initialize(app); + void onAppLaunched(const AuroraInfo& info) noexcept { + initialize(); - m_window = app->newWindow("Metaforce"sv); - if (!m_window) { - return 1; - } - m_window->setCallback(&m_windowCallback); - m_window->showWindow(); + VISetWindowTitle( + fmt::format(FMT_STRING("Metaforce {} [{}]"), METAFORCE_WC_DESCRIBE, backend_name(info.backend)).c_str()); - boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory(); - m_window->setTitle(fmt::format(FMT_STRING("Metaforce {} [{}]"), METAFORCE_WC_DESCRIBE, gfxF->platformName())); +// m_voiceEngine = boo::NewAudioVoiceEngine("metaforce", "Metaforce"); +// m_voiceEngine->setVolume(0.7f); +// m_amuseAllocWrapper.emplace(*m_voiceEngine); - boo::SWindowRect rect = m_window->getWindowFrame(); - m_windowCallback.m_lastRect = rect; - gfxF->commitTransaction([&](boo::IGraphicsDataFactory::Context& ctx) { - m_renderTex = ctx.newRenderTexture(rect.size[0], rect.size[1], boo::TextureClampMode::ClampToEdge, 3, 3); - return true; - } BooTrace); - - m_pipelineConv = hecl::NewPipelineConverter(gfxF); - hecl::conv = m_pipelineConv.get(); - - m_voiceEngine = boo::NewAudioVoiceEngine(); - m_voiceEngine->setVolume(0.7f); - m_amuseAllocWrapper.emplace(*m_voiceEngine); - - hecl::ProjectPath projectPath; - for (const auto& arg : app->getArgs()) { - hecl::Sstat theStat; - if (!hecl::Stat((arg + "/out").c_str(), &theStat) && S_ISDIR(theStat.st_mode)) { - hecl::ProjectRootPath rootPath(arg); - hecl::Database::Project tmp(rootPath); // Force project creation - } - if (m_deferredProject.empty() && hecl::SearchForProject(arg)) +#if TARGET_OS_IOS || TARGET_OS_TV + m_deferredProject = std::string{m_fileMgr.getStoreRoot()} + "game.iso"; +#else + bool inArg = false; + for (int i = 1; i < m_argc; ++i) { + std::string arg = m_argv[i]; + if (m_deferredProject.empty() && !arg.starts_with('-') && !arg.starts_with('+') && CBasics::IsDir(arg.c_str())) m_deferredProject = arg; - if (arg == "--no-shader-warmup") - m_noShaderWarmup = true; - else if (arg == "--no-sound") - m_voiceEngine->setVolume(0.f); - } - - if (m_deferredProject.empty()) { - /* Default behavior - search upwards for packaged project containing the program */ - if (hecl::ProjectRootPath projRoot = hecl::SearchForProject(ExeDir)) { - std::string rootPath(projRoot.getAbsolutePath()); - hecl::Sstat theStat; - if (hecl::Stat((rootPath + "/out/files/MP1/Metroid1.upak").c_str(), &theStat) == 0 && S_ISREG(theStat.st_mode)) - m_deferredProject = rootPath + "/out"; + else if (arg == "--no-sound") { + // m_voiceEngine->setVolume(0.f); } } +#endif - while (m_running) { - onAppIdle(); - } - - if (m_imGuiInitialized) { - m_imGuiConsole.Shutdown(); - ImGuiEngine::Shutdown(); - } - if (g_mainMP1) { - g_mainMP1->Shutdown(); - } - g_mainMP1.reset(); - m_renderTex.reset(); - m_pipelineConv.reset(); - if (m_window) { - m_window->getCommandQueue()->stopRenderer(); - } - m_cvarManager.serialize(); - m_voiceEngine.reset(); - m_amuseAllocWrapper.reset(); - CDvdFile::Shutdown(); - return 0; + //m_voiceEngine->startPump(); } - void initialize(boo::IApplication* app) { + void initialize() { zeus::detectCPU(); - for (const auto& arg : app->getArgs()) { - if (arg.find("--verbosity=") == 0 || arg.find("-v=") == 0) { - hecl::VerbosityLevel = atoi(arg.substr(arg.find_last_of('=') + 1).c_str()); - hecl::LogModule.report(logvisor::Info, FMT_STRING("Set verbosity level to {}"), hecl::VerbosityLevel); - } - } - const zeus::CPUInfo& cpuInf = zeus::cpuFeatures(); Log.report(logvisor::Info, FMT_STRING("CPU Name: {}"), cpuInf.cpuBrand); Log.report(logvisor::Info, FMT_STRING("CPU Vendor: {}"), cpuInf.cpuVendor); Log.report(logvisor::Info, FMT_STRING("CPU Features: {}"), CPUFeatureString(cpuInf)); } - void onAppIdle() noexcept { - if (!m_deferredProject.empty()) { - std::string subPath; - hecl::ProjectRootPath projPath = hecl::SearchForProject(m_deferredProject, subPath); - if (projPath) { - m_proj = std::make_unique(projPath); - m_deferredProject.clear(); - hecl::ProjectPath projectPath{m_proj->getProjectWorkingPath(), "out/files/MP1"}; - CDvdFile::Initialize(projectPath); - } else { - Log.report(logvisor::Error, FMT_STRING("Project doesn't exist at '{}'"), m_deferredProject); - m_errorString = fmt::format(FMT_STRING("Project not found at '{}'"), m_deferredProject); - m_deferredProject.clear(); + void onSdlEvent(const SDL_Event& event) noexcept { + switch (event.type) { + case SDL_KEYDOWN: + m_lAltHeld = event.key.keysym.sym == SDLK_LALT; + // Toggle fullscreen on ALT+ENTER + if (event.key.keysym.sym == SDLK_RETURN && (event.key.keysym.mod & KMOD_ALT) != 0u && event.key.repeat == 0u) { + m_cvarCommons.m_fullscreen->fromBoolean(!m_cvarCommons.m_fullscreen->toBoolean()); + } + break; + case SDL_KEYUP: + if (m_lAltHeld && event.key.keysym.sym == SDLK_LALT) { + m_imGuiConsole.ToggleVisible(); + m_lAltHeld = false; } } - if (!m_proj && m_errorString.empty()) { - m_errorString = "Project directory not specified"s; - } + } - if (m_windowCallback.m_windowInvalid) { - m_running.store(false); - return; + bool onAppIdle(float realDt) noexcept { +#ifdef NDEBUG + /* Ping the watchdog to let it know we're still alive */ + CInfiniteLoopDetector::UpdateWatchDog(std::chrono::system_clock::now()); +#endif + + if (!m_projectInitialized && !m_deferredProject.empty()) { + Log.report(logvisor::Info, FMT_STRING("Loading game from '{}'"), m_deferredProject); + if (CDvdFile::Initialize(m_deferredProject)) { + m_projectInitialized = true; + m_cvarCommons.m_lastDiscPath->fromLiteral(m_deferredProject); + } else { + Log.report(logvisor::Error, FMT_STRING("Failed to open disc image '{}'"), m_deferredProject); + m_imGuiConsole.m_errorString = fmt::format(FMT_STRING("Failed to open disc image '{}'"), m_deferredProject); + } + m_deferredProject.clear(); } const auto targetFrameTime = getTargetFrameTime(); @@ -404,10 +268,6 @@ public: m_limiter.Reset(); } else { // No more to load, and we're under frame time - { - OPTICK_EVENT("Wait for Retrace"); - m_window->waitForRetrace(); - } { OPTICK_EVENT("Sleep"); m_limiter.Sleep(targetFrameTime); @@ -415,126 +275,131 @@ public: } OPTICK_FRAME("MainThread"); - CGraphics::SetCommitResourcesAsLazy(m_cvarCommons.m_lazyCommitResources->toBoolean()); - - boo::SWindowRect rect = m_windowCallback.m_lastRect; - rect.location = {0, 0}; - boo::IGraphicsCommandQueue* gfxQ = m_window->getCommandQueue(); - if (m_windowCallback.m_rectDirty) { - gfxQ->resizeRenderTexture(m_renderTex, rect.size[0], rect.size[1]); - CGraphics::SetViewportResolution({rect.size[0], rect.size[1]}); - m_windowCallback.m_rectDirty = false; - } else if (m_firstFrame) { - CGraphics::SetViewportResolution({rect.size[0], rect.size[1]}); - } // Check if fullscreen has been toggled, if so set the fullscreen cvar accordingly - if (m_windowCallback.m_fullscreenToggleRequested) { + if (m_fullscreenToggleRequested) { m_cvarCommons.m_fullscreen->fromBoolean(!m_cvarCommons.getFullscreen()); - m_windowCallback.m_fullscreenToggleRequested = false; + m_fullscreenToggleRequested = false; } // Check if the user has modified the fullscreen CVar, if so set fullscreen state accordingly if (m_cvarCommons.m_fullscreen->isModified()) { - m_window->setFullscreen(m_cvarCommons.getFullscreen()); + VISetWindowFullscreen(m_cvarCommons.getFullscreen()); } // Let CVarManager inform all CVar listeners of the CVar's state and clear all mdoified flags if necessary m_cvarManager.proc(); - boo::IGraphicsDataFactory* gfxF = m_window->getMainContextDataFactory(); - float scale = std::floor(m_window->getVirtualPixelFactor() * 4.f) / 4.f; - if (!g_mainMP1 && m_proj) { - g_mainMP1.emplace(nullptr, nullptr, gfxF, gfxQ, m_renderTex.get()); - g_mainMP1->Init(m_fileMgr, &m_cvarManager, m_window.get(), m_voiceEngine.get(), *m_amuseAllocWrapper); - if (!m_noShaderWarmup) { - g_mainMP1->WarmupShaders(); + if (!g_mainMP1 && m_projectInitialized) { + g_mainMP1.emplace(nullptr, nullptr); + auto result = + g_mainMP1->Init(m_argc, m_argv, m_fileMgr, &m_cvarManager); + if (!result.empty()) { + Log.report(logvisor::Error, FMT_STRING("{}"), result); + m_imGuiConsole.m_errorString = result; + g_mainMP1.reset(); + CDvdFile::Shutdown(); + m_projectInitialized = false; + m_cvarCommons.m_lastDiscPath->fromLiteral(""sv); } } - if (!m_imGuiInitialized) { - ImGuiEngine::Initialize(gfxF, m_window.get(), scale, m_fileMgr.getStoreRoot()); - m_imGuiInitialized = true; - } float dt = 1 / 60.f; - float realDt = dt; - auto now = delta_clock::now(); - if (m_firstFrame) { - m_firstFrame = false; - } else { - using delta_duration = std::chrono::duration>; - realDt = std::chrono::duration_cast(now - m_prevFrameTime).count(); - if (m_cvarCommons.m_variableDt->toBoolean()) { - dt = std::min(realDt, 1 / 30.f); - } + if (m_cvarCommons.m_variableDt->toBoolean()) { + dt = std::min(realDt, 1 / 30.f); } - m_prevFrameTime = now; - - ImGuiEngine::Begin(realDt, scale); + m_imGuiConsole.PreUpdate(); if (g_mainMP1) { - m_imGuiConsole.PreUpdate(); +// if (m_voiceEngine) { +// m_voiceEngine->lockPump(); +// } if (g_mainMP1->Proc(dt)) { - m_running.store(false); - return; + return false; } - m_imGuiConsole.PostUpdate(); - } else { - m_imGuiConsole.ShowAboutWindow(false, m_errorString); +// if (m_voiceEngine) { +// m_voiceEngine->unlockPump(); +// } + } + m_imGuiConsole.PostUpdate(); + if (!g_mainMP1 && m_imGuiConsole.m_gameDiscSelected) { + std::optional result; + m_imGuiConsole.m_gameDiscSelected.swap(result); + m_deferredProject = std::move(*result); } - { - OPTICK_EVENT("Flush"); - CGraphics::SetCommitResourcesAsLazy(false); - } - - { - OPTICK_EVENT("Draw"); - gfxQ->setRenderTarget(m_renderTex); - gfxQ->clearTarget(); - gfxQ->setViewport(rect); - gfxQ->setScissor(rect); - if (g_Renderer != nullptr) { - g_Renderer->BeginScene(); + if (m_quitRequested || m_imGuiConsole.m_quitRequested || m_cvarManager.restartRequired()) { + if (g_mainMP1) { + g_mainMP1->Quit(); + } else { + return false; } + } + return true; + } + + void onAppDraw() noexcept { + OPTICK_EVENT("Draw"); + if (g_Renderer != nullptr) { + g_Renderer->BeginScene(); if (g_mainMP1) { g_mainMP1->Draw(); } - if (g_Renderer != nullptr) { - g_Renderer->EndScene(); - } + g_Renderer->EndScene(); } + } - { - OPTICK_EVENT("ImGui Draw"); - ImGuiEngine::End(); - ImGuiEngine::Draw(gfxQ); - } - - { - OPTICK_EVENT("Execute"); - gfxQ->execute(); - } - - gfxQ->resolveDisplay(m_renderTex); - - if (m_voiceEngine) { - m_voiceEngine->pumpAndMixVoices(); - } - CBooModel::ClearModelUniformCounters(); + void onAppPostDraw() noexcept { + OPTICK_EVENT("PostDraw"); +// if (m_voiceEngine) { +// m_voiceEngine->pumpAndMixVoices(); +// } +#ifdef EMSCRIPTEN + CDvdFile::DoWork(); +#endif CGraphics::TickRenderTimings(); ++logvisor::FrameIndex; } - void appQuitting(boo::IApplication* /*unused*/) override { m_running.store(false); } + void onAppWindowResized(const AuroraWindowSize& size) noexcept { + if (size.width != m_cvarCommons.getWindowSize().x || size.height != m_cvarCommons.getWindowSize().y) { + m_cvarCommons.m_windowSize->fromVec2i(zeus::CVector2i(size.width, size.height)); + } - [[nodiscard]] std::string getGraphicsApi() const { return m_cvarCommons.getGraphicsApi(); } + CGraphics::SetViewportResolution({static_cast(size.fb_width), static_cast(size.fb_height)}); + } - [[nodiscard]] uint32_t getSamples() const { return m_cvarCommons.getSamples(); } + void onAppWindowMoved(const AuroraWindowPos& pos) { + if (pos.x > 0 && pos.y > 0 && (pos.x != m_cvarCommons.getWindowPos().x || pos.y != m_cvarCommons.getWindowPos().y)) { + m_cvarCommons.m_windowPos->fromVec2i(zeus::CVector2i(pos.x, pos.y)); + } + } - [[nodiscard]] uint32_t getAnisotropy() const { return m_cvarCommons.getAnisotropy(); } + void onAppDisplayScaleChanged(float scale) noexcept { ImGuiEngine_Initialize(scale); } - [[nodiscard]] bool getDeepColor() const { return m_cvarCommons.getDeepColor(); } + void onControllerAdded(uint32_t which) noexcept { m_imGuiConsole.ControllerAdded(which); } + + void onControllerRemoved(uint32_t which) noexcept { m_imGuiConsole.ControllerRemoved(which); } + + void onAppExiting() noexcept { + m_imGuiConsole.Shutdown(); +// if (m_voiceEngine) { +// m_voiceEngine->unlockPump(); +// m_voiceEngine->stopPump(); +// } + if (g_mainMP1) { + g_mainMP1->Shutdown(); + } + g_mainMP1.reset(); + m_cvarManager.serialize(); +// m_amuseAllocWrapper.reset(); +// m_voiceEngine.reset(); + CDvdFile::Shutdown(); + } + + void onImGuiInit(float scale) noexcept { ImGuiEngine_Initialize(scale); } + + void onImGuiAddTextures() noexcept { ImGuiEngine_AddTextures(); } [[nodiscard]] std::chrono::nanoseconds getTargetFrameTime() const { if (m_cvarCommons.getVariableFrameTime()) { @@ -546,10 +411,7 @@ public: } // namespace metaforce -static char CwdBuf[1024]; -std::string ExeDir; - -static void SetupBasics(bool logging) { +static void SetupBasics() { auto result = zeus::validateCPU(); if (!result.first) { #if _WIN32 && !WINDOWS_STORE @@ -564,99 +426,189 @@ static void SetupBasics(bool logging) { exit(1); } - logvisor::RegisterStandardExceptions(); - if (logging) - logvisor::RegisterConsoleLogger(); - atSetExceptionHandler(AthenaExc); - #if SENTRY_ENABLED - hecl::Runtime::FileStoreManager fileMgr{"sentry-native-metaforce"}; - std::string cacheDir{fileMgr.getStoreRoot()}; + std::string cacheDir{metaforce::FileStoreManager::instance()->getStoreRoot()}; logvisor::RegisterSentry("metaforce", METAFORCE_WC_DESCRIBE, cacheDir.c_str()); #endif } static bool IsClientLoggingEnabled(int argc, char** argv) { - for (int i = 1; i < argc; ++i) - if (!hecl::StrNCmp(argv[i], "-l", 2)) +#ifdef EMSCRIPTEN + return true; +#else + for (int i = 1; i < argc; ++i) { + if (!strncmp(argv[i], "-l", 2)) { return true; + } + } return false; +#endif } +static std::unique_ptr g_app; +static SDL_Window* g_window; +static bool g_paused; + +static void aurora_log_callback(AuroraLogLevel level, const char* message, unsigned int len) { + logvisor::Level severity = logvisor::Fatal; + switch (level) { + case LOG_DEBUG: + case LOG_INFO: + severity = logvisor::Info; + break; + case LOG_WARNING: + severity = logvisor::Warning; + break; + case LOG_ERROR: + severity = logvisor::Error; + break; + default: + break; + } + if (level == LOG_FATAL) { + auto msg = fmt::format(FMT_STRING("Metaforce encountered an internal error:\n\n{}"), message); + SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Metaforce", msg.c_str(), g_window); + } + metaforce::Log.report(severity, FMT_STRING("{}"), message); +} + +static void aurora_imgui_init_callback(const AuroraWindowSize* size) { g_app->onImGuiInit(size->scale); } + #if !WINDOWS_STORE int main(int argc, char** argv) { - //TODO: This seems to fix a lot of weird issues with rounding - // but breaks animations, need to research why this is the case - // for now it's disabled - //fesetround(FE_TOWARDZERO); - if (argc > 1 && !hecl::StrCmp(argv[1], "--dlpackage")) { + // TODO: This seems to fix a lot of weird issues with rounding + // but breaks animations, need to research why this is the case + // for now it's disabled + // fesetround(FE_TOWARDZERO); + if (argc > 1 && !strcmp(argv[1], "--dlpackage")) { fmt::print(FMT_STRING("{}\n"), METAFORCE_DLPACKAGE); return 100; } - SetupBasics(IsClientLoggingEnabled(argc, argv)); - hecl::Runtime::FileStoreManager fileMgr{"metaforce"}; - hecl::CVarManager cvarMgr{fileMgr}; - hecl::CVarCommons cvarCmns{cvarMgr}; + metaforce::FileStoreManager fileMgr{"AxioDL", "metaforce"}; + SetupBasics(); std::vector args; - for (int i = 1; i < argc; ++i) + for (int i = 1; i < argc; ++i) { args.emplace_back(argv[i]); - cvarMgr.parseCommandLine(args); + } - std::string logFile = cvarCmns.getLogFile(); + auto icon = metaforce::GetIcon(); + + // FIXME: logvisor needs to copy this std::string logFilePath; - if (!logFile.empty()) { - std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); - char buf[100]; - std::strftime(buf, 100, "%Y-%m-%d_%H-%M-%S", std::localtime(&time)); - logFilePath = fmt::format(FMT_STRING("{}/{}-{}"), fileMgr.getStoreRoot(), buf, logFile); - logvisor::RegisterFileLogger(logFilePath.c_str()); - } - if (char* cwd = hecl::Getcwd(CwdBuf, 1024)) { - if (hecl::PathRelative(argv[0])) - ExeDir = std::string(cwd) + '/'; - std::string Argv0(argv[0]); - std::string::size_type lastIdx = Argv0.find_last_of("/\\"); - if (lastIdx != std::string::npos) - ExeDir.insert(ExeDir.end(), Argv0.begin(), Argv0.begin() + lastIdx); - } + bool restart = false; + do { + metaforce::CVarManager cvarMgr{fileMgr}; + metaforce::CVarCommons cvarCmns{cvarMgr}; + cvarMgr.parseCommandLine(args); - /* Handle -j argument */ - hecl::SetCpuCountOverride(argc, argv); - - metaforce::Application appCb(fileMgr, cvarMgr, cvarCmns); - int ret = boo::ApplicationRun(boo::IApplication::EPlatformType::Auto, appCb, "metaforce", "Metaforce", argv[0], args, - appCb.getGraphicsApi(), appCb.getSamples(), appCb.getAnisotropy(), appCb.getDeepColor(), - false); - return ret; -} + if (!restart) { + // TODO add clear loggers func to logvisor so we can recreate loggers on restart + bool logging = IsClientLoggingEnabled(argc, argv); +#if _WIN32 + if (logging && GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_UNKNOWN) { + logvisor::CreateWin32Console(); + } #endif + logvisor::RegisterStandardExceptions(); + if (logging) { + logvisor::RegisterConsoleLogger(); + } -#if WINDOWS_STORE -#include "boo/UWPViewProvider.hpp" -using namespace Windows::ApplicationModel::Core; + std::string logFile = cvarCmns.getLogFile(); + if (!logFile.empty()) { + std::time_t time = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()); + char buf[100]; + std::strftime(buf, 100, "%Y-%m-%d_%H-%M-%S", std::localtime(&time)); + logFilePath = fmt::format(FMT_STRING("{}/{}-{}"), fileMgr.getStoreRoot(), buf, logFile); + logvisor::RegisterFileLogger(logFilePath.c_str()); + } + } -[Platform::MTAThread] int WINAPIV main(Platform::Array ^ params) { - SetupBasics(false); - metaforce::Application appCb; - auto viewProvider = ref new boo::ViewProvider(appCb, "metaforce", "Metaforce", "metaforce", params, false); - CoreApplication::Run(viewProvider); + g_app = std::make_unique(argc, argv, fileMgr, cvarMgr, cvarCmns); + std::string configPath{fileMgr.getStoreRoot()}; + + + const AuroraConfig config{ + .appName = "Metaforce", + .configPath = configPath.c_str(), + .desiredBackend = metaforce::backend_from_string(cvarCmns.getGraphicsApi()), + .msaa = cvarCmns.getSamples(), + .maxTextureAnisotropy = static_cast(cvarCmns.getAnisotropy()), + .startFullscreen = cvarCmns.getFullscreen(), + .allowJoystickBackgroundEvents = cvarCmns.getAllowJoystickInBackground(), + .windowPosX = cvarCmns.getWindowPos().x, + .windowPosY = cvarCmns.getWindowPos().y, + .windowWidth = static_cast(cvarCmns.getWindowSize().x < 0 ? 0 : cvarCmns.getWindowSize().x), + .windowHeight = static_cast(cvarCmns.getWindowSize().y < 0 ? 0 : cvarCmns.getWindowSize().y), + .iconRGBA8 = icon.data.get(), + .iconWidth = icon.width, + .iconHeight = icon.height, + .logCallback = aurora_log_callback, + .imGuiInitCallback = aurora_imgui_init_callback, + }; + const auto info = aurora_initialize(argc, argv, &config); + g_window = info.window; + g_app->onImGuiAddTextures(); + g_app->onAppLaunched(info); + g_app->onAppWindowResized(info.windowSize); + while (!cvarMgr.restartRequired()) { + const auto* event = aurora_update(); + bool exiting = false; + while (event != nullptr && event->type != AURORA_NONE) { + switch (event->type) { + case AURORA_EXIT: + exiting = true; + break; + case AURORA_SDL_EVENT: + g_app->onSdlEvent(event->sdl); + break; + case AURORA_WINDOW_RESIZED: + g_app->onAppWindowResized(event->windowSize); + break; + case AURORA_WINDOW_MOVED: + g_app->onAppWindowMoved(event->windowPos); + break; + case AURORA_CONTROLLER_ADDED: + g_app->onControllerAdded(event->controller); + break; + case AURORA_CONTROLLER_REMOVED: + g_app->onControllerRemoved(event->controller); + break; + case AURORA_PAUSED: + g_paused = true; + break; + case AURORA_UNPAUSED: + g_paused = false; + break; + default: + break; + } + if (exiting) { + break; + } + ++event; + } + if (exiting) { + break; + } + if (g_paused) { + continue; + } + g_app->onAppIdle(1.f / 60.f /* TODO */); + aurora_begin_frame(); + g_app->onAppDraw(); + aurora_end_frame(); + g_app->onAppPostDraw(); + } + g_app->onAppExiting(); + aurora_shutdown(); + g_app.reset(); + + restart = cvarMgr.restartRequired(); + } while (restart); return 0; } - -#elif _WIN32 -#include -#include - -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int) { - int argc = 0; - char** argv = nullptr; - nowide::args _(argc, argv); - const DWORD outType = GetFileType(GetStdHandle(STD_ERROR_HANDLE)); - if (IsClientLoggingEnabled(argc, argv) && outType == FILE_TYPE_UNKNOWN) - logvisor::CreateWin32Console(); - return main(argc, argv); -} #endif diff --git a/Runtime/CMakeLists.txt b/Runtime/CMakeLists.txt index f7df2fb4f..02dedca35 100644 --- a/Runtime/CMakeLists.txt +++ b/Runtime/CMakeLists.txt @@ -24,14 +24,13 @@ add_subdirectory(Particle) if (WIN32) list(APPEND PLAT_SRCS CMemoryCardSysWin.cpp) -elseif (APPLE) - list(APPEND PLAT_SRCS CMemoryCardSysOSX.cpp) else () list(APPEND PLAT_SRCS CMemoryCardSysNix.cpp) endif () +find_package(Python3 COMPONENTS Interpreter REQUIRED) add_custom_command(OUTPUT TCastTo.hpp TCastTo.cpp DEPENDS MkCastTo.py - COMMAND python ARGS ${CMAKE_CURRENT_SOURCE_DIR}/MkCastTo.py + COMMAND ${Python3_EXECUTABLE} ARGS ${CMAKE_CURRENT_SOURCE_DIR}/MkCastTo.py WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating cast functions") @@ -39,15 +38,6 @@ add_subdirectory(MP1) add_subdirectory(MP2) add_subdirectory(MP3) -if (APPLE) - set_source_files_properties(MP1/CFrontEndUITouchBarMac.mm - MP1/CSaveGameScreenTouchBarMac.mm - CGameOptionsTouchBarMac.mm - PROPERTIES COMPILE_FLAGS -fobjc-arc) - bintoc(startButton.cpp Resources/startButton@2x.png START_BUTTON_2X) - list(APPEND PLAT_SRCS startButton.cpp CGameOptionsTouchBarMac.mm) -endif () - set(CAST_TO_SOURCES MkCastTo.py TCastTo.hpp TCastTo.cpp) @@ -70,9 +60,37 @@ set(RUNTIME_SOURCES_B ${PARTICLE_SOURCES} ${WORLD_SOURCES} ${WEAPON_SOURCES} - ITweak.hpp + CInfiniteLoopDetector.hpp CInfiniteLoopDetector.cpp + ConsoleVariables/FileStoreManager.hpp ConsoleVariables/FileStoreManager.cpp + ConsoleVariables/CVar.hpp ConsoleVariables/CVar.cpp + ConsoleVariables/CVarManager.hpp ConsoleVariables/CVarManager.cpp + ConsoleVariables/CVarCommons.hpp ConsoleVariables/CVarCommons.cpp + Tweaks/ITweak.hpp + Tweaks/ITweakAutoMapper.hpp + Tweaks/ITweakBall.hpp + Tweaks/ITweakGame.hpp + Tweaks/ITweakGui.hpp + Tweaks/ITweakGuiColors.hpp + Tweaks/ITweakGunRes.hpp + Tweaks/ITweakParticle.hpp + Tweaks/ITweakPlayer.hpp + Tweaks/ITweakPlayerControl.hpp + Tweaks/ITweakPlayerGun.hpp Tweaks/ITweakPlayerGun.cpp + Tweaks/ITweakPlayerRes.hpp + Tweaks/ITweakSlideShow.hpp + Tweaks/ITweakTargeting.hpp IMain.hpp - CStopwatch.hpp + CStopwatch.hpp CStopwatch.cpp + Streams/IOStreams.hpp Streams/IOStreams.cpp + Streams/CMemoryStreamOut.hpp Streams/CMemoryStreamOut.cpp + Streams/CInputStream.hpp Streams/CInputStream.cpp + Streams/COutputStream.hpp Streams/COutputStream.cpp + Streams/CMemoryInStream.hpp + Streams/CZipInputStream.hpp Streams/CZipInputStream.cpp + Streams/ContainerReaders.hpp + Streams/CTextInStream.hpp Streams/CTextInStream.cpp + Streams/CTextOutStream.hpp Streams/CTextOutStream.cpp + Streams/CFileOutStream.hpp Streams/CFileOutStream.cpp CGameAllocator.hpp CGameAllocator.cpp CMemoryCardSys.hpp CMemoryCardSys.cpp CScannableObjectInfo.hpp CScannableObjectInfo.cpp @@ -93,7 +111,6 @@ set(RUNTIME_SOURCES_B IObjectStore.hpp CSimplePool.hpp CSimplePool.cpp CGameOptions.hpp CGameOptions.cpp - CGameOptionsTouchBar.hpp CGameOptionsTouchBar.cpp CStaticInterference.hpp CStaticInterference.cpp CCRC32.hpp CCRC32.cpp IFactory.hpp @@ -109,8 +126,7 @@ set(RUNTIME_SOURCES_B CToken.hpp CToken.cpp CFactoryMgr.hpp CFactoryMgr.cpp CPakFile.hpp CPakFile.cpp - CStringExtras.hpp - IOStreams.hpp IOStreams.cpp + CStringExtras.hpp CStringExtras.cpp CMainFlowBase.hpp CMainFlowBase.cpp CMFGameBase.hpp CInGameTweakManagerBase.hpp @@ -121,22 +137,27 @@ set(RUNTIME_SOURCES_B GCNTypes.hpp CTextureCache.hpp CTextureCache.cpp CMayaSpline.hpp CMayaSpline.cpp + ImGuiPlayerLoadouts.hpp ImGuiPlayerLoadouts.cpp ${PLAT_SRCS}) function(add_runtime_common_library name) add_library(${name} ${ARGN}) - if (COMMAND add_sanitizers) - add_sanitizers(${name}) - endif () - + target_compile_definitions(${name} PUBLIC "-DMETAFORCE_TARGET_BYTE_ORDER=__BYTE_ORDER__") if (WINDOWS_STORE) set_property(TARGET ${name} PROPERTY VS_WINRT_COMPONENT TRUE) endif () endfunction() -set(RUNTIME_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) -set(RUNTIME_LIBRARIES ${HECL_APPLICATION_REPS_TARGETS_LIST} RetroDataSpec AssetNameMapNull NESEmulator - libjpeg-turbo jbus kabufuda discord-rpc logvisor OptickCore imgui) +set(RUNTIME_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}) +set(DISCORD_RPC_LIBRARY "") +if (NOT GEKKO AND NOT NX AND NOT IOS AND NOT TVOS) + set(DISCORD_RPC_LIBRARY "discord-rpc") +endif() +set(RUNTIME_LIBRARIES zeus nod NESEmulator libjpeg-turbo jbus kabufuda logvisor OptickCore + imgui_support aurora::aurora + ${DISCORD_RPC_LIBRARY} + ${ZLIB_LIBRARIES} + ) add_runtime_common_library(RuntimeCommon ${RUNTIME_SOURCES_A}) target_include_directories(RuntimeCommon PUBLIC ${RUNTIME_INCLUDES}) @@ -199,25 +220,63 @@ if (WIN32) elseif (APPLE) # nothing elseif (UNIX) - add_subdirectory(platforms/freedesktop) - declare_wmicon_target() - set(PLAT_SRCS mainicon_netwm.cpp) set(PLAT_LIBS rt) endif () -add_executable(metaforce CMain.cpp ${PLAT_SRCS} ImGuiConsole.hpp ImGuiConsole.cpp ImGuiEntitySupport.hpp ImGuiEntitySupport.cpp) # ImGuiPlayerLoadouts.hpp -# target_atdna(metaforce atdna_ImGuiPlayerLoadouts.cpp ImGuiPlayerLoadouts.hpp) +add_executable(metaforce CMain.cpp ${PLAT_SRCS} + ImGuiConsole.hpp ImGuiConsole.cpp + ImGuiControllerConfig.hpp ImGuiControllerConfig.cpp + ImGuiEntitySupport.hpp ImGuiEntitySupport.cpp) # RUNTIME_LIBRARIES repeated here for link ordering -target_link_libraries(metaforce PUBLIC RuntimeCommon RuntimeCommonB ${RUNTIME_LIBRARIES} ${PLAT_LIBS}) +target_link_libraries(metaforce PUBLIC RuntimeCommon RuntimeCommonB ${RUNTIME_LIBRARIES} ${PLAT_LIBS} aurora::main) +if (TARGET nfd) + target_link_libraries(metaforce PRIVATE nfd) +endif() +target_compile_definitions(metaforce PUBLIC "-DMETAFORCE_TARGET_BYTE_ORDER=__BYTE_ORDER__") -if (COMMAND add_sanitizers) - add_sanitizers(metaforce) +if (APPLE) + if (TVOS) + set(RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/tvos) + set(INFO_PLIST ${RESOURCE_DIR}/Info.plist.in) + file(GLOB_RECURSE RESOURCE_FILES "${RESOURCE_DIR}/Base.lproj/*") + list(APPEND RESOURCE_FILES ${RESOURCE_DIR}/Assets.car) + elseif (IOS) + set(RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/ios) + set(INFO_PLIST ${RESOURCE_DIR}/Info.plist.in) + file(GLOB_RECURSE RESOURCE_FILES "${RESOURCE_DIR}/Base.lproj/*") + list(APPEND RESOURCE_FILES + ${RESOURCE_DIR}/Assets.car + ${RESOURCE_DIR}/AppIcon60x60@2x.png + ${RESOURCE_DIR}/AppIcon76x76@2x~ipad.png) + else () + set(RESOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/platforms/macos) + set(INFO_PLIST ${RESOURCE_DIR}/Info.plist.in) + set(RESOURCE_FILES ${RESOURCE_DIR}/mainicon.icns) + endif () + target_sources(metaforce PRIVATE ${RESOURCE_FILES}) + # Add to resources, preserving directory structure + foreach (FILE ${RESOURCE_FILES}) + file(RELATIVE_PATH NEW_FILE "${RESOURCE_DIR}" ${FILE}) + get_filename_component(NEW_FILE_PATH ${NEW_FILE} DIRECTORY) + set_property(SOURCE ${FILE} PROPERTY MACOSX_PACKAGE_LOCATION "Resources/${NEW_FILE_PATH}") + source_group("Resources/${NEW_FILE_PATH}" FILES "${FILE}") + endforeach () + set_target_properties( + metaforce PROPERTIES + MACOSX_BUNDLE TRUE + MACOSX_BUNDLE_INFO_PLIST ${INFO_PLIST} + MACOSX_BUNDLE_BUNDLE_NAME Metaforce + MACOSX_BUNDLE_GUI_IDENTIFIER com.axiodl.Metaforce + MACOSX_BUNDLE_BUNDLE_VERSION "${METAFORCE_VERSION_STRING}" + MACOSX_BUNDLE_SHORT_VERSION_STRING "${METAFORCE_SHORT_VERSION_STRING}" + OUTPUT_NAME Metaforce + ) endif () - -if (NOT WINDOWS_STORE) - add_dependencies(metaforce visigen hecl) -else () +if (WINDOWS_STORE) set_property(TARGET metaforce PROPERTY VS_WINRT_COMPONENT TRUE) # This should match the Package.appxmanifest set_property(TARGET metaforce PROPERTY VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION "10.0.14393.0") endif () +if (EMSCRIPTEN) + target_link_options(metaforce PRIVATE -sTOTAL_MEMORY=268435456 -sALLOW_MEMORY_GROWTH --preload-file "${CMAKE_SOURCE_DIR}/files@/") +endif () diff --git a/Runtime/CMayaSpline.cpp b/Runtime/CMayaSpline.cpp index 1802c2edc..5f90b5c20 100644 --- a/Runtime/CMayaSpline.cpp +++ b/Runtime/CMayaSpline.cpp @@ -1,6 +1,6 @@ -#include "CMayaSpline.hpp" +#include "Runtime/CMayaSpline.hpp" -namespace rstl {} // namespace rstl +#include "Runtime/Streams/CInputStream.hpp" namespace metaforce { void ValidateTangent(zeus::CVector2f& tangent) { @@ -21,19 +21,19 @@ void ValidateTangent(zeus::CVector2f& tangent) { } CMayaSplineKnot::CMayaSplineKnot(CInputStream& in) { - x0_time = in.readFloatBig(); - x4_amplitude = in.readFloatBig(); - x8_ = in.readByte(); - x9_ = in.readByte(); + x0_time = in.ReadFloat(); + x4_amplitude = in.ReadFloat(); + x8_ = in.ReadInt8(); + x9_ = in.ReadInt8(); if (x8_ == 5) { - float x = in.readFloatBig(); - float y = in.readFloatBig(); + float x = in.ReadFloat(); + float y = in.ReadFloat(); xc_cachedTangentA = {x, y}; } if (x9_ == 5) { - float x = in.readFloatBig(); - float y = in.readFloatBig(); + float x = in.ReadFloat(); + float y = in.ReadFloat(); x14_cachedTangentB = {x, y}; } } @@ -166,17 +166,16 @@ void CMayaSplineKnot::CalculateTangents(CMayaSplineKnot* prev, CMayaSplineKnot* ValidateTangent(x14_cachedTangentB); } -CMayaSpline::CMayaSpline(CInputStream& in, s32 count) { - x0_preInfinity = in.readByte(); - x4_postInfinity = in.readByte(); - u32 knotCount = in.readUint32Big(); +CMayaSpline::CMayaSpline(CInputStream& in, s32 count) : x0_preInfinity(in.ReadInt8()), x4_postInfinity(in.ReadInt8()) { + + u32 knotCount = in.ReadLong(); x8_knots.reserve(knotCount); for (size_t i = 0; i < knotCount; ++i) { x8_knots.emplace_back(in); } - x18_clampMode = in.readByte(); - x1c_minAmplitudeTime = in.readFloatBig(); - x20_maxAmplitudeTime = in.readFloatBig(); + x18_clampMode = in.ReadInt8(); + x1c_minAmplitudeTime = in.ReadFloat(); + x20_maxAmplitudeTime = in.ReadFloat(); } float CMayaSpline::GetMinTime() const { return x8_knots.empty() ? 0.f : x8_knots[0].GetTime(); } @@ -223,7 +222,7 @@ float CMayaSpline::EvaluateAtUnclamped(float time) { } return EvaluateInfinities(time, true); } else if (x8_knots[lastIdx].GetTime() >= time) { - bool bVar2 = false; + bVar2 = false; s32 local_68 = -1; s32 iVar1 = x24_chachedKnotIndex; if (iVar1 != -1) { diff --git a/Runtime/CMemoryCardSys.cpp b/Runtime/CMemoryCardSys.cpp index 9ae7656d1..300c7425b 100644 --- a/Runtime/CMemoryCardSys.cpp +++ b/Runtime/CMemoryCardSys.cpp @@ -6,8 +6,8 @@ #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Graphics/CTexture.hpp" #include "Runtime/GuiSys/CStringTable.hpp" -#include -#include +#include "ConsoleVariables/CVar.hpp" +#include "ConsoleVariables/CVarManager.hpp" namespace metaforce { namespace { @@ -16,8 +16,8 @@ using ECardResult = kabufuda::ECardResult; static std::string g_CardImagePaths[2] = {}; static kabufuda::Card g_CardStates[2] = {kabufuda::Card{"GM8E", "01"}, kabufuda::Card{"GM8E", "01"}}; // static kabufuda::ECardResult g_OpResults[2] = {}; -hecl::CVar* mc_dolphinAPath = nullptr; -hecl::CVar* mc_dolphinBPath = nullptr; +CVar* mc_dolphinAPath = nullptr; +CVar* mc_dolphinBPath = nullptr; } // namespace CSaveWorldIntermediate::CSaveWorldIntermediate(CAssetId mlvl, CAssetId savw) : x0_mlvlId(mlvl), x8_savwId(savw) { if (!savw.IsValid()) @@ -71,12 +71,12 @@ const CSaveWorldMemory& CMemoryCardSys::GetSaveWorldMemory(CAssetId wldId) const } CMemoryCardSys::CMemoryCardSys() { - mc_dolphinAPath = hecl::CVarManager::instance()->findOrMakeCVar( + mc_dolphinAPath = CVarManager::instance()->findOrMakeCVar( "memcard.PathA"sv, "Path to the memory card image for SlotA"sv, ""sv, - (hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::System | hecl::CVar::EFlags::ModifyRestart)); - mc_dolphinBPath = hecl::CVarManager::instance()->findOrMakeCVar( + (CVar::EFlags::Archive | CVar::EFlags::System | CVar::EFlags::ModifyRestart)); + mc_dolphinBPath = CVarManager::instance()->findOrMakeCVar( "memcard.PathB"sv, "Path to the memory card image for SlotB"sv, ""sv, - (hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::System | hecl::CVar::EFlags::ModifyRestart)); + (CVar::EFlags::Archive | CVar::EFlags::System | CVar::EFlags::ModifyRestart)); x0_hints = g_SimplePool->GetObj("HINT_Hints"); xc_memoryWorlds.reserve(16); x1c_worldInter.emplace(); @@ -171,38 +171,39 @@ std::pair CMemoryCardSys::GetAreaAndWorldIdForSaveId(s32 save void CMemoryCardSys::CCardFileInfo::LockBannerToken(CAssetId bannerTxtr, CSimplePool& sp) { x3c_bannerTex = bannerTxtr; - x40_bannerTok.emplace(sp.GetObj({FOURCC('TXTR'), bannerTxtr}, m_texParam)); + x40_bannerTok.emplace(sp.GetObj({FOURCC('TXTR'), bannerTxtr})); } -CMemoryCardSys::CCardFileInfo::Icon::Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp, - const CVParamTransfer& cv) -: x0_id(id), x4_speed(speed), x8_tex(sp.GetObj({FOURCC('TXTR'), id}, cv)) {} +CMemoryCardSys::CCardFileInfo::Icon::Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp) +: x0_id(id), x4_speed(speed), x8_tex(sp.GetObj({FOURCC('TXTR'), id})) {} void CMemoryCardSys::CCardFileInfo::LockIconToken(CAssetId iconTxtr, kabufuda::EAnimationSpeed speed, CSimplePool& sp) { - x50_iconToks.emplace_back(iconTxtr, speed, sp, m_texParam); + x50_iconToks.emplace_back(iconTxtr, speed, sp); } u32 CMemoryCardSys::CCardFileInfo::CalculateBannerDataSize() const { u32 ret = 68; if (x3c_bannerTex.IsValid()) { - if ((*x40_bannerTok)->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3) + if ((*x40_bannerTok)->GetTextureFormat() == ETexelFormat::RGB5A3) { ret = 6212; - else + } else { ret = 3652; + } } bool paletteTex = false; for (const Icon& icon : x50_iconToks) { - if (icon.x8_tex->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3) + if (icon.x8_tex->GetTextureFormat() == ETexelFormat::RGB5A3) { ret += 2048; - else { + } else { ret += 1024; paletteTex = true; } } - if (paletteTex) + if (paletteTex) { ret += 512; + } return ret; } @@ -215,53 +216,56 @@ void CMemoryCardSys::CCardFileInfo::BuildCardBuffer() { u32 bannerSz = CalculateBannerDataSize(); x104_cardBuffer.resize((bannerSz + xf4_saveBuffer.size() + 8191) & ~8191); - CMemoryOutStream w(x104_cardBuffer.data(), x104_cardBuffer.size()); - w.writeUint32Big(0); - char comment[64]; - std::memset(comment, 0, std::size(comment)); - std::strncpy(comment, x28_comment.data(), std::size(comment) - 1); - w.writeBytes(comment, 64); - WriteBannerData(w); - WriteIconData(w); + { + CMemoryStreamOut w(x104_cardBuffer.data(), x104_cardBuffer.size(), CMemoryStreamOut::EOwnerShip::NotOwned); + w.WriteLong(0); + char comment[64]; + std::memset(comment, 0, std::size(comment)); + std::strncpy(comment, x28_comment.data(), std::size(comment) - 1); + w.Put(reinterpret_cast(comment), 64); + WriteBannerData(w); + WriteIconData(w); + } memmove(x104_cardBuffer.data() + bannerSz, xf4_saveBuffer.data(), xf4_saveBuffer.size()); reinterpret_cast(*x104_cardBuffer.data()) = - hecl::SBig(CCRC32::Calculate(x104_cardBuffer.data() + 4, x104_cardBuffer.size() - 4)); + CBasics::SwapBytes(CCRC32::Calculate(x104_cardBuffer.data() + 4, x104_cardBuffer.size() - 4)); xf4_saveBuffer.clear(); } -void CMemoryCardSys::CCardFileInfo::WriteBannerData(CMemoryOutStream& out) const { +void CMemoryCardSys::CCardFileInfo::WriteBannerData(COutputStream& out) const { if (x3c_bannerTex.IsValid()) { const TLockedToken& tex = *x40_bannerTok; - u32 bufSz; - ETexelFormat fmt; - std::unique_ptr palette; - std::unique_ptr texels = tex->BuildMemoryCardTex(bufSz, fmt, palette); - - if (fmt == ETexelFormat::RGB5A3) - out.writeBytes(texels.get(), 6144); - else - out.writeBytes(texels.get(), 3072); - - if (fmt == ETexelFormat::C8) - out.writeBytes(palette.get(), 512); + const auto format = tex->GetTextureFormat(); + const auto* texels = tex->GetConstBitMapData(0); + if (format == ETexelFormat::RGB5A3) { + out.Put(texels, 6144); + } else { + out.Put(texels, 3072); + } + if (format == ETexelFormat::C8) { + out.Put(reinterpret_cast(tex->GetPalette()->GetPaletteData()), 512); + } } } -void CMemoryCardSys::CCardFileInfo::WriteIconData(CMemoryOutStream& out) const { - std::unique_ptr palette; +void CMemoryCardSys::CCardFileInfo::WriteIconData(COutputStream& out) const { + const u8* palette = nullptr; for (const Icon& icon : x50_iconToks) { - u32 bufSz; - ETexelFormat fmt; - std::unique_ptr texels = icon.x8_tex->BuildMemoryCardTex(bufSz, fmt, palette); - - if (fmt == ETexelFormat::RGB5A3) - out.writeBytes(texels.get(), 2048); - else - out.writeBytes(texels.get(), 1024); + const auto format = icon.x8_tex->GetTextureFormat(); + const auto* texels = icon.x8_tex->GetConstBitMapData(0); + if (format == ETexelFormat::RGB5A3) { + out.Put(texels, 2048); + } else { + out.Put(texels, 1024); + } + if (format == ETexelFormat::C8) { + palette = reinterpret_cast(icon.x8_tex->GetPalette()->GetPaletteData()); + } + } + if (palette != nullptr) { + out.Put(palette, 512); } - if (palette) - out.writeBytes(palette.get(), 512); } ECardResult CMemoryCardSys::CCardFileInfo::PumpCardTransfer() { @@ -292,26 +296,29 @@ ECardResult CMemoryCardSys::CCardFileInfo::PumpCardTransfer() { ECardResult CMemoryCardSys::CCardFileInfo::GetStatus(kabufuda::CardStat& stat) const { ECardResult result = CMemoryCardSys::GetStatus(m_handle.slot, m_handle.getFileNo(), stat); - if (result != ECardResult::READY) + if (result != ECardResult::READY) { return result; + } stat.SetCommentAddr(4); stat.SetIconAddr(68); kabufuda::EImageFormat bannerFmt; if (x3c_bannerTex.IsValid()) { - if ((*x40_bannerTok)->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3) + if ((*x40_bannerTok)->GetTextureFormat() == ETexelFormat::RGB5A3) { bannerFmt = kabufuda::EImageFormat::RGB5A3; - else + } else { bannerFmt = kabufuda::EImageFormat::C8; - } else + } + } else { bannerFmt = kabufuda::EImageFormat::None; + } stat.SetBannerFormat(bannerFmt); int idx = 0; for (const Icon& icon : x50_iconToks) { - stat.SetIconFormat(icon.x8_tex->GetMemoryCardTexelFormat() == ETexelFormat::RGB5A3 ? kabufuda::EImageFormat::RGB5A3 - : kabufuda::EImageFormat::C8, + stat.SetIconFormat(icon.x8_tex->GetTextureFormat() == ETexelFormat::RGB5A3 ? kabufuda::EImageFormat::RGB5A3 + : kabufuda::EImageFormat::C8, idx); stat.SetIconSpeed(icon.x4_speed, idx); ++idx; @@ -340,7 +347,7 @@ std::string CMemoryCardSys::_GetDolphinCardPath(kabufuda::ECardSlot slot) { return g_CardImagePaths[static_cast(slot)]; } -void CMemoryCardSys::_ResolveDolphinCardPath(const hecl::CVar* cv, kabufuda::ECardSlot slot) { +void CMemoryCardSys::_ResolveDolphinCardPath(const CVar* cv, kabufuda::ECardSlot slot) { if (cv != nullptr && cv->toLiteral().empty()) { g_CardImagePaths[int(slot)] = ResolveDolphinCardPath(slot); } else if (cv != nullptr) { @@ -555,9 +562,8 @@ void CMemoryCardSys::CommitToDisk(kabufuda::ECardSlot port) { } bool CMemoryCardSys::CreateDolphinCard(kabufuda::ECardSlot slot) { - std::string path = - _CreateDolphinCard(slot, slot == kabufuda::ECardSlot::SlotA ? mc_dolphinAPath->hasDefaultValue() - : mc_dolphinBPath->hasDefaultValue()); + std::string path = _CreateDolphinCard(slot, slot == kabufuda::ECardSlot::SlotA ? mc_dolphinAPath->hasDefaultValue() + : mc_dolphinBPath->hasDefaultValue()); if (CardProbe(slot).x0_error != ECardResult::READY) { return false; } diff --git a/Runtime/CMemoryCardSys.hpp b/Runtime/CMemoryCardSys.hpp index 6c99bf540..b676425a9 100644 --- a/Runtime/CMemoryCardSys.hpp +++ b/Runtime/CMemoryCardSys.hpp @@ -6,11 +6,12 @@ #include #include "Runtime/CGameHintInfo.hpp" -#include "Runtime/CWorldSaveGameInfo.hpp" +#include "Runtime/Streams/CMemoryStreamOut.hpp" #include "Runtime/CToken.hpp" -#include "Runtime/rstl.hpp" +#include "Runtime/CWorldSaveGameInfo.hpp" #include "Runtime/GuiSys/CStringTable.hpp" #include "Runtime/World/CWorld.hpp" +#include "Runtime/rstl.hpp" #include @@ -68,7 +69,7 @@ class CMemoryCardSys { public: static void _ResetCVar(kabufuda::ECardSlot slot); - static void _ResolveDolphinCardPath(const hecl::CVar* cv, kabufuda::ECardSlot slot); + static void _ResolveDolphinCardPath(const CVar* cv, kabufuda::ECardSlot slot); static std::string ResolveDolphinCardPath(kabufuda::ECardSlot slot); static bool CreateDolphinCard(kabufuda::ECardSlot slot); static std::string _GetDolphinCardPath(kabufuda::ECardSlot slot); @@ -114,7 +115,7 @@ public: CAssetId x0_id; kabufuda::EAnimationSpeed x4_speed; TLockedToken x8_tex; - Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp, const CVParamTransfer& cv); + Icon(CAssetId id, kabufuda::EAnimationSpeed speed, CSimplePool& sp); }; enum class EStatus { Standby, Transferring, Done }; @@ -130,20 +131,18 @@ public: std::vector xf4_saveBuffer; std::vector x104_cardBuffer; - CVParamTransfer m_texParam = {new TObjOwnerParam(SBIG('OTEX'))}; - CCardFileInfo(kabufuda::ECardSlot port, std::string_view name) : m_handle(port), x18_fileName(name) {} void LockBannerToken(CAssetId bannerTxtr, CSimplePool& sp); void LockIconToken(CAssetId iconTxtr, kabufuda::EAnimationSpeed speed, CSimplePool& sp); - kabufuda::ECardSlot GetCardPort() const { return m_handle.slot; } - int GetFileNo() const { return m_handle.getFileNo(); } - u32 CalculateBannerDataSize() const; - u32 CalculateTotalDataSize() const; + [[nodiscard]] kabufuda::ECardSlot GetCardPort() const { return m_handle.slot; } + [[nodiscard]] int GetFileNo() const { return m_handle.getFileNo(); } + [[nodiscard]] u32 CalculateBannerDataSize() const; + [[nodiscard]] u32 CalculateTotalDataSize() const; void BuildCardBuffer(); - void WriteBannerData(CMemoryOutStream& out) const; - void WriteIconData(CMemoryOutStream& out) const; + void WriteBannerData(COutputStream& out) const; + void WriteIconData(COutputStream& out) const; void SetComment(const std::string& c) { x28_comment = c; } ECardResult PumpCardTransfer(); ECardResult GetStatus(CardStat& stat) const; @@ -151,9 +150,9 @@ public: ECardResult WriteFile(); ECardResult CloseFile(); - CMemoryOutStream BeginMemoryOut(u32 sz) { + CMemoryStreamOut BeginMemoryOut(u32 sz) { xf4_saveBuffer.resize(sz); - return CMemoryOutStream(xf4_saveBuffer.data(), sz); + return CMemoryStreamOut(xf4_saveBuffer.data(), sz, CMemoryStreamOut::EOwnerShip::NotOwned, sz); } }; diff --git a/Runtime/CMemoryCardSysNix.cpp b/Runtime/CMemoryCardSysNix.cpp index c7ff75db6..bebc5db5f 100644 --- a/Runtime/CMemoryCardSysNix.cpp +++ b/Runtime/CMemoryCardSysNix.cpp @@ -1,29 +1,49 @@ #include "CMemoryCardSys.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/IMain.hpp" +#include +#include namespace metaforce { +static std::optional GetPrefPath(const char* app) { + char* path = SDL_GetPrefPath(nullptr, app); + if (path == nullptr) { + return {}; + } + std::string str{path}; + SDL_free(path); + return str; +} + std::string CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) { if (g_Main->IsUSA() && !g_Main->IsTrilogy()) { - const char* home = getenv("HOME"); - if (!home || home[0] != '/') + const auto dolphinPath = GetPrefPath("dolphin-emu"); + if (!dolphinPath) { return {}; - const char* dataHome = getenv("XDG_DATA_HOME"); + } + auto path = *dolphinPath; + path += fmt::format(FMT_STRING("GC/MemoryCard{:c}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B'); - /* XDG-selected data path */ - std::string path = - ((dataHome && dataHome[0] == '/') ? dataHome : std::string(home)) + "/.local/share/dolphin-emu"; - path += fmt::format(FMT_STRING("/GC/MemoryCard{:c}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B'); - - hecl::Sstat theStat; - if (hecl::Stat(path.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) { + CBasics::Sstat theStat{}; + if (CBasics::Stat(path.c_str(), &theStat) != 0 || !S_ISREG(theStat.st_mode)) { /* legacy case for older dolphin versions */ + const char* home = getenv("HOME"); + if (home == nullptr || home[0] != '/') { + return {}; + } + path = home; +#ifndef __APPLE__ path += fmt::format(FMT_STRING("/.dolphin-emu/GC/MemoryCard{:c}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B'); - if (hecl::Stat(path.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) +#else + path += fmt::format(FMT_STRING("/Library/Application Support/Dolphin/GC/MemoryCard{:c}.USA.raw"), + slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B'); +#endif + if (CBasics::Stat(path.c_str(), &theStat) != 0 || !S_ISREG(theStat.st_mode)) { return {}; + } } return path; @@ -34,33 +54,39 @@ std::string CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) { std::string CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool dolphin) { if (g_Main->IsUSA() && !g_Main->IsTrilogy()) { if (dolphin) { - const char* home = getenv("HOME"); - if (!home || home[0] != '/') + const auto dolphinPath = GetPrefPath("dolphin-emu"); + if (!dolphinPath) { return {}; - const char* dataHome = getenv("XDG_DATA_HOME"); - - /* XDG-selected data path */ - std::string path = - ((dataHome && dataHome[0] == '/') ? dataHome : std::string(home)) + "/.local/share/dolphin-emu/GC"; - - if (hecl::RecursiveMakeDir(path.c_str()) < 0) + } + auto path = *dolphinPath + "GC"; + int ret = mkdir(path.c_str(), 0755); + if (ret != 0 && errno != EEXIST) { return {}; + } path += fmt::format(FMT_STRING("/MemoryCard{:c}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B'); - const auto fp = hecl::FopenUnique(path.c_str(), "wb"); - if (fp != nullptr) { + auto* file = fopen(path.c_str(), "wbe"); + if (file != nullptr) { + fclose(file); return path; } } else { std::string path = _GetDolphinCardPath(slot); - hecl::SanitizePath(path); if (path.find('/') == std::string::npos) { - path = hecl::GetcwdStr() + "/" + _GetDolphinCardPath(slot); + auto basePath = GetPrefPath("metaforce"); + if (!basePath) { + return {}; + } + path = *basePath + _GetDolphinCardPath(slot); } - std::string tmpPath = path.substr(0, path.find_last_of("/")); - hecl::RecursiveMakeDir(tmpPath.c_str()); - const auto fp = hecl::FopenUnique(path.c_str(), "wb"); - if (fp) { + std::string tmpPath = path.substr(0, path.find_last_of('/')); + int ret = mkdir(tmpPath.c_str(), 0755); + if (ret != 0 && ret != EEXIST) { + return {}; + } + auto* file = fopen(path.c_str(), "wbe"); + if (file != nullptr) { + fclose(file); return path; } } diff --git a/Runtime/CMemoryCardSysWin.cpp b/Runtime/CMemoryCardSysWin.cpp index 3fba93526..fc5d68191 100644 --- a/Runtime/CMemoryCardSysWin.cpp +++ b/Runtime/CMemoryCardSysWin.cpp @@ -2,11 +2,23 @@ #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/IMain.hpp" +#include "Runtime/CBasics.hpp" -#include +#include +#include namespace metaforce { +static std::optional GetPrefPath(const char* app) { + char* path = SDL_GetPrefPath(nullptr, app); + if (path == nullptr) { + return {}; + } + std::string str{path}; + SDL_free(path); + return str; +} + #if WINDOWS_STORE using namespace Windows::Storage; #endif @@ -53,8 +65,8 @@ std::string CMemoryCardSys::ResolveDolphinCardPath(kabufuda::ECardSlot slot) { path += fmt::format(FMT_STRING("/GC/MemoryCard{}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B'); - hecl::Sstat theStat; - if (hecl::Stat(path.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) + struct _stat64 theStat{}; + if (_stat64(path.c_str(), &theStat) || !S_ISREG(theStat.st_mode)) return {}; return path; @@ -101,26 +113,33 @@ std::string CMemoryCardSys::_CreateDolphinCard(kabufuda::ECardSlot slot, bool do #endif path += "/GC"; - if (hecl::RecursiveMakeDir(path.c_str()) < 0) + if (CBasics::RecursiveMakeDir(path.c_str()) < 0) return {}; path += fmt::format(FMT_STRING("/MemoryCard{}.USA.raw"), slot == kabufuda::ECardSlot::SlotA ? 'A' : 'B'); - const auto fp = hecl::FopenUnique(path.c_str(), "wb"); + const nowide::wstackstring wpath(path); + FILE* fp = _wfopen(wpath.get(), L"wb"); if (fp == nullptr) { return {}; } + fclose(fp); return path; } else { std::string path = _GetDolphinCardPath(slot); - hecl::SanitizePath(path); if (path.find('/') == std::string::npos) { - path = hecl::GetcwdStr() + "/" + _GetDolphinCardPath(slot); + auto prefPath = GetPrefPath("Metaforce"); + if (!prefPath) { + return {}; + } + path = *prefPath + _GetDolphinCardPath(slot); } - std::string tmpPath = path.substr(0, path.find_last_of("/")); - hecl::RecursiveMakeDir(tmpPath.c_str()); - const auto fp = hecl::FopenUnique(path.c_str(), "wb"); + std::string tmpPath = path.substr(0, path.find_last_of('/')); + CBasics::RecursiveMakeDir(tmpPath.c_str()); + const nowide::wstackstring wpath(path); + FILE* fp = _wfopen(wpath.get(), L"wb"); if (fp) { + fclose(fp); return path; } } diff --git a/Runtime/CPakFile.cpp b/Runtime/CPakFile.cpp index c0b91600b..ba921a4b6 100644 --- a/Runtime/CPakFile.cpp +++ b/Runtime/CPakFile.cpp @@ -26,19 +26,19 @@ const SObjectTag* CPakFile::GetResIdByName(std::string_view name) const { return nullptr; } -void CPakFile::LoadResourceTable(athena::io::MemoryReader& r) { +void CPakFile::LoadResourceTable(CInputStream& r) { x74_resList.reserve( std::max(size_t(64), size_t(ROUND_UP_32(x4c_resTableCount * sizeof(SResInfo)) + sizeof(SResInfo) - 1)) / sizeof(SResInfo)); if (x28_24_buildDepList) x64_depList.reserve(x4c_resTableCount); for (u32 i = 0; i < x4c_resTableCount; ++i) { - u32 flags = r.readUint32Big(); + u32 flags = r.ReadLong(); FourCC fcc; - r.readBytesToBuf(&fcc, 4); - CAssetId id = r.readUint32Big(); - u32 size = r.readUint32Big(); - u32 offset = r.readUint32Big(); + r.ReadBytes(reinterpret_cast(&fcc), 4); + CAssetId id = r.Get(); + u32 size = r.ReadLong(); + u32 offset = r.ReadLong(); if (fcc == FOURCC('MLVL')) m_mlvlId = id; x74_resList.emplace_back(id, fcc, offset, size, flags); @@ -50,7 +50,8 @@ void CPakFile::LoadResourceTable(athena::io::MemoryReader& r) { void CPakFile::DataLoad() { x30_dvdReq.reset(); - athena::io::MemoryReader r(x38_headerData.data() + x48_resTableOffset, x38_headerData.size() - x48_resTableOffset); + CMemoryInStream r(x38_headerData.data() + x48_resTableOffset, x38_headerData.size() - x48_resTableOffset, + CMemoryInStream::EOwnerShip::NotOwned); LoadResourceTable(r); x2c_asyncLoadPhase = EAsyncPhase::Loaded; if (x28_26_worldPak) { @@ -60,28 +61,27 @@ void CPakFile::DataLoad() { } void CPakFile::InitialHeaderLoad() { - athena::io::MemoryReader r(x38_headerData.data(), x38_headerData.size()); + CMemoryInStream r(x38_headerData.data(), x38_headerData.size(), CMemoryInStream::EOwnerShip::NotOwned); x30_dvdReq.reset(); - u32 version = r.readUint32Big(); - if (version != 0x80030005) { + u32 version = r.ReadLong(); + if (version != 0x00030005) { Log.report(logvisor::Fatal, FMT_STRING("{}: Incompatible pak file version -- Current version is {:08X}, you're using {:08X}"), - GetPath(), 0x80030005, version); + GetPath(), 0x00030005, version); return; } - r.readUint32Big(); - u32 nameCount = r.readUint32Big(); + r.ReadLong(); + u32 nameCount = r.ReadLong(); x54_nameList.reserve(nameCount); for (u32 i = 0; i < nameCount; ++i) { SObjectTag tag(r); - u32 nameLen = r.readUint32Big(); - auto name = r.readString(nameLen); + auto name = CStringExtras::ReadString(r); x54_nameList.emplace_back(name, tag); } - x4c_resTableCount = r.readUint32Big(); - x48_resTableOffset = u32(r.position()); + x4c_resTableCount = r.ReadLong(); + x48_resTableOffset = u32(r.GetReadPosition()); x2c_asyncLoadPhase = EAsyncPhase::DataLoad; u32 newSize = ROUND_UP_32(x4c_resTableCount * 20 + x48_resTableOffset); u32 origSize = u32(x38_headerData.size()); diff --git a/Runtime/CPakFile.hpp b/Runtime/CPakFile.hpp index a0804e076..01119b1d7 100644 --- a/Runtime/CPakFile.hpp +++ b/Runtime/CPakFile.hpp @@ -57,7 +57,7 @@ private: std::vector x74_resList; mutable s32 x84_currentSeek = -1; CAssetId m_mlvlId; - void LoadResourceTable(athena::io::MemoryReader& r); + void LoadResourceTable(CInputStream& r); void DataLoad(); void InitialHeaderLoad(); void Warmup(); diff --git a/Runtime/CPlayerState.cpp b/Runtime/CPlayerState.cpp index 2f263e1d6..853a332e5 100644 --- a/Runtime/CPlayerState.cpp +++ b/Runtime/CPlayerState.cpp @@ -4,10 +4,11 @@ #include #include +#include "Runtime/CStringExtras.hpp" #include "Runtime/CMemoryCardSys.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Camera/CCameraManager.hpp" #include "Runtime/Camera/CFirstPersonCamera.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -76,63 +77,63 @@ constexpr std::array ComboAmmoPeriods{ CPlayerState::CPlayerState() { x24_powerups.resize(41); } -CPlayerState::CPlayerState(CBitStreamReader& stream) { - x4_enabledItems = u32(stream.ReadEncoded(32)); +CPlayerState::CPlayerState(CInputStream& stream) { + x4_enabledItems = u32(stream.ReadBits(32)); - const u32 integralHP = u32(stream.ReadEncoded(32)); + const u32 integralHP = u32(stream.ReadBits(32)); float realHP; std::memcpy(&realHP, &integralHP, sizeof(float)); xc_health.SetHP(realHP); - x8_currentBeam = EBeamId(stream.ReadEncoded(CBitStreamReader::GetBitCount(5))); - x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4))); + x8_currentBeam = EBeamId(stream.ReadBits(CInputStream::GetBitCount(5))); + x20_currentSuit = EPlayerSuit(stream.ReadBits(CInputStream::GetBitCount(4))); x24_powerups.resize(41); for (size_t i = 0; i < x24_powerups.size(); ++i) { if (PowerUpMaxValues[i] == 0) { continue; } - const u32 a = u32(stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxValues[i]))); - const u32 b = u32(stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxValues[i]))); + const u32 a = u32(stream.ReadBits(CInputStream::GetBitCount(PowerUpMaxValues[i]))); + const u32 b = u32(stream.ReadBits(CInputStream::GetBitCount(PowerUpMaxValues[i]))); x24_powerups[i] = CPowerUp(a, b); } const auto& scanStates = g_MemoryCardSys->GetScanStates(); x170_scanTimes.reserve(scanStates.size()); for (const auto& state : scanStates) { - float time = stream.ReadEncoded(1) ? 1.f : 0.f; + float time = stream.ReadBits(1) ? 1.f : 0.f; x170_scanTimes.emplace_back(state.first, time); } - x180_scanCompletionRate.first = u32(stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100u))); - x180_scanCompletionRate.second = u32(stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100u))); + x180_scanCompletionRate.first = u32(stream.ReadBits(CInputStream::GetBitCount(0x100u))); + x180_scanCompletionRate.second = u32(stream.ReadBits(CInputStream::GetBitCount(0x100u))); } -void CPlayerState::PutTo(CBitStreamWriter& stream) { - stream.WriteEncoded(x4_enabledItems, 32); +void CPlayerState::PutTo(COutputStream& stream) { + stream.WriteBits(x4_enabledItems, 32); const float realHP = xc_health.GetHP(); u32 integralHP; std::memcpy(&integralHP, &realHP, sizeof(u32)); - stream.WriteEncoded(integralHP, 32); - stream.WriteEncoded(u32(x8_currentBeam), CBitStreamWriter::GetBitCount(5)); - stream.WriteEncoded(u32(x20_currentSuit), CBitStreamWriter::GetBitCount(4)); + stream.WriteBits(integralHP, 32); + stream.WriteBits(u32(x8_currentBeam), COutputStream::GetBitCount(5)); + stream.WriteBits(u32(x20_currentSuit), COutputStream::GetBitCount(4)); for (size_t i = 0; i < x24_powerups.size(); ++i) { const CPowerUp& pup = x24_powerups[i]; - stream.WriteEncoded(pup.x0_amount, CBitStreamWriter::GetBitCount(PowerUpMaxValues[i])); - stream.WriteEncoded(pup.x4_capacity, CBitStreamWriter::GetBitCount(PowerUpMaxValues[i])); + stream.WriteBits(pup.x0_amount, COutputStream::GetBitCount(PowerUpMaxValues[i])); + stream.WriteBits(pup.x4_capacity, COutputStream::GetBitCount(PowerUpMaxValues[i])); } for (const auto& scanTime : x170_scanTimes) { if (scanTime.second >= 1.f) - stream.WriteEncoded(true, 1); + stream.WriteBits(true, 1); else - stream.WriteEncoded(false, 1); + stream.WriteBits(false, 1); } - stream.WriteEncoded(x180_scanCompletionRate.first, CBitStreamWriter::GetBitCount(0x100)); - stream.WriteEncoded(x180_scanCompletionRate.second, CBitStreamWriter::GetBitCount(0x100)); + stream.WriteBits(x180_scanCompletionRate.first, COutputStream::GetBitCount(0x100)); + stream.WriteBits(x180_scanCompletionRate.second, COutputStream::GetBitCount(0x100)); } u32 CPlayerState::GetMissileCostForAltAttack() const { return costs[size_t(x8_currentBeam)]; } @@ -437,7 +438,7 @@ CPlayerState::EItemType CPlayerState::ItemNameToType(std::string_view name) { }}; std::string lowName{name}; - athena::utility::tolower(lowName); + CStringExtras::ToLower(lowName); const auto iter = std::find_if(typeNameMap.cbegin(), typeNameMap.cend(), [&lowName](const auto& entry) { return entry.first == lowName; }); diff --git a/Runtime/CPlayerState.hpp b/Runtime/CPlayerState.hpp index 72ae5b136..adc268e0d 100644 --- a/Runtime/CPlayerState.hpp +++ b/Runtime/CPlayerState.hpp @@ -4,7 +4,7 @@ #include #include "Runtime/CStaticInterference.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/rstl.hpp" #include "Runtime/World/CHealthInfo.hpp" @@ -164,8 +164,8 @@ public: CStaticInterference& GetStaticInterference() { return x188_staticIntf; } const std::vector>& GetScanTimes() const { return x170_scanTimes; } CPlayerState(); - explicit CPlayerState(CBitStreamReader& stream); - void PutTo(CBitStreamWriter& stream); + explicit CPlayerState(CInputStream& stream); + void PutTo(COutputStream& stream); static u32 GetPowerUpMaxValue(EItemType type); static EItemType ItemNameToType(std::string_view name); static std::string_view ItemTypeToName(EItemType type); diff --git a/Runtime/CRandom16.cpp b/Runtime/CRandom16.cpp index 4cf44ec54..31b3921ab 100644 --- a/Runtime/CRandom16.cpp +++ b/Runtime/CRandom16.cpp @@ -6,9 +6,12 @@ CRandom16* CRandom16::g_randomNumber = nullptr; // &DefaultRandom CGlobalRandom* CGlobalRandom::g_currentGlobalRandom = nullptr; //&DefaultGlobalRandom; namespace { u32 g_numNextCalls = 0; +u32 g_lastSeed = 0; }; void CRandom16::IncrementNumNextCalls() { ++g_numNextCalls; } u32 CRandom16::GetNumNextCalls() { return g_numNextCalls; } void CRandom16::ResetNumNextCalls() { g_numNextCalls = 0; } +u32 CRandom16::GetLastSeed() { return g_lastSeed; } +void CRandom16::SetLastSeed(u32 seed) { g_lastSeed = seed; } } // namespace metaforce diff --git a/Runtime/CRandom16.hpp b/Runtime/CRandom16.hpp index 1a8e9ff05..1ddfacd3a 100644 --- a/Runtime/CRandom16.hpp +++ b/Runtime/CRandom16.hpp @@ -14,6 +14,7 @@ public: s32 Next() { IncrementNumNextCalls(); m_seed = (m_seed * 0x41c64e6d) + 0x00003039; + SetLastSeed(m_seed); return (m_seed >> 16) & 0xffff; } @@ -32,6 +33,8 @@ public: static void IncrementNumNextCalls(); static u32 GetNumNextCalls(); static void ResetNumNextCalls(); + static u32 GetLastSeed(); + static void SetLastSeed(u32 seed); }; class CGlobalRandom { diff --git a/Runtime/CResFactory.cpp b/Runtime/CResFactory.cpp index e0d446f36..459988fde 100644 --- a/Runtime/CResFactory.cpp +++ b/Runtime/CResFactory.cpp @@ -65,7 +65,7 @@ void CResFactory::BuildAsync(const SObjectTag& tag, const CVParamTransfer& xfer, if (search == m_loadMap.end()) { SLoadingData data(tag, target, xfer, x4_loader.GetResourceCompression(tag), selfRef); data.x14_resSize = x4_loader.ResourceSize(tag); - if (data.x14_resSize) { + if (data.x14_resSize != 0) { data.x10_loadBuffer = std::unique_ptr(new u8[data.x14_resSize]); data.x8_dvdReq = x4_loader.LoadResourceAsync(tag, data.x10_loadBuffer.get()); AddToLoadList(std::move(data)); @@ -107,9 +107,9 @@ void CResFactory::CancelBuild(const SObjectTag& tag) { void CResFactory::LoadPersistentResources(CSimplePool& sp) { const auto& paks = x4_loader.GetPaks(); - for (auto it = paks.begin(); it != paks.end(); ++it) { - if (!(*it)->IsWorldPak()) { - for (const CAssetId& id : (*it)->GetDepList()) { + for (const auto & pak : paks) { + if (!pak->IsWorldPak()) { + for (const CAssetId& id : pak->GetDepList()) { SObjectTag tag(GetResourceTypeById(id), id); m_nonWorldTokens.push_back(sp.GetObj(tag)); m_nonWorldTokens.back().Lock(); diff --git a/Runtime/CResLoader.cpp b/Runtime/CResLoader.cpp index 482becd53..99a1b1d9d 100644 --- a/Runtime/CResLoader.cpp +++ b/Runtime/CResLoader.cpp @@ -8,7 +8,7 @@ static logvisor::Module Log("CResLoader"); CResLoader::CResLoader() { x48_curPak = x18_pakLoadedList.end(); } const std::vector* CResLoader::GetTagListForFile(std::string_view name) const { - const std::string namePak = std::string(name).append(".upak"); + const std::string namePak = std::string(name).append(".pak"); for (const std::unique_ptr& pak : x18_pakLoadedList) { if (CStringExtras::CompareCaseInsensitive(namePak, pak->x18_path)) { return &pak->GetDepList(); @@ -18,7 +18,7 @@ const std::vector* CResLoader::GetTagListForFile(std::string_view name } void CResLoader::AddPakFileAsync(std::string_view name, bool buildDepList, bool worldPak, bool override) { - const std::string namePak = std::string(name).append(".upak"); + const std::string namePak = std::string(name).append(".pak"); if (CDvdFile::FileExists(namePak)) { x30_pakLoadingList.emplace_back(std::make_unique(namePak, buildDepList, worldPak, override)); ++x44_pakLoadingCount; @@ -44,7 +44,8 @@ std::unique_ptr CResLoader::LoadNewResourcePartSync(const SObjectT CPakFile* const file = FindResourceForLoad(tag); file->SyncSeekRead(buf, length, ESeekOrigin::Begin, x50_cachedResInfo->GetOffset() + offset); - return std::make_unique(buf, length, !extBuf); + return std::make_unique( + buf, length, extBuf == nullptr ? CMemoryInStream::EOwnerShip::Owned : CMemoryInStream::EOwnerShip::NotOwned); } void CResLoader::LoadMemResourceSync(const SObjectTag& tag, std::unique_ptr& bufOut, int* sizeOut) { @@ -57,9 +58,10 @@ void CResLoader::LoadMemResourceSync(const SObjectTag& tag, std::unique_ptr CResLoader::LoadResourceFromMemorySync(const SObjectTag& tag, const void* buf) { FindResourceForLoad(tag); - std::unique_ptr newStrm = std::make_unique(buf, x50_cachedResInfo->GetSize()); + std::unique_ptr newStrm = + std::make_unique(buf, x50_cachedResInfo->GetSize(), CMemoryInStream::EOwnerShip::NotOwned); if (x50_cachedResInfo->IsCompressed()) { - newStrm->readUint32Big(); + newStrm->ReadLong(); newStrm = std::make_unique(std::move(newStrm)); } return newStrm; @@ -77,9 +79,10 @@ std::unique_ptr CResLoader::LoadNewResourceSync(const SObjectTag& file->SyncSeekRead(buf, resSz, ESeekOrigin::Begin, x50_cachedResInfo->GetOffset()); const bool takeOwnership = extBuf == nullptr; - std::unique_ptr newStrm = std::make_unique(buf, resSz, takeOwnership); + std::unique_ptr newStrm = std::make_unique( + buf, resSz, takeOwnership ? CMemoryInStream::EOwnerShip::Owned : CMemoryInStream::EOwnerShip::NotOwned); if (x50_cachedResInfo->IsCompressed()) { - newStrm->readUint32Big(); + newStrm->ReadLong(); newStrm = std::make_unique(std::move(newStrm)); } @@ -116,7 +119,7 @@ std::unique_ptr CResLoader::LoadNewResourcePartSync(const metaforce::SObje } void CResLoader::GetTagListForFile(const char* pakName, std::vector& out) const { - std::string path = std::string(pakName) + ".upak"; + std::string path = std::string(pakName) + ".pak"; for (const std::unique_ptr& file : m_overridePakList) { if (_GetTagListForFile(out, path, file)) diff --git a/Runtime/CResLoader.hpp b/Runtime/CResLoader.hpp index 17fdc0e0d..b9cc41d82 100644 --- a/Runtime/CResLoader.hpp +++ b/Runtime/CResLoader.hpp @@ -7,7 +7,7 @@ #include #include "Runtime/CPakFile.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" namespace metaforce { diff --git a/Runtime/CScannableObjectInfo.cpp b/Runtime/CScannableObjectInfo.cpp index d950522fc..9cdbb1928 100644 --- a/Runtime/CScannableObjectInfo.cpp +++ b/Runtime/CScannableObjectInfo.cpp @@ -4,7 +4,7 @@ namespace metaforce { CScannableObjectInfo::CScannableObjectInfo(CInputStream& in, CAssetId resId) : x0_scannableObjectId(resId) { - const u32 version = in.readUint32Big(); + const u32 version = in.ReadLong(); Load(in, version); for (auto& bucket : x14_buckets) { @@ -33,18 +33,18 @@ CScannableObjectInfo::CScannableObjectInfo(CInputStream& in, CAssetId resId) : x } void CScannableObjectInfo::Load(CInputStream& in, u32 version) { - in.readUint32Big(); - in.readUint32Big(); - x4_stringId = in.readUint32Big(); + in.ReadLong(); + in.ReadLong(); + x4_stringId = in.Get(); if (version < 4) { - x8_totalDownloadTime = in.readFloatBig(); + x8_totalDownloadTime = in.ReadFloat(); } else { - const u32 scanSpeed = in.readUint32Big(); + const u32 scanSpeed = in.ReadLong(); x8_totalDownloadTime = g_tweakGui->GetScanSpeed(scanSpeed); } - xc_category = in.readUint32Big(); + xc_category = in.ReadLong(); if (version > 4) { - x10_important = in.readBool(); + x10_important = in.ReadBool(); } for (size_t i = 0; i < x14_buckets.capacity(); i++) { @@ -53,15 +53,15 @@ void CScannableObjectInfo::Load(CInputStream& in, u32 version) { } CScannableObjectInfo::SBucket::SBucket(CInputStream& in, u32 version) { - x0_texture = in.readUint32Big(); - x4_appearanceRange = in.readFloatBig(); - x8_imagePos = in.readUint32Big(); + x0_texture = in.Get(); + x4_appearanceRange = in.ReadFloat(); + x8_imagePos = in.ReadLong(); if (version > 1) { - xc_size.x = in.readUint32Big(); - xc_size.y = in.readUint32Big(); - x14_interval = in.readFloatBig(); + xc_size.x = in.ReadLong(); + xc_size.y = in.ReadLong(); + x14_interval = in.ReadFloat(); if (version >= 3) - x18_fadeDuration = in.readFloatBig(); + x18_fadeDuration = in.ReadFloat(); } } diff --git a/Runtime/CScriptMailbox.cpp b/Runtime/CScriptMailbox.cpp index 2f6b10dde..a6b64edb8 100644 --- a/Runtime/CScriptMailbox.cpp +++ b/Runtime/CScriptMailbox.cpp @@ -8,12 +8,12 @@ namespace metaforce { -CScriptMailbox::CScriptMailbox(CBitStreamReader& in, const CWorldSaveGameInfo& saveWorld) { +CScriptMailbox::CScriptMailbox(CInputStream& in, const CWorldSaveGameInfo& saveWorld) { const u32 relayCount = saveWorld.GetRelayCount(); if (saveWorld.GetRelayCount()) { std::vector relayStates(saveWorld.GetRelayCount()); for (u32 i = 0; i < relayCount; ++i) { - relayStates[i] = in.ReadEncoded(1); + relayStates[i] = in.ReadBits(1); } for (u32 i = 0; i < relayCount; ++i) { @@ -79,7 +79,7 @@ void CScriptMailbox::SendMsgs(TAreaId areaId, CStateManager& stateMgr) { } } -void CScriptMailbox::PutTo(CBitStreamWriter& out, const CWorldSaveGameInfo& saveWorld) { +void CScriptMailbox::PutTo(COutputStream& out, const CWorldSaveGameInfo& saveWorld) { const u32 relayCount = saveWorld.GetRelayCount(); std::vector relays(relayCount); @@ -91,7 +91,7 @@ void CScriptMailbox::PutTo(CBitStreamWriter& out, const CWorldSaveGameInfo& save } for (u32 i = 0; i < relayCount; ++i) { - out.WriteEncoded(u32(relays[i]), 1); + out.WriteBits(u32(relays[i]), 1); } } diff --git a/Runtime/CScriptMailbox.hpp b/Runtime/CScriptMailbox.hpp index a8fac0dbc..658a1b100 100644 --- a/Runtime/CScriptMailbox.hpp +++ b/Runtime/CScriptMailbox.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/World/ScriptObjectSupport.hpp" @@ -29,13 +29,13 @@ class CScriptMailbox { public: CScriptMailbox() = default; - CScriptMailbox(CBitStreamReader& in, const CWorldSaveGameInfo& saveWorld); + CScriptMailbox(CInputStream& in, const CWorldSaveGameInfo& saveWorld); bool HasMsg(TEditorId id) const; void AddMsg(TEditorId id); void RemoveMsg(TEditorId id); void SendMsgs(TAreaId areaId, CStateManager& stateMgr); - void PutTo(CBitStreamWriter& out, const CWorldSaveGameInfo& saveWorld); + void PutTo(COutputStream& out, const CWorldSaveGameInfo& saveWorld); }; } // namespace metaforce diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 99f062b9d..df9cac33b 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -17,7 +17,7 @@ #include "Runtime/CSortedLists.hpp" #include "Runtime/CTimeProvider.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CLight.hpp" #include "Runtime/Input/ControlMapper.hpp" #include "Runtime/Input/CRumbleManager.hpp" @@ -47,19 +47,19 @@ #include "Runtime/World/CSnakeWeedSwarm.hpp" #include "Runtime/World/CWallCrawlerSwarm.hpp" #include "Runtime/World/CWorld.hpp" -#include "TCastTo.hpp" // Generated file, do not modify include path +#include "Runtime/ConsoleVariables/CVarManager.hpp" -#include +#include "TCastTo.hpp" // Generated file, do not modify include path #include namespace metaforce { namespace { -hecl::CVar* debugToolDrawAiPath = nullptr; -hecl::CVar* debugToolDrawLighting = nullptr; -hecl::CVar* debugToolDrawCollisionActors = nullptr; -hecl::CVar* debugToolDrawMazePath = nullptr; -hecl::CVar* debugToolDrawPlatformCollision = nullptr; -hecl::CVar* sm_logScripting = nullptr; +CVar* debugToolDrawAiPath = nullptr; +CVar* debugToolDrawLighting = nullptr; +CVar* debugToolDrawCollisionActors = nullptr; +CVar* debugToolDrawMazePath = nullptr; +CVar* debugToolDrawPlatformCollision = nullptr; +CVar* sm_logScripting = nullptr; } // namespace logvisor::Module LogModule("metaforce::CStateManager"); CStateManager::CStateManager(const std::weak_ptr& mailbox, const std::weak_ptr& mwInfo, @@ -81,7 +81,7 @@ CStateManager::CStateManager(const std::weak_ptr& mailbox, const x88c_rumbleManager = &x86c_stateManagerContainer->xf250_rumbleManager; g_Renderer->SetDrawableCallback(&CStateManager::RendererDrawCallback, this); - x908_loaderCount = int(EScriptObjectType::ScriptObjectTypeMAX); + x90c_loaderFuncs.resize(int(EScriptObjectType::ScriptObjectTypeMAX)); x90c_loaderFuncs[size_t(EScriptObjectType::Actor)] = ScriptLoader::LoadActor; x90c_loaderFuncs[size_t(EScriptObjectType::Waypoint)] = ScriptLoader::LoadWaypoint; x90c_loaderFuncs[size_t(EScriptObjectType::Door)] = ScriptLoader::LoadDoor; @@ -217,9 +217,9 @@ CStateManager::CStateManager(const std::weak_ptr& mailbox, const g_StateManager = this; if (sm_logScripting == nullptr) { - sm_logScripting = hecl::CVarManager::instance()->findOrMakeCVar( + sm_logScripting = CVarManager::instance()->findOrMakeCVar( "stateManager.logScripting"sv, "Prints object communication to the console", false, - hecl::CVar::EFlags::ReadOnly | hecl::CVar::EFlags::Archive | hecl::CVar::EFlags::Game); + CVar::EFlags::ReadOnly | CVar::EFlags::Archive | CVar::EFlags::Game); } m_logScriptingReference.emplace(&m_logScripting, sm_logScripting); } @@ -439,7 +439,7 @@ void CStateManager::SetupParticleHook(const CActor& actor) const { void CStateManager::MurderScriptInstanceNames() { xb40_uniqueInstanceNames.clear(); } -std::string CStateManager::HashInstanceName(CInputStream& in) { return in.readString(); } +std::string CStateManager::HashInstanceName(CInputStream& in) { return in.Get(); } void CStateManager::SetActorAreaId(CActor& actor, TAreaId aid) { const TAreaId actorAid = actor.GetAreaIdAlways(); @@ -504,8 +504,8 @@ void CStateManager::DrawReflection(const zeus::CVector3f& reflectPoint) { CGraphics::SetViewPointMatrix(look); const CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState(); const CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this); - g_Renderer->SetPerspective(cam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, cam->GetNearClipDistance(), - cam->GetFarClipDistance()); + g_Renderer->SetPerspective(cam->GetFov(), CGraphics::GetViewportWidth(), CGraphics::GetViewportHeight(), + cam->GetNearClipDistance(), cam->GetFarClipDistance()); x84c_player->RenderReflectedPlayer(*this); @@ -534,6 +534,8 @@ void CStateManager::BuildDynamicLightListForWorld() { } x8e0_dynamicLights.clear(); + x8e0_dynamicLights.reserve(GetLightObjectList().size()); + for (const CEntity* ent : GetLightObjectList()) { const auto& light = static_cast(*ent); if (light.GetActive()) { @@ -543,20 +545,31 @@ void CStateManager::BuildDynamicLightListForWorld() { } } } + + std::sort(x8e0_dynamicLights.begin(), x8e0_dynamicLights.end(), [](const CLight& a, const CLight& b) { + if (b.GetPriority() > a.GetPriority()) { + return true; + } else if (b.GetPriority() == a.GetPriority()) { + return a.GetIntensity() > b.GetIntensity(); + } else { + return false; + } + }); } + void CStateManager::DrawDebugStuff() const { - if (hecl::com_developer != nullptr && !hecl::com_developer->toBoolean()) { + if (com_developer != nullptr && !com_developer->toBoolean()) { return; } // FIXME: Add proper globals for CVars if (debugToolDrawAiPath == nullptr || debugToolDrawCollisionActors == nullptr || debugToolDrawLighting == nullptr || debugToolDrawMazePath == nullptr || debugToolDrawPlatformCollision == nullptr) { - debugToolDrawAiPath = hecl::CVarManager::instance()->findCVar("debugTool.drawAiPath"); - debugToolDrawMazePath = hecl::CVarManager::instance()->findCVar("debugTool.drawMazePath"); - debugToolDrawCollisionActors = hecl::CVarManager::instance()->findCVar("debugTool.drawCollisionActors"); - debugToolDrawLighting = hecl::CVarManager::instance()->findCVar("debugTool.drawLighting"); - debugToolDrawPlatformCollision = hecl::CVarManager::instance()->findCVar("debugTool.drawPlatformCollision"); + debugToolDrawAiPath = CVarManager::instance()->findCVar("debugTool.drawAiPath"); + debugToolDrawMazePath = CVarManager::instance()->findCVar("debugTool.drawMazePath"); + debugToolDrawCollisionActors = CVarManager::instance()->findCVar("debugTool.drawCollisionActors"); + debugToolDrawLighting = CVarManager::instance()->findCVar("debugTool.drawLighting"); + debugToolDrawPlatformCollision = CVarManager::instance()->findCVar("debugTool.drawPlatformCollision"); return; } @@ -600,7 +613,7 @@ void CStateManager::DrawDebugStuff() const { void CStateManager::RenderCamerasAndAreaLights() { x870_cameraManager->RenderCameras(*this); - for (const CCameraFilterPassPoly& filter : xb84_camFilterPasses) { + for (auto& filter : xb84_camFilterPasses) { filter.Draw(); } } @@ -615,7 +628,7 @@ void CStateManager::DrawE3DeathEffect() { const float blurAmt = zeus::clamp(0.f, (player.x9f4_deathTime - 1.f) / (6.f - 1.f), 1.f); if (blurAmt > 0.f) { CCameraBlurPass blur; - blur.SetBlur(EBlurType::HiBlur, 7.f * blurAmt, 0.f); + blur.SetBlur(EBlurType::HiBlur, 7.f * blurAmt, 0.f, false); blur.Draw(); } } @@ -623,7 +636,7 @@ void CStateManager::DrawE3DeathEffect() { const float whiteAmt = zeus::clamp(0.f, 1.f - player.x9f4_deathTime / (0.05f * 6.f), 1.f); zeus::CColor color = zeus::skWhite; color.a() = whiteAmt; - m_deathWhiteout.draw(color); + CCameraFilterPass::DrawFilter(EFilterType::Add, EFilterShape::Fullscreen, color, nullptr, 1.f); } void CStateManager::DrawAdditionalFilters() { @@ -633,7 +646,7 @@ void CStateManager::DrawAdditionalFilters() { zeus::CColor color = zeus::skWhite; color.a() = 1.f - xf0c_escapeTimer; - m_escapeWhiteout.draw(color); + CCameraFilterPass::DrawFilter(EFilterType::Add, EFilterShape::Fullscreen, color, nullptr, 1.f); } zeus::CFrustum CStateManager::SetupDrawFrustum(const SViewport& vp) const { @@ -658,7 +671,7 @@ zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const { const CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this); const zeus::CTransform camXf = x870_cameraManager->GetCurrentCameraTransform(*this); g_Renderer->SetWorldViewpoint(camXf); - CBooModel::SetNewPlayerPositionAndTime(x84c_player->GetTranslation()); + CCubeModel::SetNewPlayerPositionAndTime(x84c_player->GetTranslation(), CStopwatch::GetGlobalTimerObj()); const int vpWidth = static_cast(xf2c_viewportScale.x() * vp.x8_width); const int vpHeight = static_cast(xf2c_viewportScale.y() * vp.xc_height); const int vpLeft = static_cast((vp.x8_width - vpWidth) / 2 + vp.x0_left); @@ -674,29 +687,10 @@ zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const { proj.setPersp(zeus::SProjPersp{fov, width / height, cam->GetNearClipDistance(), cam->GetFarClipDistance()}); frustum.updatePlanes(camXf, proj); g_Renderer->SetClippingPlanes(frustum); - // g_Renderer->PrimColor(zeus::skWhite); + g_Renderer->PrimColor(zeus::skWhite); CGraphics::SetModelMatrix(zeus::CTransform()); x87c_fluidPlaneManager->StartFrame(false); - g_Renderer->SetDebugOption(IRenderer::EDebugOption::One, 1); - return frustum; -} - -zeus::CFrustum CStateManager::SetupViewForCubeFaceDraw(const zeus::CVector3f& pos, int face) const { - const zeus::CTransform mainCamXf = x870_cameraManager->GetCurrentCameraTransform(*this); - const zeus::CTransform camXf = zeus::CTransform(mainCamXf.basis * CGraphics::skCubeBasisMats[face], pos); - g_Renderer->SetWorldViewpoint(camXf); - CBooModel::SetNewPlayerPositionAndTime(x84c_player->GetTranslation()); - constexpr float width = CUBEMAP_RES; - g_Renderer->SetViewport(0, 0, width, width); - CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR); - constexpr float fov = zeus::degToRad(90.f); - g_Renderer->SetPerspective(zeus::radToDeg(fov), width, width, 0.2f, 750.f); - zeus::CFrustum frustum; - zeus::CProjection proj; - proj.setPersp(zeus::SProjPersp{fov, 1.f, 0.2f, 750.f}); - frustum.updatePlanes(camXf, proj); - g_Renderer->SetClippingPlanes(frustum); - CGraphics::SetModelMatrix(zeus::CTransform()); + g_Renderer->SetDebugOption(IRenderer::EDebugOption::PVSState, int(EPVSVisSetState::NodeFound)); return frustum; } @@ -707,27 +701,25 @@ void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport, const CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this); zeus::CFrustum frustum; - frustum.updatePlanes(backupViewMatrix, zeus::SProjPersp(zeus::degToRad(cam->GetFov()), g_Viewport.aspect, + frustum.updatePlanes(backupViewMatrix, zeus::SProjPersp(zeus::degToRad(cam->GetFov()), CGraphics::GetViewportAspect(), cam->GetNearClipDistance(), cam->GetFarClipDistance())); g_Renderer->SetClippingPlanes(frustum); - g_Renderer->SetPerspective(cam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, cam->GetNearClipDistance(), - cam->GetFarClipDistance()); + g_Renderer->SetPerspective(cam->GetFov(), CGraphics::GetViewportWidth(), CGraphics::GetViewportHeight(), + cam->GetNearClipDistance(), cam->GetFarClipDistance()); } void CStateManager::DrawWorld() { SCOPED_GRAPHICS_DEBUG_GROUP("CStateManager::DrawWorld", zeus::skBlue); const CTimeProvider timeProvider(xf14_curTimeMod900); - const SViewport backupViewport = g_Viewport; + const SViewport backupViewport = CGraphics::g_Viewport; /* Area camera is in (not necessarily player) */ const TAreaId visAreaId = GetVisAreaId(); x850_world->TouchSky(); - DrawWorldCubeFaces(); - - const zeus::CFrustum frustum = SetupViewForDraw(g_Viewport); + const zeus::CFrustum frustum = SetupViewForDraw(CGraphics::g_Viewport); const zeus::CTransform backupViewMatrix = CGraphics::g_ViewMatrix; int areaCount = 0; @@ -790,7 +782,6 @@ void CStateManager::DrawWorld() { SetupFogForArea(area); g_Renderer->EnablePVS(pvsArr[i], area.x4_selfIdx); g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel); - g_Renderer->UpdateAreaUniforms(area.x4_selfIdx); g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, mask, targetMask); } @@ -984,120 +975,6 @@ void CStateManager::DrawWorld() { DrawAdditionalFilters(); } -void CStateManager::DrawActorCubeFaces(CActor& actor, int& cubeInst) const { - if (!actor.m_reflectionCube || - (!TCastToPtr(actor) && (!actor.GetActive() || !actor.IsDrawEnabled() || actor.xe4_30_outOfFrustum))) - return; - - const TAreaId visAreaId = actor.GetAreaIdAlways(); - const SViewport backupVp = g_Viewport; - - int areaCount = 0; - std::array areaArr; - for (const CGameArea& area : *x850_world) { - if (areaCount == 10) { - break; - } - auto occState = CGameArea::EOcclusionState::Occluded; - if (area.IsPostConstructed()) { - occState = area.GetOcclusionState(); - } - if (occState == CGameArea::EOcclusionState::Visible) { - areaArr[areaCount++] = &area; - } - } - - for (int f = 0; f < 6; ++f) { - SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CStateManager::DrawActorCubeFaces [{}] {} {} {}"), f, - actor.GetUniqueId(), actor.GetEditorId(), actor.GetName()) - .c_str(), - zeus::skOrange); - CGraphics::g_BooMainCommandQueue->setRenderTarget(actor.m_reflectionCube, f); - SetupViewForCubeFaceDraw(actor.GetRenderBounds().center(), f); - CGraphics::g_BooMainCommandQueue->clearTarget(); - - std::sort(areaArr.begin(), areaArr.begin() + areaCount, [visAreaId](const CGameArea* a, const CGameArea* b) { - if (a->x4_selfIdx == b->x4_selfIdx) { - return false; - } - if (visAreaId == a->x4_selfIdx) { - return false; - } - if (visAreaId == b->x4_selfIdx) { - return true; - } - return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) > CGraphics::g_ViewPoint.dot(b->GetAABB().center()); - }); - - int pvsCount = 0; - std::array pvsArr; - for (auto area = areaArr.cbegin(); area != areaArr.cbegin() + areaCount; ++area) { - const CGameArea* areaPtr = *area; - CPVSVisSet& pvsSet = pvsArr[pvsCount++]; - pvsSet.Reset(EPVSVisSetState::OutOfBounds); - GetVisSetForArea(areaPtr->x4_selfIdx, visAreaId, pvsSet); - } - - for (int i = areaCount - 1; i >= 0; --i) { - const CGameArea& area = *areaArr[i]; - SetupFogForArea(area); - g_Renderer->EnablePVS(pvsArr[i], area.x4_selfIdx); - g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel); - g_Renderer->UpdateAreaUniforms(area.x4_selfIdx, EWorldShadowMode::None, true, cubeInst * 6 + f); - g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, 0x2, 0x0); - } - - if (!SetupFogForDraw()) { - g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::skBlack); - } - - x850_world->DrawSky(zeus::CTransform::Translate(CGraphics::g_ViewPoint)); - - for (int i = 0; i < areaCount; ++i) { - const CGameArea& area = *areaArr[i]; - CPVSVisSet& pvs = pvsArr[i]; - SetupFogForArea(area); - g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel); - g_Renderer->EnablePVS(pvs, area.x4_selfIdx); - g_Renderer->DrawSortedGeometry(area.x4_selfIdx, 0x2, 0x0); - } - } - - CGraphics::g_BooMainCommandQueue->generateMipmaps(actor.m_reflectionCube); - - CBooRenderer::BindMainDrawTarget(); - g_Renderer->SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height); - - ++cubeInst; -} - -void CStateManager::DrawWorldCubeFaces() const { - size_t areaCount = 0; - std::array areaArr; - for (const CGameArea& area : *x850_world) { - if (areaCount == areaArr.size()) { - break; - } - auto occState = CGameArea::EOcclusionState::Occluded; - if (area.IsPostConstructed()) { - occState = area.GetOcclusionState(); - } - if (occState == CGameArea::EOcclusionState::Visible) { - areaArr[areaCount++] = &area; - } - } - - for (size_t ai = 0; ai < areaCount; ++ai) { - const CGameArea& area = *areaArr[ai]; - int cubeInst = 0; - for (CEntity* ent : *area.GetAreaObjects()) { - if (const TCastToPtr actor = ent) { - DrawActorCubeFaces(*actor, cubeInst); - } - } - } -} - void CStateManager::SetupFogForArea3XRange(TAreaId area) const { if (area == kInvalidAreaId) { area = x8cc_nextAreaId; @@ -1197,7 +1074,7 @@ void CStateManager::PreRender() { } SCOPED_GRAPHICS_DEBUG_GROUP("CStateManager::PreRender", zeus::skBlue); - const zeus::CFrustum frustum = SetupDrawFrustum(g_Viewport); + const zeus::CFrustum frustum = SetupDrawFrustum(CGraphics::g_Viewport); x86c_stateManagerContainer->xf370_.clear(); x86c_stateManagerContainer->xf39c_renderLast.clear(); xf7c_projectedShadow = nullptr; @@ -1470,14 +1347,14 @@ CStateManager::GetIdListForScript(TEditorId id) const { } void CStateManager::LoadScriptObjects(TAreaId aid, CInputStream& in, std::vector& idsOut) { - in.readUByte(); + in.ReadUint8(); - const u32 objCount = in.readUint32Big(); + const u32 objCount = in.ReadLong(); idsOut.reserve(idsOut.size() + objCount); for (u32 i = 0; i < objCount; ++i) { - const auto objType = static_cast(in.readUByte()); - const u32 objSize = in.readUint32Big(); - const u32 pos = static_cast(in.position()); + const auto objType = static_cast(in.ReadUint8()); + const u32 objSize = in.ReadLong(); + const u32 pos = static_cast(in.GetReadPosition()); const auto id = LoadScriptObject(aid, objType, objSize, in); if (id.first == kInvalidEditorId) { continue; @@ -1502,15 +1379,15 @@ void CStateManager::LoadScriptObjects(TAreaId aid, CInputStream& in, std::vector std::pair CStateManager::LoadScriptObject(TAreaId aid, EScriptObjectType type, u32 length, CInputStream& in) { OPTICK_EVENT(); - const TEditorId id = in.readUint32Big(); - const u32 connCount = in.readUint32Big(); + const TEditorId id = in.ReadLong(); + const u32 connCount = in.ReadLong(); length -= 8; std::vector conns; conns.reserve(connCount); for (u32 i = 0; i < connCount; ++i) { - const auto state = EScriptObjectState(in.readUint32Big()); - const auto msg = EScriptObjectMessage(in.readUint32Big()); - const TEditorId target = in.readUint32Big(); + const auto state = EScriptObjectState(in.ReadLong()); + const auto msg = EScriptObjectMessage(in.ReadLong()); + const TEditorId target = in.ReadLong(); // Metaforce Addition if (m_incomingConnections.find(target) == m_incomingConnections.cend()) { m_incomingConnections.emplace(target, std::set()); @@ -1521,9 +1398,9 @@ std::pair CStateManager::LoadScriptObject(TAreaId aid, ESc length -= 12; conns.push_back(SConnection{state, msg, target}); } - const u32 propCount = in.readUint32Big(); + const u32 propCount = in.ReadLong(); length -= 4; - const auto startPos = in.position(); + const auto startPos = in.GetReadPosition(); bool error = false; FScriptLoader loader = {}; @@ -1545,7 +1422,7 @@ std::pair CStateManager::LoadScriptObject(TAreaId aid, ESc error = true; } - const u32 readAmt = in.position() - startPos; + const u32 readAmt = in.GetReadPosition() - startPos; if (readAmt > length) { LogModule.report(logvisor::Fatal, FMT_STRING("Script object overread while reading {}"), ScriptObjectTypeToStr(type)); @@ -1553,15 +1430,12 @@ std::pair CStateManager::LoadScriptObject(TAreaId aid, ESc const u32 leftover = length - readAmt; for (u32 i = 0; i < leftover; ++i) { - in.readByte(); + in.ReadChar(); } if (error || ent == nullptr) { - in.seek(startPos, athena::SeekOrigin::Begin); - const std::string name = HashInstanceName(in); - in.seek(startPos + length, athena::SeekOrigin::Begin); - LogModule.report(logvisor::Error, FMT_STRING("Script load error while loading {}, name: {}"), - ScriptObjectTypeToStr(type), name); + LogModule.report(logvisor::Error, FMT_STRING("Script load error while loading {} (Editor ID: {}, Area: {})"), + ScriptObjectTypeToStr(type), id, aid); return {kInvalidEditorId, kInvalidUniqueId}; } else { #ifndef NDEBUG @@ -1609,7 +1483,7 @@ void CStateManager::InitScriptObjects(const std::vector& ids) { void CStateManager::InformListeners(const zeus::CVector3f& pos, EListenNoiseType type) { for (CEntity* ent : GetListeningAiObjectList()) { - if (const TCastToPtr ai = ent) { + if (const TCastToPtr ai = ent) { if (!ai->GetActive()) { continue; } @@ -1645,7 +1519,7 @@ void CStateManager::ApplyKnockBack(CActor& actor, const CDamageInfo& info, const return; } - const TCastToPtr ai = actor; + const TCastToPtr ai = actor; if (!ai && hInfo->GetHP() <= 0.f) { if (dampedPower > hInfo->GetKnockbackResistance()) { if (const TCastToPtr physActor = actor) { @@ -2096,7 +1970,10 @@ void CStateManager::UpdateAreaSounds() { CSfxManager::SetActiveAreas(areas); } -void CStateManager::FrameEnd() { g_SimplePool->Flush(); } +void CStateManager::FrameEnd() { + CModel::FrameDone(); + g_SimplePool->Flush(); +} void CStateManager::ProcessPlayerInput() { if (x84c_player) { @@ -2355,7 +2232,7 @@ void CStateManager::MoveActors(float dt) { continue; } - if (const TCastToPtr ai = physActor) { + if (const TCastToPtr ai = physActor) { bool doThink = !xf94_29_cinematicPause; if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId) { const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways()); @@ -2447,7 +2324,7 @@ void CStateManager::Think(float dt) { } } else { for (CEntity* ent : GetAllObjectList()) { - if (const TCastToPtr ai = ent) { + if (const TCastToPtr ai = ent) { bool doThink = !xf94_29_cinematicPause; if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId) { const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways()); @@ -2487,7 +2364,12 @@ void CStateManager::ClearGraveyard() { x854_objectGraveyard.clear(); } -void CStateManager::FrameBegin(s32 frameCount) { x8d4_inputFrameIdx = frameCount; } +void CStateManager::FrameBegin(s32 frameCount) { + x8d4_inputFrameIdx = frameCount; + CTexture::SetCurrentFrameCount(frameCount); + CGraphicsPalette::SetCurrentFrameCount(frameCount); + // SwapOutTexturesToARAM(2, 0x180000); +} void CStateManager::InitializeState(CAssetId mlvlId, TAreaId aid, CAssetId mreaId) { const bool hadRandom = x900_activeRandom != nullptr; diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 01da8f29d..26b7c15f8 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -18,7 +18,6 @@ #include "Runtime/Camera/CCameraManager.hpp" #include "Runtime/Camera/CCameraShakeData.hpp" #include "Runtime/GameObjectLists.hpp" -#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp" #include "Runtime/Input/CFinalInput.hpp" #include "Runtime/Input/CRumbleManager.hpp" #include "Runtime/Weapon/CWeaponMgr.hpp" @@ -158,10 +157,7 @@ private: CRandom16 x8fc_random; CRandom16* x900_activeRandom = nullptr; EGameState x904_gameState = EGameState::Running; - u32 x908_loaderCount = 0; - std::array x90c_loaderFuncs{}; - - bool xab0_worldLoaded = false; + rstl::reserved_vector x90c_loaderFuncs; enum class EInitPhase { LoadWorld, LoadFirstArea, Done } xb3c_initPhase = EInitPhase::LoadWorld; @@ -170,8 +166,8 @@ private: CFinalInput xb54_finalInput; static constexpr size_t numCameraPasses = 9; - std::array xb84_camFilterPasses; // size: 0x2c - std::array xd14_camBlurPasses; // size: 0x34 + std::array xb84_camFilterPasses; // size: 0x2c + std::array xd14_camBlurPasses; // size: 0x34 s32 xeec_hintIdx = -1; u32 xef0_hintPeriods = 0; @@ -211,13 +207,11 @@ private: bool xf94_29_cinematicPause : 1 = false; bool xf94_30_fullThreat : 1 = false; - CColoredQuadFilter m_deathWhiteout{EFilterType::Add}; - CColoredQuadFilter m_escapeWhiteout{EFilterType::Add}; bool m_warping = false; std::map> m_incomingConnections; bool m_logScripting = false; - std::optional> m_logScriptingReference; + std::optional> m_logScriptingReference; void UpdateThermalVisor(); static void RendererDrawCallback(void*, void*, int); @@ -258,11 +252,8 @@ public: void DrawAdditionalFilters(); zeus::CFrustum SetupDrawFrustum(const SViewport& vp) const; zeus::CFrustum SetupViewForDraw(const SViewport& vp) const; - zeus::CFrustum SetupViewForCubeFaceDraw(const zeus::CVector3f& pos, int face) const; void ResetViewAfterDraw(const SViewport& backupViewport, const zeus::CTransform& backupViewMatrix) const; void DrawWorld(); - void DrawActorCubeFaces(CActor& actor, int& cubeInst) const; - void DrawWorldCubeFaces() const; void SetupFogForArea3XRange(TAreaId area) const; void SetupFogForArea(TAreaId area) const; void SetupFogForAreaNonCurrent(TAreaId area) const; @@ -385,8 +376,8 @@ public: void ClearActiveRandom() { x900_activeRandom = nullptr; } CRumbleManager& GetRumbleManager() { return *x88c_rumbleManager; } const CRumbleManager& GetRumbleManager() const { return *x88c_rumbleManager; } - CCameraFilterPassPoly& GetCameraFilterPass(int idx) { return xb84_camFilterPasses[idx]; } - const CCameraFilterPassPoly& GetCameraFilterPass(int idx) const { return xb84_camFilterPasses[idx]; } + CCameraFilterPass& GetCameraFilterPass(int idx) { return xb84_camFilterPasses[idx]; } + const CCameraFilterPass& GetCameraFilterPass(int idx) const { return xb84_camFilterPasses[idx]; } CCameraBlurPass& GetCameraBlurPass(int idx) { return xd14_camBlurPasses[idx]; } const CCameraBlurPass& GetCameraBlurPass(int idx) const { return xd14_camBlurPasses[idx]; } diff --git a/Runtime/CStaticInterference.cpp b/Runtime/CStaticInterference.cpp index b44d6007c..e6735c9f5 100644 --- a/Runtime/CStaticInterference.cpp +++ b/Runtime/CStaticInterference.cpp @@ -19,7 +19,7 @@ void CStaticInterference::RemoveSource(TUniqueId id) { void CStaticInterference::Update(CStateManager&, float dt) { std::vector newSources; - newSources.reserve(x0_sources.size()); + newSources.reserve(x0_sources.capacity()); for (CStaticInterferenceSource& src : x0_sources) { if (src.x8_timeLeft >= 0.f) { src.x8_timeLeft -= dt; diff --git a/Runtime/CStopwatch.cpp b/Runtime/CStopwatch.cpp new file mode 100644 index 000000000..bf7330bbe --- /dev/null +++ b/Runtime/CStopwatch.cpp @@ -0,0 +1,30 @@ +#include "Runtime/CStopwatch.hpp" + +namespace metaforce { +CStopwatch CStopwatch::mGlobalTimer = {}; + +float CStopwatch::GetElapsedTime() const { + return static_cast(std::chrono::duration_cast(Time::now() - m_startTime).count()) / 1000.f; +} + +u16 CStopwatch::GetElapsedMicros() const { + return std::chrono::duration_cast(Time::now() - m_startTime).count(); +} + +u64 CStopwatch::GetCurMicros() const { + return std::chrono::duration_cast(Time::now().time_since_epoch()).count(); +} + +void CStopwatch::InitGlobalTimer() { mGlobalTimer.Reset(); } + +void CStopwatch::Reset() { m_startTime = std::chrono::steady_clock::now(); } + +void CStopwatch::Wait(float wait) { + if (std::fabs(wait) < 0.001f) { + wait = 0.f; + } + + auto waitDur = FloatSeconds{wait}; + while ((Time::now() - m_startTime) < waitDur) {} +} +} // namespace metaforce \ No newline at end of file diff --git a/Runtime/CStopwatch.hpp b/Runtime/CStopwatch.hpp index 4e2b27675..799ddac7c 100644 --- a/Runtime/CStopwatch.hpp +++ b/Runtime/CStopwatch.hpp @@ -1,31 +1,31 @@ #pragma once +#include "Runtime/GCNTypes.hpp" + +#include #include -#include namespace metaforce { class CStopwatch { - std::chrono::steady_clock::time_point m_start; +private: + static CStopwatch mGlobalTimer; + + using Time = std::chrono::steady_clock; + using MicroSeconds = std::chrono::microseconds; + using MilliSeconds = std::chrono::milliseconds; + using FloatSeconds = std::chrono::duration; + Time::time_point m_startTime; public: - CStopwatch() : m_start(std::chrono::steady_clock::now()) {} - double report(const char* name) const { - double t = - std::chrono::duration_cast(std::chrono::steady_clock::now() - m_start).count() / - 1000000.0; - //#ifndef NDEBUG - // fmt::print(FMT_STRING("{} {}\n"), name, t); - //#endif - return t; - } - double reportReset(const char* name) { - std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); - double t = std::chrono::duration_cast(now - m_start).count() / 1000000.0; - //#ifndef NDEBUG - // fmt::print(FMT_STRING("{} {}\n"), name, t); - //#endif - m_start = now; - return t; - } + static void InitGlobalTimer(); + static CStopwatch& GetGlobalTimerObj() { return mGlobalTimer; } + static float GetGlobalTime() { return mGlobalTimer.GetElapsedTime(); } + + void Reset(); + void Wait(float wait); + + float GetElapsedTime() const; + u16 GetElapsedMicros() const; + u64 GetCurMicros() const; }; } // namespace metaforce diff --git a/Runtime/CStringExtras.cpp b/Runtime/CStringExtras.cpp new file mode 100644 index 000000000..0fb2c9620 --- /dev/null +++ b/Runtime/CStringExtras.cpp @@ -0,0 +1,97 @@ +#include "Runtime/CStringExtras.hpp" +#include "Runtime/Streams/CInputStream.hpp" + +#include + +namespace metaforce { +std::string CStringExtras::ReadString(CInputStream& in) { + u32 strLen = in.ReadLong(); + std::string ret; + u32 readLen = 512; + char tmp[512] = {}; + for (; strLen > 0; strLen -= readLen) { + readLen = 512; + if (strLen <= 512) { + readLen = strLen; + } + in.ReadBytes(tmp, readLen); + ret.append(tmp, readLen); + } + + return ret; +} + +std::string CStringExtras::ConvertToANSI(std::u16string_view sv) { + std::string out; + out.reserve(sv.size()); + for (const char16_t c : sv) { + out.push_back(static_cast(c)); + } + return out; +} + +std::u16string CStringExtras::ConvertToUNICODE(std::string_view sv) { + std::u16string out; + out.reserve(sv.size()); + for (const char c : sv) { + out.push_back(static_cast(c)); + } + return out; +} + +std::string CStringExtras::ConvertToUTF8(std::u16string_view sv) { + std::string out; + const auto* in = sv.data(); + const auto* end = in + sv.size(); + while (in < end) { + char32_t utf32 = 0; + const char16_t* next = OSUTF16To32(in, &utf32); + // TODO: bug in OSUTF + if (next == nullptr) { + utf32 = *in; + in++; + } else { + in = next; + } + std::array chars8{}; + char8_t* end8 = OSUTF32To8(utf32, chars8.data()); + if (end8 == nullptr) { + continue; + } + const auto* c = chars8.data(); + while (c < end8) { + out.push_back(static_cast(*c)); + c++; + } + } + return out; +} + +std::u16string CStringExtras::ConvertToUTF16(std::string_view sv) { + std::u16string out; + const auto* in = reinterpret_cast(sv.data()); + const auto* end = in + sv.size(); + while (in < end) { + char32_t utf32 = 0; + const char8_t* next = OSUTF8To32(in, &utf32); + // TODO: bug in OSUTF + if (next == nullptr) { + utf32 = *in; + in++; + } else { + in = next; + } + std::array chars16{}; + char16_t* end16 = OSUTF32To16(utf32, chars16.data()); + if (end16 == nullptr) { + continue; + } + const auto* c = chars16.data(); + while (c < end16) { + out.push_back(*c); + c++; + } + } + return out; +} +} // namespace metaforce diff --git a/Runtime/CStringExtras.hpp b/Runtime/CStringExtras.hpp index 96bb9ba3a..99040af27 100644 --- a/Runtime/CStringExtras.hpp +++ b/Runtime/CStringExtras.hpp @@ -3,11 +3,19 @@ #include #include #include +#include +#include namespace metaforce { - +class CInputStream; class CStringExtras { public: + static std::string ConvertToANSI(std::u16string_view sv); + static std::u16string ConvertToUNICODE(std::string_view sv); + // Metaforce addition: UTF-8/16 compatible versions of the above + static std::string ConvertToUTF8(std::u16string_view sv); + static std::u16string ConvertToUTF16(std::string_view sv); + // Checks if the provided views into string data can be considered equal or not based on // whether or not all their characters are equal to one another in a character insensitive manner. // @@ -35,6 +43,72 @@ public: } return s; } + + static inline void ToLower(std::string& str) { std::transform(str.begin(), str.end(), str.begin(), ::tolower); } + static std::string ReadString(CInputStream& in); + static inline bool ParseBool(std::string_view boolean, bool* valid) { + std::string val(boolean); + // compare must be case insensitive + // This is the cleanest solution since I only need to do it once + ToLower(val); + + // Check for true first + if (val == "true" || val == "1" || val == "yes" || val == "on") { + if (valid) + *valid = true; + + return true; + } + + // Now false + if (val == "false" || val == "0" || val == "no" || val == "off") { + if (valid) + *valid = true; + + return false; + } + + // Well that could've gone better + + if (valid) + *valid = false; + + return false; + } + + static inline std::vector& Split(std::string_view s, char delim, std::vector& elems) { + std::string tmps(s); + std::stringstream ss(tmps); + std::string item; + + while (std::getline(ss, item, delim)) { + elems.push_back(item); + } + + return elems; + } + + static inline std::vector Split(std::string_view s, char delim) { + std::vector elems; + Split(s, delim, elems); + return elems; + } + + static inline std::string LeftTrim(const std::string &s) + { + size_t start = s.find_first_not_of(" \n\r\t\f\v"); + return (start == std::string::npos) ? "" : s.substr(start); + } + + static inline std::string RightTrim(const std::string &s) + { + size_t end = s.find_last_not_of(" \n\r\t\f\v"); + return (end == std::string::npos) ? "" : s.substr(0, end + 1); + } + + static inline std::string Trim(const std::string &s) { + return RightTrim(LeftTrim(s)); + } }; } // namespace metaforce diff --git a/Runtime/CTextureCache.cpp b/Runtime/CTextureCache.cpp index 77adda107..2c4bee3b3 100644 --- a/Runtime/CTextureCache.cpp +++ b/Runtime/CTextureCache.cpp @@ -3,11 +3,11 @@ namespace metaforce { CTextureCache::CTextureCache(CInputStream& in) { - u32 textureCount = in.readUint32Big(); + u32 textureCount = in.ReadLong(); for (u32 i = 0; i < textureCount; ++i) { CAssetId uid(in); if (m_textureInfo.find(uid) == m_textureInfo.end()) - m_textureInfo.emplace(uid, CTextureInfo(in)); + m_textureInfo.emplace(uid, in.Get()); } } @@ -23,4 +23,4 @@ CFactoryFnReturn FTextureCacheFactory([[maybe_unused]] const SObjectTag& tag, CI [[maybe_unused]] CObjectReference* selfRef) { return TToken::GetIObjObjectFor(std::make_unique(in)); } -} // namespace metaforce \ No newline at end of file +} // namespace metaforce diff --git a/Runtime/CTextureCache.hpp b/Runtime/CTextureCache.hpp index 3f095172f..258965014 100644 --- a/Runtime/CTextureCache.hpp +++ b/Runtime/CTextureCache.hpp @@ -1,6 +1,10 @@ #pragma once + #include "Runtime/RetroTypes.hpp" #include "Runtime/Graphics/CTexture.hpp" + +#include + namespace metaforce { class CPaletteInfo { u32 m_format; @@ -9,7 +13,7 @@ class CPaletteInfo { public: explicit CPaletteInfo(CInputStream& in) - : m_format(in.readUint32Big()), m_elementCount(in.readUint32Big()), m_dolphinHash(in.readUint64Big()) {} + : m_format(in.ReadLong()), m_elementCount(in.ReadLong()), m_dolphinHash(in.ReadLongLong()) {} }; class CTextureInfo { ETexelFormat m_format; @@ -21,12 +25,12 @@ class CTextureInfo { public: explicit CTextureInfo(CInputStream& in) - : m_format(ETexelFormat(in.readUint32Big())) - , m_mipCount(in.readUint32Big()) - , m_width(in.readUint16Big()) - , m_height(in.readUint16Big()) - , m_dolphinHash(in.readUint64Big()) { - bool hasPal = in.readBool(); + : m_format(ETexelFormat(in.ReadLong())) + , m_mipCount(in.ReadLong()) + , m_width(in.ReadShort()) + , m_height(in.ReadShort()) + , m_dolphinHash(in.ReadLongLong()) { + bool hasPal = in.ReadBool(); if (hasPal) m_paletteInfo.emplace(in); } @@ -43,4 +47,4 @@ public: CFactoryFnReturn FTextureCacheFactory(const metaforce::SObjectTag& tag, CInputStream& in, const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); -} // namespace metaforce \ No newline at end of file +} // namespace metaforce diff --git a/Runtime/CToken.cpp b/Runtime/CToken.cpp index 94f756b71..8d0637496 100644 --- a/Runtime/CToken.cpp +++ b/Runtime/CToken.cpp @@ -39,7 +39,7 @@ void CObjectReference::Lock() { } void CObjectReference::CancelLoad() { - if (xC_objectStore && IsLoading()) { + if ((xC_objectStore != nullptr) && IsLoading()) { xC_objectStore->GetFactory().CancelBuild(x4_objTag); x3_loading = false; } @@ -102,6 +102,8 @@ IObj* CToken::GetObj() { return x0_objRef->GetObject(); } CToken& CToken::operator=(const CToken& other) { + if (this == &other) + return *this; Unlock(); RemoveRef(); x0_objRef = other.x0_objRef; diff --git a/Runtime/CToken.hpp b/Runtime/CToken.hpp index d56459df3..0ddd01a83 100644 --- a/Runtime/CToken.hpp +++ b/Runtime/CToken.hpp @@ -91,6 +91,7 @@ public: CToken(IObj* obj); CToken(std::unique_ptr&& obj); const SObjectTag* GetObjectTag() const; + const CObjectReference* GetObjectReference() const { return x0_objRef; } ~CToken(); }; @@ -158,6 +159,8 @@ public: m_obj = nullptr; return *this; } + + bool IsNull() const { return m_obj == nullptr; } }; template diff --git a/Runtime/CWorldSaveGameInfo.cpp b/Runtime/CWorldSaveGameInfo.cpp index dd0829d03..43200231c 100644 --- a/Runtime/CWorldSaveGameInfo.cpp +++ b/Runtime/CWorldSaveGameInfo.cpp @@ -4,50 +4,50 @@ namespace metaforce { CWorldSaveGameInfo::CWorldSaveGameInfo(CInputStream& in) { - in.readUint32Big(); - const u32 version = in.readUint32Big(); + in.ReadLong(); + const u32 version = in.ReadLong(); if (version > 1) { - x0_areaCount = in.readUint32Big(); + x0_areaCount = in.ReadLong(); } if (version > 2) { - const u32 cinematicCount = in.readUint32Big(); + const u32 cinematicCount = in.ReadLong(); x4_cinematics.reserve(cinematicCount); for (u32 i = 0; i < cinematicCount; ++i) { - x4_cinematics.emplace_back(in.readUint32Big()); + x4_cinematics.emplace_back(in.ReadLong()); } - const u32 relayCount = in.readUint32Big(); + const u32 relayCount = in.ReadLong(); x14_relays.reserve(relayCount); for (u32 i = 0; i < relayCount; ++i) { - x14_relays.emplace_back(in.readUint32Big()); + x14_relays.emplace_back(in.ReadLong()); } } - const u32 layerCount = in.readUint32Big(); + const u32 layerCount = in.ReadLong(); x24_layers.reserve(layerCount); for (u32 i = 0; i < layerCount; ++i) { SLayerState& st = x24_layers.emplace_back(); - st.x0_area = in.readUint32Big(); - st.x4_layer = in.readUint32Big(); + st.x0_area = in.ReadLong(); + st.x4_layer = in.ReadLong(); } - const u32 doorCount = in.readUint32Big(); + const u32 doorCount = in.ReadLong(); x34_doors.reserve(doorCount); for (u32 i = 0; i < doorCount; ++i) { - x34_doors.emplace_back(in.readUint32Big()); + x34_doors.emplace_back(in.ReadLong()); } if (version <= 0) { return; } - const u32 scanCount = in.readUint32Big(); + const u32 scanCount = in.ReadLong(); x44_scans.reserve(scanCount); for (u32 i = 0; i < scanCount; ++i) { SScanState& st = x44_scans.emplace_back(); - st.x0_id = in.readUint32Big(); - st.x4_category = EScanCategory(in.readUint32Big()); + st.x0_id = in.Get(); + st.x4_category = EScanCategory(in.ReadLong()); } } diff --git a/Runtime/CWorldSaveGameInfo.hpp b/Runtime/CWorldSaveGameInfo.hpp index e8f31f9d0..91f393da8 100644 --- a/Runtime/CWorldSaveGameInfo.hpp +++ b/Runtime/CWorldSaveGameInfo.hpp @@ -2,8 +2,6 @@ #include -#include "DNACommon/SAVWCommon.hpp" - #include "Runtime/CFactoryMgr.hpp" #include "Runtime/RetroTypes.hpp" @@ -11,7 +9,8 @@ namespace metaforce { class CWorldSaveGameInfo { public: - using EScanCategory = DataSpec::SAVWCommon::EScanCategory; + enum class EScanCategory { None, Data, Lore, Creature, Research, Artifact }; + struct SScanState { CAssetId x0_id; EScanCategory x4_category; diff --git a/Runtime/Camera/CBallCamera.cpp b/Runtime/Camera/CBallCamera.cpp index 2ee35ba44..94c0d8869 100644 --- a/Runtime/Camera/CBallCamera.cpp +++ b/Runtime/Camera/CBallCamera.cpp @@ -51,7 +51,7 @@ CBallCamera::CBallCamera(TUniqueId uid, TUniqueId watchedId, const zeus::CTransf g_tweakBall->GetBallCameraSpringTardis()) , x228_ballCameraCentroidSpring(g_tweakBall->GetBallCameraCentroidSpringConstant(), g_tweakBall->GetBallCameraCentroidSpringMax(), - g_tweakBall->GetBallCameraCentroidSpringTardis()) + g_tweakBall->GetBallCameraCentroidSpringTardis() * 1.1f) , x23c_ballCameraLookAtSpring(g_tweakBall->GetBallCameraLookAtSpringConstant(), g_tweakBall->GetBallCameraLookAtSpringMax(), g_tweakBall->GetBallCameraLookAtSpringTardis()) diff --git a/Runtime/Camera/CCameraFilter.cpp b/Runtime/Camera/CCameraFilter.cpp index f6028b113..752aba7a6 100644 --- a/Runtime/Camera/CCameraFilter.cpp +++ b/Runtime/Camera/CCameraFilter.cpp @@ -1,21 +1,18 @@ #include "Runtime/Camera/CCameraFilter.hpp" +#include "Runtime/CDvdFile.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" +#include "Runtime/Graphics/CGX.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include "Runtime/Graphics/Shaders/CColoredQuadFilter.hpp" -#include "Runtime/Graphics/Shaders/CRandomStaticFilter.hpp" -#include "Runtime/Graphics/Shaders/CScanLinesFilter.hpp" -#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" #include #include namespace metaforce { -template -void CCameraFilterPass::Update(float dt) { +void CCameraFilterPass::Update(float dt) { if (x10_remTime <= 0.f) return; @@ -31,26 +28,16 @@ void CCameraFilterPass::Update(float dt) { x20_nextTxtr = {}; } } - - if (x0_curType == EFilterType::Passthru) - m_shader = std::nullopt; - else if (x0_curType != origType) - m_shader.emplace(x0_curType, x24_texObj); } -template -void CCameraFilterPass::SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, - CAssetId txtr) { +void CCameraFilterPass::SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, + CAssetId txtr) { if (time == 0.f) { xc_duration = 0.f; x10_remTime = 0.f; if (txtr.IsValid()) x24_texObj = g_SimplePool->GetObj({FOURCC('TXTR'), txtr}); - if (type == EFilterType::Passthru) - m_shader = std::nullopt; - else if (x0_curType != type || (x20_nextTxtr != txtr && txtr.IsValid())) - m_shader.emplace(type, x24_texObj); x4_nextType = type; x0_curType = type; @@ -90,28 +77,18 @@ void CCameraFilterPass::SetFilter(EFilterType type, EFilterShape shape, float } x0_curType = x4_nextType; } - - if (x0_curType == EFilterType::Passthru) - m_shader = std::nullopt; - else if (x0_curType != origType || (x20_nextTxtr != origTxtr && x20_nextTxtr.IsValid())) - m_shader.emplace(x0_curType, x24_texObj); } } -template -void CCameraFilterPass::DisableFilter(float time) { - SetFilter(EFilterType::Passthru, x8_shape, time, zeus::skWhite, -1); +void CCameraFilterPass::DisableFilter(float time) { + SetFilter(EFilterType::Passthru, x8_shape, time, zeus::skWhite, {}); } -template -void CCameraFilterPass::Draw() { - if (!m_shader) { - return; - } - m_shader->DrawFilter(x8_shape, x18_curColor, GetT(x4_nextType == EFilterType::Passthru)); +void CCameraFilterPass::Draw() { + DrawFilter(x0_curType, x8_shape, x18_curColor, x24_texObj.GetObj(), GetT(x4_nextType == EFilterType::Passthru)); } -float CCameraFilterPassBase::GetT(bool invert) const { +float CCameraFilterPass::GetT(bool invert) const { float tmp; if (xc_duration == 0.f) tmp = 1.f; @@ -122,58 +99,220 @@ float CCameraFilterPassBase::GetT(bool invert) const { return tmp; } -void CCameraFilterPassPoly::SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, - CAssetId txtr) { - if (!m_filter || m_shape != shape) { - m_shape = shape; - switch (shape) { - case EFilterShape::Fullscreen: - case EFilterShape::FullscreenHalvesLeftRight: - case EFilterShape::FullscreenHalvesTopBottom: - case EFilterShape::FullscreenQuarters: - if (txtr.IsValid()) - m_filter = std::make_unique>(); - else - m_filter = std::make_unique>(); - break; - case EFilterShape::CinemaBars: - m_filter = std::make_unique>(); - break; - case EFilterShape::ScanLinesEven: - m_filter = std::make_unique>(); - break; - case EFilterShape::ScanLinesOdd: - m_filter = std::make_unique>(); - break; - case EFilterShape::RandomStatic: - m_filter = std::make_unique>(); - break; - case EFilterShape::CookieCutterDepthRandomStatic: - m_filter = std::make_unique>(); - break; - default: - break; - } +void CCameraFilterPass::DrawFilter(EFilterType type, EFilterShape shape, const zeus::CColor& color, CTexture* tex, + float lod) { + switch (type) { + case EFilterType::Multiply: + g_Renderer->SetBlendMode_ColorMultiply(); + break; + case EFilterType::Invert: + g_Renderer->SetBlendMode_InvertDst(); + break; + case EFilterType::Add: + g_Renderer->SetBlendMode_AdditiveAlpha(); + break; + case EFilterType::Subtract: + CGX::SetBlendMode(GX_BM_SUBTRACT, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + break; + case EFilterType::Blend: + g_Renderer->SetBlendMode_AlphaBlended(); + break; + case EFilterType::Widescreen: + return; + case EFilterType::SceneAdd: + g_Renderer->SetBlendMode_AdditiveDestColor(); + break; + case EFilterType::NoColor: + g_Renderer->SetBlendMode_NoColorWrite(); + break; + default: + return; } - if (m_filter) - m_filter->SetFilter(type, shape, time, color, txtr); + DrawFilterShape(shape, color, tex, lod); + g_Renderer->SetBlendMode_AlphaBlended(); +} + +void CCameraFilterPass::DrawFullScreenColoredQuad(const zeus::CColor& color) { + SCOPED_GRAPHICS_DEBUG_GROUP("CCameraFilterPass::DrawFullScreenColoredQuad", zeus::skBlue); + const auto [lt, rb] = g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f); + g_Renderer->SetDepthReadWrite(false, false); + g_Renderer->BeginTriangleStrip(4); + g_Renderer->PrimColor(color); + g_Renderer->PrimVertex({lt.x() - 1.f, 0.f, 1.f + rb.y()}); + g_Renderer->PrimVertex({lt.x() - 1.f, 0.f, lt.y() - 1.f}); + g_Renderer->PrimVertex({1.f + rb.x(), 0.f, 1.f + rb.y()}); + g_Renderer->PrimVertex({1.f + rb.x(), 0.f, lt.y() - 1.f}); + g_Renderer->EndPrimitive(); +} + +void CCameraFilterPass::DrawFilterShape(EFilterShape shape, const zeus::CColor& color, CTexture* tex, float lod) { + switch (shape) { + default: + if (tex == nullptr) { + DrawFullScreenColoredQuad(color); + } else { + DrawFullScreenTexturedQuad(color, tex, lod); + } + break; + case EFilterShape::FullscreenQuarters: + if (tex == nullptr) { + DrawFullScreenColoredQuad(color); + } else { + DrawFullScreenTexturedQuadQuarters(color, tex, lod); + } + break; + case EFilterShape::CinemaBars: + DrawWideScreen(color, tex, lod); + break; + case EFilterShape::ScanLinesEven: + DrawScanLines(color, true); + break; + case EFilterShape::ScanLinesOdd: + DrawScanLines(color, false); + break; + case EFilterShape::RandomStatic: + DrawRandomStatic(color, 1.f, false); + break; + case EFilterShape::CookieCutterDepthRandomStatic: + DrawRandomStatic(color, lod, true); + break; + } +} + +void CCameraFilterPass::DrawFullScreenTexturedQuadQuarters(const zeus::CColor& color, CTexture* tex, float lod) { + SCOPED_GRAPHICS_DEBUG_GROUP("CCameraFilterPass::DrawFullScreenTexturedQuadQuarters", zeus::skBlue); + const auto [lt, rb] = g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + g_Renderer->SetDepthReadWrite(false, false); + if (tex != nullptr) { + tex->Load(GX_TEXMAP0, EClampMode::Repeat); + } + CGraphics::SetCullMode(ERglCullMode::None); + for (int i = 0; i < 4; ++i) { + g_Renderer->SetModelMatrix(zeus::CTransform::Scale((i & 1) != 0 ? 1.f : -1.f, 0.f, (i & 2) != 0 ? 1.f : -1.f)); + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(lod, lod); + CGraphics::StreamVertex(lt.x(), 0.f, rb.y()); + CGraphics::StreamTexcoord(lod, 0.f); + CGraphics::StreamVertex(lt.x(), 0.f, 0.f); + CGraphics::StreamTexcoord(0.f, lod); + CGraphics::StreamVertex(0.f, 0.f, rb.y()); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex(0.f, 0.f, 0.f); + CGraphics::StreamEnd(); + } + CGraphics::SetCullMode(ERglCullMode::Front); +} + +void CCameraFilterPass::DrawFullScreenTexturedQuad(const zeus::CColor& color, CTexture* tex, float lod) { + SCOPED_GRAPHICS_DEBUG_GROUP("CCameraFilterPass::DrawFullScreenTexturedQuad", zeus::skBlue); + const float u = 0.5f - 0.5f * lod; + const float v = 0.5f + 0.5f * lod; + const auto [lt, rb] = g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f); + g_Renderer->SetDepthReadWrite(false, false); + if (tex != nullptr) { + tex->Load(GX_TEXMAP0, EClampMode::Repeat); + } + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(u, v); + CGraphics::StreamVertex(lt.x() - 1.f, 0.f, 1.f + rb.y()); + CGraphics::StreamTexcoord(u, u); + CGraphics::StreamVertex(lt.x() - 1.f, 0.f, lt.y() - 1.f); + CGraphics::StreamTexcoord(v, v); + CGraphics::StreamVertex(1.f + rb.x(), 0.f, 1.f + rb.y()); + CGraphics::StreamTexcoord(v, u); + CGraphics::StreamVertex(1.f + rb.x(), 0.f, lt.y() - 1.f); + CGraphics::StreamEnd(); +} + +void CCameraFilterPass::DrawRandomStatic(const zeus::CColor& color, float alpha, bool cookieCutterDepth) { + // TODO this shouldn't be here + static CTexture m_randomStatic{ETexelFormat::IA4, 640, 448, 1, "Camera Random Static"}; + + SCOPED_GRAPHICS_DEBUG_GROUP("CCameraFilterPass::DrawRandomStatic", zeus::skBlue); + const auto [lb, rt] = g_Renderer->SetViewportOrtho(true, 0.f, 1.f); + if (cookieCutterDepth) { + CGraphics::SetAlphaCompare(ERglAlphaFunc::GEqual, static_cast((1.f - alpha) * 255.f), ERglAlphaOp::And, + ERglAlphaFunc::Always, 0); + g_Renderer->SetDepthReadWrite(true, true); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + } else { + g_Renderer->SetDepthReadWrite(false, false); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulateColor); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + } + + // Upload random static texture (game reads from .text) + const u8* buf = CDvdFile::GetDolBuf() + 0x4f60; + u8* out = m_randomStatic.Lock(); + memcpy(out, buf + ROUND_UP_32(rand() & 0x7fff), m_randomStatic.GetMemoryAllocated()); + m_randomStatic.UnLock(); + m_randomStatic.Load(GX_TEXMAP0, EClampMode::Clamp); + + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(0.f, 1.f); + CGraphics::StreamVertex(lb.x() - 1.f, 0.01f, rt.y() + 1.f); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex(lb.x() - 1.f, 0.01f, lb.y() - 1.f); + CGraphics::StreamTexcoord(1.f, 1.f); + CGraphics::StreamVertex(rt.x() + 1.f, 0.01f, rt.y() + 1.f); + CGraphics::StreamTexcoord(1.f, 0.f); + CGraphics::StreamVertex(rt.x() + 1.f, 0.01f, lb.y() - 1.f); + CGraphics::StreamEnd(); + if (cookieCutterDepth) { + CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); + } +} + +void CCameraFilterPass::DrawScanLines(const zeus::CColor& color, bool even) { + SCOPED_GRAPHICS_DEBUG_GROUP("CCameraFilterPass::DrawScanLines", zeus::skBlue); + const auto [lt, rb] = g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f); + g_Renderer->SetDepthReadWrite(false, false); + g_Renderer->SetModelMatrix({}); + // CGraphics::SetLineWidth(2.f, 5); + // g_Renderer->BeginLines(...); + // TODO + // CGraphics::SetLineWidth(1.f, 5); +} + +void CCameraFilterPass::DrawWideScreen(const zeus::CColor& color, CTexture* tex, float lod) { + SCOPED_GRAPHICS_DEBUG_GROUP("CCameraFilterPass::DrawWideScreen", zeus::skBlue); + // const auto vp = g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f); + // float f = -((vp.second.x() - vp.first.x()) * 0.0625f * 9.f - (vp.second.y() - vp.first.y())) * 0.5f; + // g_Renderer->SetDepthReadWrite(false, false); + // g_Renderer->SetModelMatrix({}); + // if (tex != nullptr) { + // tex->Load(GX_TEXMAP0, EClampMode::Repeat); + // } + // CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::sTevPass805a5ebc); + // CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::skPassThru); + // CGraphics::StreamBegin(GX_TRIANGLESTRIP); + // float x = rand() % 4000; } void CCameraBlurPass::Draw(bool clearDepth) { if (x10_curType == EBlurType::NoBlur) return; - if (x10_curType == EBlurType::Xray) { - if (!m_xrayShader) - m_xrayShader.emplace(x0_paletteTex); - m_xrayShader->draw(x1c_curValue); - } else { - if (!m_shader) - m_shader.emplace(); - m_shader->draw(x1c_curValue, clearDepth); - if (clearDepth) - CGraphics::SetDepthRange(DEPTH_NEAR, DEPTH_FAR); - } + // TODO + // if (x10_curType == EBlurType::Xray) { + // if (!m_xrayShader) + // m_xrayShader.emplace(x0_paletteTex); + // m_xrayShader->draw(x1c_curValue); + // } else { + // if (!m_shader) + // m_shader.emplace(); + // m_shader->draw(x1c_curValue, clearDepth); + // if (clearDepth) + // CGraphics::SetDepthRange(DEPTH_NEAR, DEPTH_FAR); + // } } void CCameraBlurPass::Update(float dt) { @@ -188,7 +327,8 @@ void CCameraBlurPass::Update(float dt) { } } -void CCameraBlurPass::SetBlur(EBlurType type, float amount, float duration) { +void CCameraBlurPass::SetBlur(EBlurType type, float amount, float duration, bool usePersistentFb) { + // TODO impl usePersistentFb if (duration == 0.f) { x24_totalTime = 0.f; x28_remainingTime = 0.f; @@ -203,9 +343,9 @@ void CCameraBlurPass::SetBlur(EBlurType type, float amount, float duration) { x14_endType = type; x10_curType = type; - // x2c_usePersistent = b1; + x2c_usePersistent = usePersistentFb; } else { - // x2c_usePersistent = b1; + x2c_usePersistent = usePersistentFb; x24_totalTime = duration; x28_remainingTime = duration; x18_endValue = x1c_curValue; @@ -222,6 +362,6 @@ void CCameraBlurPass::SetBlur(EBlurType type, float amount, float duration) { } } -void CCameraBlurPass::DisableBlur(float duration) { SetBlur(EBlurType::NoBlur, 0.f, duration); } +void CCameraBlurPass::DisableBlur(float duration) { SetBlur(EBlurType::NoBlur, 0.f, duration, x2c_usePersistent); } } // namespace metaforce diff --git a/Runtime/Camera/CCameraFilter.hpp b/Runtime/Camera/CCameraFilter.hpp index 686af021c..06a4226ae 100644 --- a/Runtime/Camera/CCameraFilter.hpp +++ b/Runtime/Camera/CCameraFilter.hpp @@ -4,10 +4,10 @@ #include #include "Runtime/CToken.hpp" -#include "Runtime/RetroTypes.hpp" #include "Runtime/Graphics/CTexture.hpp" #include "Runtime/Graphics/Shaders/CCameraBlurFilter.hpp" #include "Runtime/Graphics/Shaders/CXRayBlurFilter.hpp" +#include "Runtime/RetroTypes.hpp" #include @@ -37,8 +37,8 @@ enum class EFilterShape { CookieCutterDepthRandomStatic }; -class CCameraFilterPassBase { -protected: +class CCameraFilterPass { +private: EFilterType x0_curType = EFilterType::Passthru; EFilterType x4_nextType = EFilterType::Passthru; EFilterShape x8_shape = EFilterShape::Fullscreen; @@ -49,46 +49,24 @@ protected: zeus::CColor x1c_nextColor; CAssetId x20_nextTxtr; TLockedToken x24_texObj; // Used to be auto_ptr - float GetT(bool invert) const; + + [[nodiscard]] float GetT(bool invert) const; + + static void DrawFilterShape(EFilterShape shape, const zeus::CColor& color, CTexture* tex, float lod); + static void DrawFullScreenColoredQuad(const zeus::CColor& color); + static void DrawFullScreenTexturedQuad(const zeus::CColor& color, CTexture* tex, float lod); + static void DrawFullScreenTexturedQuadQuarters(const zeus::CColor& color, CTexture* tex, float lod); + static void DrawRandomStatic(const zeus::CColor& color, float alpha, bool cookieCutterDepth); + static void DrawScanLines(const zeus::CColor& color, bool even); + static void DrawWideScreen(const zeus::CColor& color, CTexture* tex, float lod); public: - virtual ~CCameraFilterPassBase() = default; - virtual void Update(float dt) = 0; - virtual void SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, - CAssetId txtr) = 0; - virtual void DisableFilter(float time) = 0; - virtual void Draw() = 0; -}; - -template -class CCameraFilterPass final : public CCameraFilterPassBase { - std::optional m_shader; - -public: - void Update(float dt) override; - void SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, CAssetId txtr) override; - void DisableFilter(float time) override; - void Draw() override; -}; - -class CCameraFilterPassPoly { - EFilterShape m_shape{}; - std::unique_ptr m_filter; - -public: - void Update(float dt) { - if (m_filter) - m_filter->Update(dt); - } + void Update(float dt); void SetFilter(EFilterType type, EFilterShape shape, float time, const zeus::CColor& color, CAssetId txtr); - void DisableFilter(float time) { - if (m_filter) - m_filter->DisableFilter(time); - } - void Draw() const { - if (m_filter) - m_filter->Draw(); - } + void DisableFilter(float time); + void Draw(); + + static void DrawFilter(EFilterType type, EFilterShape shape, const zeus::CColor& color, CTexture* tex, float lod); }; enum class EBlurType { NoBlur, LoBlur, HiBlur, Xray }; @@ -102,17 +80,14 @@ class CCameraBlurPass { float x20_startValue = 0.f; float x24_totalTime = 0.f; float x28_remainingTime = 0.f; - // bool x2c_usePersistent = false; - // bool x2d_noPersistentCopy = false; - // u32 x30_persistentBuf = 0; - - std::optional m_shader; - std::optional m_xrayShader; + bool x2c_usePersistent = false; + bool x2d_noPersistentCopy = false; + u32 x30_persistentBuf = 0; public: void Draw(bool clearDepth = false); void Update(float dt); - void SetBlur(EBlurType type, float amount, float duration); + void SetBlur(EBlurType type, float amount, float duration, bool usePersistentFb); void DisableBlur(float duration); EBlurType GetCurrType() const { return x10_curType; } }; diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index 3b132059b..4e33e1e5b 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -77,7 +77,7 @@ void CCameraManager::EnterCinematic(CStateManager& mgr) { } else if (const TCastToConstPtr weap = ent) { if (weap->GetActive()) { if (False(weap->GetAttribField() & EProjectileAttrib::KeepInCinematic)) { - if (TCastToConstPtr(mgr.GetObjectById(weap->GetOwnerId())) || + if (TCastToConstPtr(mgr.GetObjectById(weap->GetOwnerId())) || TCastToConstPtr(mgr.GetObjectById(weap->GetOwnerId()))) mgr.FreeScriptObject(weap->GetUniqueId()); } @@ -475,7 +475,7 @@ void CCameraManager::UpdateCameraHints(float, CStateManager& mgr) { } void CCameraManager::ThinkCameras(float dt, CStateManager& mgr) { - CGameCameraList gcList = mgr.GetCameraObjectList(); + CGameCameraList& gcList = mgr.GetCameraObjectList(); for (CEntity* ent : gcList) { if (const TCastToPtr gc = ent) { diff --git a/Runtime/Camera/CCameraShakeData.cpp b/Runtime/Camera/CCameraShakeData.cpp index 28a25d3ed..8d97d0dea 100644 --- a/Runtime/Camera/CCameraShakeData.cpp +++ b/Runtime/Camera/CCameraShakeData.cpp @@ -13,10 +13,10 @@ namespace metaforce { SCameraShakePoint SCameraShakePoint::LoadCameraShakePoint(CInputStream& in) { u32 useEnvelope = ScriptLoader::LoadParameterFlags(in); - float attackTime = in.readFloatBig(); - float sustainTime = in.readFloatBig(); - float duration = in.readFloatBig(); - float magnitude = in.readFloatBig(); + float attackTime = in.ReadFloat(); + float sustainTime = in.ReadFloat(); + float duration = in.ReadFloat(); + float magnitude = in.ReadFloat(); return {useEnvelope != 0, attackTime, sustainTime, duration, magnitude}; } @@ -28,15 +28,15 @@ CCameraShakerComponent CCameraShakerComponent::LoadNewCameraShakerComponent(CInp } CCameraShakeData::CCameraShakeData(CInputStream& in) { - in.readUint32Big(); - in.readFloatBig(); - in.readFloatBig(); - in.readFloatBig(); - in.readFloatBig(); - in.readFloatBig(); - in.readFloatBig(); - in.readFloatBig(); - in.readBool(); + in.ReadLong(); + in.ReadFloat(); + in.ReadFloat(); + in.ReadFloat(); + in.ReadFloat(); + in.ReadFloat(); + in.ReadFloat(); + in.ReadFloat(); + in.ReadBool(); BuildProjectileCameraShake(0.5f, 0.75f); } @@ -100,13 +100,13 @@ float CCameraShakeData::GetMaxFMComponent() const { } CCameraShakeData CCameraShakeData::LoadCameraShakeData(CInputStream& in) { - const float xMag = in.readFloatBig(); - in.readFloatBig(); - const float yMag = in.readFloatBig(); - in.readFloatBig(); - const float zMag = in.readFloatBig(); - in.readFloatBig(); - const float duration = in.readFloatBig(); + const float xMag = in.ReadFloat(); + in.ReadFloat(); + const float yMag = in.ReadFloat(); + in.ReadFloat(); + const float zMag = in.ReadFloat(); + in.ReadFloat(); + const float duration = in.ReadFloat(); const SCameraShakePoint xAM(false, 0.f, 0.f, duration, 2.f * xMag); const SCameraShakePoint yAM(false, 0.f, 0.f, duration, 2.f * yMag); diff --git a/Runtime/Camera/CFirstPersonCamera.cpp b/Runtime/Camera/CFirstPersonCamera.cpp index 70eec0884..2c3e26dbf 100644 --- a/Runtime/Camera/CFirstPersonCamera.cpp +++ b/Runtime/Camera/CFirstPersonCamera.cpp @@ -16,7 +16,7 @@ CFirstPersonCamera::CFirstPersonCamera(TUniqueId uid, const zeus::CTransform& xf nearz, farz, aspect, watchedObj, false, 0) , x188_orbitCameraSpeed(orbitCameraSpeed) , x190_gunFollowXf(xf) { - DataSpec::DNAMP1::tw_FieldOfView->addListener([this](hecl::CVar* cv) { _fovListener(cv); }); + MP1::tw_FieldOfView->addListener([this](CVar* cv) { _fovListener(cv); }); } void CFirstPersonCamera::Accept(IVisitor& visitor) { visitor.Visit(this); } @@ -328,7 +328,7 @@ void CFirstPersonCamera::UpdateElevation(CStateManager& mgr) { } } -void CFirstPersonCamera::_fovListener(hecl::CVar* cv) { +void CFirstPersonCamera::_fovListener(CVar* cv) { x15c_currentFov = x180_perspInterpStartFov = x184_perspInterpEndFov = cv->toReal(); x170_24_perspDirty = true; } diff --git a/Runtime/Camera/CFirstPersonCamera.hpp b/Runtime/Camera/CFirstPersonCamera.hpp index 4493ff24e..3d0910953 100644 --- a/Runtime/Camera/CFirstPersonCamera.hpp +++ b/Runtime/Camera/CFirstPersonCamera.hpp @@ -17,7 +17,7 @@ class CFirstPersonCamera : public CGameCamera { bool x1c6_24_deferBallTransitionProcessing : 1 = false; zeus::CVector3f x1c8_closeInVec; float x1d4_closeInTimer = 0.f; - void _fovListener(hecl::CVar* cv); + void _fovListener(CVar* cv); public: DEFINE_ENTITY diff --git a/Runtime/Camera/CGameCamera.cpp b/Runtime/Camera/CGameCamera.cpp index d86d7c825..41aa31591 100644 --- a/Runtime/Camera/CGameCamera.cpp +++ b/Runtime/Camera/CGameCamera.cpp @@ -44,9 +44,8 @@ void CGameCamera::SetActive(bool active) { zeus::CMatrix4f CGameCamera::GetPerspectiveMatrix() const { if (x170_24_perspDirty) { - const_cast(this)->xec_perspectiveMatrix = - CGraphics::CalculatePerspectiveMatrix(x15c_currentFov, x168_aspect, x160_znear, x164_zfar, false); - const_cast(this)->x170_24_perspDirty = false; + xec_perspectiveMatrix = CGraphics::CalculatePerspectiveMatrix(x15c_currentFov, x168_aspect, x160_znear, x164_zfar); + x170_24_perspDirty = false; } return xec_perspectiveMatrix; diff --git a/Runtime/Camera/CGameCamera.hpp b/Runtime/Camera/CGameCamera.hpp index 0950cc897..db98ff966 100644 --- a/Runtime/Camera/CGameCamera.hpp +++ b/Runtime/Camera/CGameCamera.hpp @@ -15,14 +15,14 @@ class CGameCamera : public CActor { protected: TUniqueId xe8_watchedObject; - zeus::CMatrix4f xec_perspectiveMatrix; + mutable zeus::CMatrix4f xec_perspectiveMatrix; zeus::CTransform x12c_origXf; float x15c_currentFov; float x160_znear; float x164_zfar; float x168_aspect; u32 x16c_controllerIdx; - bool x170_24_perspDirty : 1 = true; + mutable bool x170_24_perspDirty : 1 = true; bool x170_25_disablesInput : 1; float x174_delayTime = 0.f; float x178_perspInterpRemTime = 0.f; diff --git a/Runtime/Character/CActorLights.cpp b/Runtime/Character/CActorLights.cpp index 815b3c8c5..f44ab053d 100644 --- a/Runtime/Character/CActorLights.cpp +++ b/Runtime/Character/CActorLights.cpp @@ -4,7 +4,7 @@ #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Camera/CFirstPersonCamera.hpp" #include "Runtime/Collision/CGameCollision.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CModel.hpp" #include "Runtime/World/CExplosion.hpp" #include "Runtime/World/CGameArea.hpp" @@ -135,7 +135,7 @@ void CActorLights::AddOverflowToLights(const CLight& light, const zeus::CColor& } void CActorLights::MoveAmbienceToLights(const zeus::CColor& color) { - if (x298_29_ambienceGenerated) { + if (x298_29_ambienceGenerated || x0_areaLights.empty()) { x288_ambientColor += color * 0.333333f; x288_ambientColor.a() = 1.f; return; @@ -187,6 +187,7 @@ bool CActorLights::BuildAreaLightList(const CStateManager& mgr, const CGameArea& /* Early return if not ready for update */ if (mgr.GetInputFrameIdx() - x2a4_lastUpdateFrame < x2a8_areaUpdateFramePeriod) return false; + x2a4_lastUpdateFrame = mgr.GetInputFrameIdx(); vec = aabb.center() + x2ac_actorPosBias; if (x2d4_worldLightingLevel == worldLightingLevel) if ((x2c0_lastActorPos - vec).magSquared() < x2cc_actorPositionDeltaUpdateThreshold) @@ -243,19 +244,13 @@ bool CActorLights::BuildAreaLightList(const CStateManager& mgr, const CGameArea& x288_ambientColor = light.GetNormalIndependentLightingAtPoint(vec); } else { EPVSVisSetState visible = EPVSVisSetState::OutOfBounds; - if (area.GetAreaVisSet()) { - if (lightIt->DoesCastShadows()) { - u32 pvsIdx; - if (use2ndLayer) - pvsIdx = area.Get2ndPVSLightFeature(lightIdx); - else - pvsIdx = area.Get1stPVSLightFeature(lightIdx); - visible = sets[0].GetVisible(pvsIdx); - if (visible != EPVSVisSetState::OutOfBounds) - visible = std::max(visible, sets[1].GetVisible(pvsIdx)); - if (visible != EPVSVisSetState::OutOfBounds) - visible = std::max(visible, sets[2].GetVisible(pvsIdx)); - } + if (area.GetAreaVisSet() && lightIt->DoesCastShadows()) { + u32 pvsIdx = use2ndLayer ? area.Get2ndPVSLightFeature(lightIdx) : area.Get1stPVSLightFeature(lightIdx); + visible = sets[0].GetVisible(pvsIdx); + if (visible != EPVSVisSetState::OutOfBounds) + visible = std::max(visible, sets[1].GetVisible(pvsIdx)); + if (visible != EPVSVisSetState::OutOfBounds) + visible = std::max(visible, sets[2].GetVisible(pvsIdx)); } if (visible != EPVSVisSetState::EndOfTree) { zeus::CSphere sphere(light.GetPosition(), light.GetRadius() * 2.f); @@ -435,52 +430,54 @@ void CActorLights::BuildDynamicLightList(const CStateManager& mgr, const zeus::C std::vector CActorLights::BuildLightVector() const { std::vector lights; - if (x0_areaLights.size()) { - if (x2dc_brightLightLag && x299_25_useBrightLightLag) { + if (!x0_areaLights.empty()) { + if (x2dc_brightLightLag != 0 && x299_25_useBrightLightLag) { CLight overrideLight = x0_areaLights[0]; overrideLight.SetColor(overrideLight.GetColor() * (1.f - x2dc_brightLightLag / 15.f)); lights.push_back(overrideLight); - } else + } else { lights.push_back(x0_areaLights[0]); + } for (auto it = x0_areaLights.begin() + 1; it != x0_areaLights.end(); ++it) { lights.push_back(*it); } - - if (x29c_shadowLightArrIdx > 0) { - /* Ensure shadow light comes first for shader extension */ - std::swap(lights[0], lights[x29c_shadowLightArrIdx]); - } } - for (const CLight& light : x144_dynamicLights) + for (const CLight& light : x144_dynamicLights) { lights.push_back(light); - - zeus::CColor ambColor = x288_ambientColor; - ambColor.a() = 1.f; - lights.push_back(CLight::BuildLocalAmbient(zeus::skZero3f, ambColor)); + } return lights; } -void CActorLights::ActivateLights(CBooModel& model) const { - std::vector lights; - +void CActorLights::ActivateLights() const { if (x298_28_inArea) { if (!x298_26_hasAreaLights || x299_26_ambientOnly) { - // g_Renderer->SetAmbientColor(zeus::skWhite); - lights.push_back(CLight::BuildLocalAmbient(zeus::skZero3f, zeus::skWhite)); - model.ActivateLights(lights); + g_Renderer->SetAmbientColor(zeus::skWhite); + CGraphics::DisableAllLights(); return; } } + auto ambient = x288_ambientColor; + ambient.a() = 1.f; + g_Renderer->SetAmbientColor(ambient); - lights = BuildLightVector(); - model.ActivateLights(lights); + const auto lights = BuildLightVector(); + if (lights.empty()) { + CGraphics::DisableAllLights(); + } else { + for (ERglLight idx = 0; const auto& item : lights) { + CGraphics::LoadLight(idx, item); + idx++; + } + // Sets n LSB to 1 + CGraphics::SetLightState(static_cast((1 << lights.size()) + 255)); + } if (x298_31_disableWorldLights) { - zeus::CColor color(x2d4_worldLightingLevel); - g_Renderer->SetGXRegister1Color(color); + g_Renderer->SetAmbientColor(zeus::skBlack); + g_Renderer->SetGXRegister1Color({x2d4_worldLightingLevel}); } } diff --git a/Runtime/Character/CActorLights.hpp b/Runtime/Character/CActorLights.hpp index c1c8de5fc..48fe79a64 100644 --- a/Runtime/Character/CActorLights.hpp +++ b/Runtime/Character/CActorLights.hpp @@ -63,7 +63,7 @@ public: bool BuildAreaLightList(const CStateManager& mgr, const CGameArea& area, const zeus::CAABox& aabb); void BuildDynamicLightList(const CStateManager& mgr, const zeus::CAABox& aabb); std::vector BuildLightVector() const; - void ActivateLights(CBooModel& model) const; + void ActivateLights() const; void SetCastShadows(bool v) { x298_25_castShadows = v; } void SetHasAreaLights(bool v) { x298_26_hasAreaLights = v; } void SetFindShadowLight(bool v) { x298_27_findShadowLight = v; } diff --git a/Runtime/Character/CAdditiveAnimPlayback.hpp b/Runtime/Character/CAdditiveAnimPlayback.hpp index c85ac976d..27fb1ae68 100644 --- a/Runtime/Character/CAdditiveAnimPlayback.hpp +++ b/Runtime/Character/CAdditiveAnimPlayback.hpp @@ -2,6 +2,7 @@ #include #include "Runtime/RetroTypes.hpp" +#include "Runtime/Streams/CInputStream.hpp" namespace metaforce { class CAdditiveAnimationInfo; @@ -16,8 +17,8 @@ class CAdditiveAnimationInfo { public: void read(CInputStream& in) { - x0_fadeInDur = in.readFloatBig(); - x4_fadeOutDur = in.readFloatBig(); + x0_fadeInDur = in.ReadFloat(); + x4_fadeOutDur = in.ReadFloat(); } CAdditiveAnimationInfo() = default; explicit CAdditiveAnimationInfo(CInputStream& in) { read(in); } diff --git a/Runtime/Character/CAdditiveBodyState.cpp b/Runtime/Character/CAdditiveBodyState.cpp index fefb2a9b7..8449f9a62 100644 --- a/Runtime/Character/CAdditiveBodyState.cpp +++ b/Runtime/Character/CAdditiveBodyState.cpp @@ -24,8 +24,8 @@ void CABSAim::Start(CBodyController& bc, CStateManager& mgr) { const CAnimData& animData = *bc.GetOwner().GetModelData()->GetAnimationData(); x28_hWeight = -animData.GetAdditiveAnimationWeight(x8_anims[0]); x28_hWeight += animData.GetAdditiveAnimationWeight(x8_anims[1]); - x30_vWeight = -animData.GetAdditiveAnimationWeight(x8_anims[2]); - x30_vWeight += animData.GetAdditiveAnimationWeight(x8_anims[3]); + x30_vWeight = -animData.GetAdditiveAnimationWeight(x8_anims[3]); + x30_vWeight += animData.GetAdditiveAnimationWeight(x8_anims[2]); x4_needsIdle = false; if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::AdditiveIdle)) diff --git a/Runtime/Character/CAllFormatsAnimSource.cpp b/Runtime/Character/CAllFormatsAnimSource.cpp index 7e852ede9..e3c01f9cc 100644 --- a/Runtime/Character/CAllFormatsAnimSource.cpp +++ b/Runtime/Character/CAllFormatsAnimSource.cpp @@ -26,7 +26,7 @@ void CAnimFormatUnion::SubConstruct(u8* storage, EAnimFormat fmt, CInputStream& } CAnimFormatUnion::CAnimFormatUnion(CInputStream& in, IObjectStore& store) { - x0_format = EAnimFormat(in.readUint32Big()); + x0_format = EAnimFormat(in.ReadLong()); SubConstruct(x4_storage, x0_format, in, store); } diff --git a/Runtime/Character/CAnimCharacterSet.cpp b/Runtime/Character/CAnimCharacterSet.cpp index a85150f8f..bced78e93 100644 --- a/Runtime/Character/CAnimCharacterSet.cpp +++ b/Runtime/Character/CAnimCharacterSet.cpp @@ -5,7 +5,7 @@ namespace metaforce { CAnimCharacterSet::CAnimCharacterSet(CInputStream& in) -: x0_version(in.readUint16Big()), x4_characterSet(in), x1c_animationSet(in) {} +: x0_version(in.ReadShort()), x4_characterSet(in), x1c_animationSet(in) {} CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream& in, const CVParamTransfer&, CObjectReference* selfRef) { diff --git a/Runtime/Character/CAnimData.cpp b/Runtime/Character/CAnimData.cpp index c7d6a01b5..720645f39 100644 --- a/Runtime/Character/CAnimData.cpp +++ b/Runtime/Character/CAnimData.cpp @@ -23,6 +23,7 @@ #include "Runtime/Character/CTransitionManager.hpp" #include "Runtime/Character/IAnimReader.hpp" #include "Runtime/Graphics/CSkinnedModel.hpp" +#include "Runtime/Graphics/CGX.hpp" #include @@ -41,23 +42,22 @@ void CAnimData::InitializeCache() {} CAnimData::CAnimData(CAssetId id, const CCharacterInfo& character, int defaultAnim, int charIdx, bool loop, TLockedToken layout, TToken model, - const std::optional>& iceModel, + const std::optional>& iceModel, const std::weak_ptr& ctx, std::shared_ptr animMgr, - std::shared_ptr transMgr, TLockedToken charFactory, - int drawInstCount) + std::shared_ptr transMgr, TLockedToken charFactory) : x0_charFactory(charFactory) , xc_charInfo(character) , xcc_layoutData(layout) , xd8_modelData(std::move(model)) , xfc_animCtx(ctx.lock()) , x100_animMgr(std::move(animMgr)) +, x108_aabb() , x1d8_selfId(id) , x1fc_transMgr(std::move(transMgr)) , x204_charIdx(charIdx) , x208_defaultAnim(defaultAnim) , x224_pose(layout->GetSegIdList().GetList().size()) -, x2fc_poseBuilder(CLayoutDescription{layout}) -, m_drawInstCount(drawInstCount) { +, x2fc_poseBuilder(CLayoutDescription{layout}) { x220_25_loop = loop; if (iceModel) @@ -69,7 +69,10 @@ CAnimData::CAnimData(CAssetId id, const CCharacterInfo& character, int defaultAn g_SoundPOINodes.resize(20); g_TransientInt32POINodes.resize(16); - x108_aabb = xd8_modelData->GetModel()->GetAABB(); + xd8_modelData->CalculateDefault(); + for (const auto& item : *xd8_modelData->GetModel()->GetPositions()) { + x108_aabb.accumulateBounds(item); + } x120_particleDB.CacheParticleDesc(xc_charInfo.GetParticleResData()); CHierarchyPoseBuilder pb(CLayoutDescription{xcc_layoutData}); @@ -260,7 +263,7 @@ std::shared_ptr CAnimData::GetAnimationManager() { return x10 void CAnimData::SetPhase(float ph) { x1f8_animRoot->VSetPhase(ph); } -void CAnimData::Touch(const CSkinnedModel& model, int shadIdx) const { model.GetModelInst()->Touch(shadIdx); } +void CAnimData::Touch(CSkinnedModel& model, int shadIdx) const { model.GetModel()->Touch(shadIdx); } SAdvancementDeltas CAnimData::GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const { return x1f8_animRoot->VGetAdvancementResults(a, b).x8_deltas; @@ -457,7 +460,7 @@ zeus::CTransform CAnimData::GetLocatorTransform(CSegId id, const CCharAnimTime* if (!x220_30_poseBuilt) { x2fc_poseBuilder.BuildTransform(id, ret); } else { - ret.setRotation(x224_pose.GetTransformMinusOffset(id)); + ret.setRotation(x224_pose.GetRotation(id)); ret.origin = x224_pose.GetOffset(id); } return ret; @@ -485,7 +488,7 @@ float CAnimData::GetAnimationDuration(int animIn) const { std::set prims; anim->GetUniquePrimitives(prims); - SObjectTag tag{FOURCC('ANIM'), 0}; + SObjectTag tag{FOURCC('ANIM'), {}}; float durAccum = 0.f; for (const CPrimitive& prim : prims) { tag.id = prim.GetAnimResId(); @@ -545,23 +548,25 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time) { void CAnimData::RenderAuxiliary(const zeus::CFrustum& frustum) const { x120_particleDB.AddToRendererClipped(frustum); } -void CAnimData::Render(CSkinnedModel& model, const CModelFlags& drawFlags, - const std::optional& morphEffect, const float* morphMagnitudes) { - SetupRender(model, drawFlags, morphEffect, morphMagnitudes); +void CAnimData::Render(CSkinnedModel& model, const CModelFlags& drawFlags, CVertexMorphEffect* morphEffect, + TConstVectorRef averagedNormals) { + SetupRender(model, morphEffect, averagedNormals); DrawSkinnedModel(model, drawFlags); } -void CAnimData::SetupRender(CSkinnedModel& model, const CModelFlags& drawFlags, - const std::optional& morphEffect, const float* morphMagnitudes) { +void CAnimData::SetupRender(CSkinnedModel& model, CVertexMorphEffect* morphEffect, TConstVectorRef averagedNormals) { OPTICK_EVENT(); if (!x220_30_poseBuilt) { x2fc_poseBuilder.BuildNoScale(x224_pose); x220_30_poseBuilt = true; } - PoseSkinnedModel(model, x224_pose, drawFlags, morphEffect, morphMagnitudes); + PoseSkinnedModel(model, x224_pose, morphEffect, averagedNormals); } -void CAnimData::DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags) { model.Draw(flags); } +void CAnimData::DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags) { + CGX::SetChanCtrl(CGX::EChannelId::Channel0, CGraphics::g_LightActive); + model.Draw(flags); +} void CAnimData::PreRender() { if (!x220_31_poseCached) { @@ -588,7 +593,7 @@ void CAnimData::PrimitiveSetToTokenVector(const std::set& primSet, s bool preLock) { tokensOut.reserve(primSet.size()); - SObjectTag tag{FOURCC('ANIM'), 0}; + SObjectTag tag{FOURCC('ANIM'), {}}; for (const CPrimitive& prim : primSet) { tag.id = prim.GetAnimResId(); tokensOut.push_back(g_SimplePool->GetObj(tag)); @@ -797,17 +802,18 @@ void CAnimData::AdvanceAnim(CCharAnimTime& time, zeus::CVector3f& offset, zeus:: } void CAnimData::SetXRayModel(const TLockedToken& model, const TLockedToken& skinRules) { - xf4_xrayModel = std::make_shared(model, skinRules, xd8_modelData->GetLayoutInfo(), 0, m_drawInstCount); + xf4_xrayModel = std::make_shared(model, skinRules, xd8_modelData->GetLayoutInfo()); + xf4_xrayModel->CalculateDefault(); } void CAnimData::SetInfraModel(const TLockedToken& model, const TLockedToken& skinRules) { - xf8_infraModel = - std::make_shared(model, skinRules, xd8_modelData->GetLayoutInfo(), 0, m_drawInstCount); + xf8_infraModel = std::make_shared(model, skinRules, xd8_modelData->GetLayoutInfo()); + xf4_xrayModel->CalculateDefault(); } -void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, const CModelFlags& drawFlags, - const std::optional& morphEffect, const float* morphMagnitudes) { - model.Calculate(pose, drawFlags, morphEffect, morphMagnitudes); +void CAnimData::PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, CVertexMorphEffect* morphEffect, + TConstVectorRef averagedNormals) { + model.Calculate(pose, morphEffect, averagedNormals, nullptr); } void CAnimData::AdvanceParticles(const zeus::CTransform& xf, float dt, const zeus::CVector3f& vec, @@ -820,7 +826,7 @@ float CAnimData::GetAverageVelocity(int animIn) const { std::set prims; anim->GetUniquePrimitives(prims); - SObjectTag tag{FOURCC('ANIM'), 0}; + SObjectTag tag{FOURCC('ANIM'), {}}; float velAccum = 0.f; float durAccum = 0.f; for (const CPrimitive& prim : prims) { @@ -885,7 +891,10 @@ zeus::CAABox CAnimData::GetBoundingBox() const { void CAnimData::SubstituteModelData(const TCachedToken& model) { xd8_modelData = model; - x108_aabb = xd8_modelData->GetModel()->GetAABB(); + x108_aabb = {}; + for (const auto& item : *xd8_modelData->GetModel()->GetPositions()) { + x108_aabb.accumulateBounds(item); + } } void CAnimData::SetParticleCEXTValue(std::string_view name, int idx, float value) { diff --git a/Runtime/Character/CAnimData.hpp b/Runtime/Character/CAnimData.hpp index 0e7bb21ac..9485adfd3 100644 --- a/Runtime/Character/CAnimData.hpp +++ b/Runtime/Character/CAnimData.hpp @@ -68,7 +68,7 @@ class CCharAnimTime; class CCharLayoutInfo; class CInt32POINode; class CModel; -class CMorphableSkinnedModel; +class CSkinnedModelWithAvgNormals; class CParticlePOINode; class CPrimitive; class CRandom16; @@ -102,7 +102,7 @@ private: CCharacterInfo xc_charInfo; TLockedToken xcc_layoutData; TLockedToken xd8_modelData; - TLockedToken xe4_iceModelData; + TLockedToken xe4_iceModelData; std::shared_ptr xf4_xrayModel; std::shared_ptr xf8_infraModel; std::shared_ptr xfc_animCtx; @@ -144,14 +144,12 @@ private: static rstl::reserved_vector g_SoundPOINodes; static rstl::reserved_vector g_TransientInt32POINodes; - int m_drawInstCount; - public: CAnimData(CAssetId, const CCharacterInfo& character, int defaultAnim, int charIdx, bool loop, TLockedToken layout, TToken model, - const std::optional>& iceModel, const std::weak_ptr& ctx, - std::shared_ptr animMgr, std::shared_ptr transMgr, - TLockedToken charFactory, int drawInstCount); + const std::optional>& iceModel, + const std::weak_ptr& ctx, std::shared_ptr animMgr, + std::shared_ptr transMgr, TLockedToken charFactory); void SetParticleEffectState(std::string_view effectName, bool active, CStateManager& mgr); void InitializeEffects(CStateManager& mgr, TAreaId aId, const zeus::CVector3f& scale); @@ -172,7 +170,7 @@ public: const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; } const CCharLayoutInfo& GetCharLayoutInfo() const { return *xcc_layoutData.GetObj(); } void SetPhase(float ph); - void Touch(const CSkinnedModel& model, int shaderIdx) const; + void Touch(CSkinnedModel& model, int shaderIdx) const; SAdvancementDeltas GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const; CCharAnimTime GetTimeOfUserEvent(EUserEventType type, const CCharAnimTime& time) const; void MultiplyPlaybackRate(float mul); @@ -196,10 +194,9 @@ public: std::shared_ptr GetAnimationManager() const; void RecalcPoseBuilder(const CCharAnimTime* time); void RenderAuxiliary(const zeus::CFrustum& frustum) const; - void Render(CSkinnedModel& model, const CModelFlags& drawFlags, const std::optional& morphEffect, - const float* morphMagnitudes); - void SetupRender(CSkinnedModel& model, const CModelFlags& drawFlags, - const std::optional& morphEffect, const float* morphMagnitudes); + void Render(CSkinnedModel& model, const CModelFlags& drawFlags, CVertexMorphEffect* morphEffect, + TConstVectorRef averagedNormals); + void SetupRender(CSkinnedModel& model, CVertexMorphEffect* morphEffect, TConstVectorRef averagedNormals); static void DrawSkinnedModel(CSkinnedModel& model, const CModelFlags& flags); void PreRender(); void BuildPose(); @@ -220,8 +217,8 @@ public: TLockedToken& GetModelData() { return xd8_modelData; } const TLockedToken& GetModelData() const { return xd8_modelData; } - static void PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, const CModelFlags& drawFlags, - const std::optional& morphEffect, const float* morphMagnitudes); + static void PoseSkinnedModel(CSkinnedModel& model, const CPoseAsTransforms& pose, CVertexMorphEffect* morphEffect, + TConstVectorRef averagedNormals); void AdvanceParticles(const zeus::CTransform& xf, float dt, const zeus::CVector3f&, CStateManager& stateMgr); float GetAverageVelocity(int animIn) const; void ResetPOILists(); @@ -245,8 +242,8 @@ public: s32 GetCharacterIndex() const { return x204_charIdx; } u16 GetDefaultAnimation() const { return x208_defaultAnim; } - TLockedToken& GetIceModel() { return xe4_iceModelData; } - const TLockedToken& GetIceModel() const { return xe4_iceModelData; } + TLockedToken& GetIceModel() { return xe4_iceModelData; } + const TLockedToken& GetIceModel() const { return xe4_iceModelData; } void SetParticleLightIdx(s32 idx) { x21c_particleLightIdx = idx; } void MarkPoseDirty() { x220_30_poseBuilt = false; } diff --git a/Runtime/Character/CAnimPOIData.cpp b/Runtime/Character/CAnimPOIData.cpp index 0f9328307..600044fba 100644 --- a/Runtime/Character/CAnimPOIData.cpp +++ b/Runtime/Character/CAnimPOIData.cpp @@ -4,24 +4,24 @@ namespace metaforce { -CAnimPOIData::CAnimPOIData(CInputStream& in) : x0_version(in.readUint32Big()) { - u32 boolCount = in.readUint32Big(); +CAnimPOIData::CAnimPOIData(CInputStream& in) : x0_version(in.ReadLong()) { + u32 boolCount = in.ReadLong(); x4_boolNodes.reserve(boolCount); for (u32 i = 0; i < boolCount; ++i) x4_boolNodes.emplace_back(in); - u32 int32Count = in.readUint32Big(); + u32 int32Count = in.ReadLong(); x14_int32Nodes.reserve(int32Count); for (u32 i = 0; i < int32Count; ++i) x14_int32Nodes.emplace_back(in); - u32 particleCount = in.readUint32Big(); + u32 particleCount = in.ReadLong(); x24_particleNodes.reserve(particleCount); for (u32 i = 0; i < particleCount; ++i) x24_particleNodes.emplace_back(in); if (x0_version >= 2) { - u32 soundCount = in.readUint32Big(); + u32 soundCount = in.ReadLong(); x34_soundNodes.reserve(soundCount); for (u32 i = 0; i < soundCount; ++i) x34_soundNodes.emplace_back(in); diff --git a/Runtime/Character/CAnimSource.cpp b/Runtime/Character/CAnimSource.cpp index 7ab35115e..b3bef0e07 100644 --- a/Runtime/Character/CAnimSource.cpp +++ b/Runtime/Character/CAnimSource.cpp @@ -45,22 +45,22 @@ std::unique_ptr RotationAndOffsetStorage::GetRotationsAndOffsets(const const std::vector& offs, u32 frameCount) { u32 size = DataSizeInBytes(rots.size() / frameCount, offs.size() / frameCount, frameCount); - std::unique_ptr ret(new float[(size / 4 + 1) * 4]); + auto ret = std::make_unique((size / 4 + 1) * 4); CopyRotationsAndOffsets(rots, offs, frameCount, ret.get()); return ret; } RotationAndOffsetStorage::CRotationAndOffsetVectors::CRotationAndOffsetVectors(CInputStream& in) { - const u32 quatCount = in.readUint32Big(); + const u32 quatCount = in.ReadLong(); x0_rotations.reserve(quatCount); for (u32 i = 0; i < quatCount; ++i) { - x0_rotations.emplace_back().readBig(in); + x0_rotations.emplace_back() = in.Get(); } - const u32 vecCount = in.readUint32Big(); + const u32 vecCount = in.ReadLong(); x10_offsets.reserve(vecCount); for (u32 i = 0; i < vecCount; ++i) { - x10_offsets.emplace_back().readBig(in); + x10_offsets.emplace_back() = in.Get(); } } @@ -75,10 +75,10 @@ RotationAndOffsetStorage::RotationAndOffsetStorage(const CRotationAndOffsetVecto static std::vector ReadIndexTable(CInputStream& in) { std::vector ret; - u32 count = in.readUint32Big(); + u32 count = in.ReadLong(); ret.reserve(count); for (u32 i = 0; i < count; ++i) - ret.push_back(in.readUByte()); + ret.push_back(in.ReadUint8()); return ret; } @@ -103,12 +103,12 @@ void CAnimSource::CalcAverageVelocity() { CAnimSource::CAnimSource(CInputStream& in, IObjectStore& store) : x0_duration(in) , x8_interval(in) -, x10_frameCount(in.readUint32Big()) +, x10_frameCount(in.ReadLong()) , x1c_rootBone(in) , x20_rotationChannels(ReadIndexTable(in)) , x30_translationChannels(ReadIndexTable(in)) , x40_data(RotationAndOffsetStorage::CRotationAndOffsetVectors(in), x10_frameCount) -, x54_evntId(in.readUint32Big()) { +, x54_evntId(in) { if (x54_evntId.IsValid()) { x58_evntData = store.GetObj({SBIG('EVNT'), x54_evntId}); x58_evntData.GetObj(); @@ -118,6 +118,7 @@ CAnimSource::CAnimSource(CInputStream& in, IObjectStore& store) void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& set, const CCharAnimTime& time) const { const auto frameIdx = u32(time / x8_interval); + const auto nextFrameIdx = (frameIdx + 1) % x10_frameCount; float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds(); if (std::fabs(remTime) < 0.00001f) { remTime = 0.f; @@ -131,7 +132,7 @@ void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& s const u8 rotIdx = x20_rotationChannels[id]; if (rotIdx != 0xff) { const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotIdx * 4]; - const float* frameDataB = &x40_data.x0_storage[(frameIdx + 1) * floatsPerFrame + rotIdx * 4]; + const float* frameDataB = &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotIdx * 4]; const zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]); const zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]); @@ -141,7 +142,7 @@ void CAnimSource::GetSegStatementSet(const CSegIdList& list, CSegStatementSet& s if (transIdx != 0xff) { const float* frameVecDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; const float* frameVecDataB = - &x40_data.x0_storage[(frameIdx - 1) * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; + &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; const zeus::CVector3f vecA(frameVecDataA[0], frameVecDataA[1], frameVecDataA[2]); const zeus::CVector3f vecB(frameVecDataB[0], frameVecDataB[1], frameVecDataB[2]); set[id].x10_offset = zeus::CVector3f::lerp(vecA, vecB, t); @@ -164,7 +165,8 @@ const std::vector& CAnimSource::GetBoolPOIStream() const { return zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTime& time) const { u8 rotIdx = x20_rotationChannels[seg]; if (rotIdx != 0xff) { - u32 frameIdx = unsigned(time / x8_interval); + const auto frameIdx = u32(time / x8_interval); + const auto nextFrameIdx = (frameIdx + 1) % x10_frameCount; float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds(); if (std::fabs(remTime) < 0.00001f) remTime = 0.f; @@ -172,7 +174,7 @@ zeus::CQuaternion CAnimSource::GetRotation(const CSegId& seg, const CCharAnimTim const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4; const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotIdx * 4]; - const float* frameDataB = &x40_data.x0_storage[(frameIdx + 1) * floatsPerFrame + rotIdx * 4]; + const float* frameDataB = &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotIdx * 4]; zeus::CQuaternion quatA(frameDataA[0], frameDataA[1], frameDataA[2], frameDataA[3]); zeus::CQuaternion quatB(frameDataB[0], frameDataB[1], frameDataB[2], frameDataB[3]); @@ -189,7 +191,8 @@ zeus::CVector3f CAnimSource::GetOffset(const CSegId& seg, const CCharAnimTime& t if (transIdx == 0xff) return {}; - u32 frameIdx = unsigned(time / x8_interval); + const auto frameIdx = u32(time / x8_interval); + const auto nextFrameIdx = (frameIdx + 1) % x10_frameCount; float remTime = time.GetSeconds() - frameIdx * x8_interval.GetSeconds(); if (std::fabs(remTime) < 0.00001f) remTime = 0.f; @@ -198,7 +201,7 @@ zeus::CVector3f CAnimSource::GetOffset(const CSegId& seg, const CCharAnimTime& t const u32 floatsPerFrame = x40_data.x10_transPerFrame * 3 + x40_data.xc_rotPerFrame * 4; const u32 rotFloatsPerFrame = x40_data.xc_rotPerFrame * 4; const float* frameDataA = &x40_data.x0_storage[frameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; - const float* frameDataB = &x40_data.x0_storage[(frameIdx - 1) * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; + const float* frameDataB = &x40_data.x0_storage[nextFrameIdx * floatsPerFrame + rotFloatsPerFrame + transIdx * 3]; zeus::CVector3f vecA(frameDataA[0], frameDataA[1], frameDataA[2]); zeus::CVector3f vecB(frameDataB[0], frameDataB[1], frameDataB[2]); return zeus::CVector3f::lerp(vecA, vecB, t); diff --git a/Runtime/Character/CAnimSourceReader.cpp b/Runtime/Character/CAnimSourceReader.cpp index fd27d6686..1dcc58848 100644 --- a/Runtime/Character/CAnimSourceReader.cpp +++ b/Runtime/Character/CAnimSourceReader.cpp @@ -250,7 +250,7 @@ SAdvancementResults CAnimSourceReader::VGetAdvancementResults(const CCharAnimTim if (x54_source->HasOffset(3)) { zeus::CVector3f ta = x54_source->GetOffset(3, prevTime); zeus::CVector3f tb = x54_source->GetOffset(3, accum); - ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb) * (tb - ta); + ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb.inverse()) * (tb - ta); } return ret; @@ -274,6 +274,7 @@ SAdvancementResults CAnimSourceReader::VReverseView(const CCharAnimTime& dt) { SAdvancementResults ret; if (xc_curTime.EqualsZero()) { + xc_curTime = x54_source->GetDuration(); ret.x0_remTime = dt; return ret; } else if (dt.EqualsZero()) { @@ -298,7 +299,7 @@ SAdvancementResults CAnimSourceReader::VReverseView(const CCharAnimTime& dt) { if (x54_source->HasOffset(3)) { zeus::CVector3f ta = x54_source->GetOffset(3, prevTime); zeus::CVector3f tb = x54_source->GetOffset(3, xc_curTime); - ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb) * (tb - ta); + ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb.inverse()) * (tb - ta); } return ret; @@ -319,7 +320,12 @@ void CAnimSourceReader::VGetSegStatementSet(const CSegIdList& list, CSegStatemen SAdvancementResults CAnimSourceReader::VAdvanceView(const CCharAnimTime& dt) { SAdvancementResults ret; - if (xc_curTime >= x54_source->GetDuration()) { + if (xc_curTime == x54_source->GetDuration()) { + xc_curTime = {}; + x14_passedBoolCount = 0; + x18_passedIntCount = 0; + x1c_passedParticleCount = 0; + x20_passedSoundCount = 0; ret.x0_remTime = dt; return ret; } else if (dt.EqualsZero()) { @@ -344,7 +350,7 @@ SAdvancementResults CAnimSourceReader::VAdvanceView(const CCharAnimTime& dt) { if (x54_source->HasOffset(3)) { zeus::CVector3f ta = x54_source->GetOffset(3, prevTime); zeus::CVector3f tb = x54_source->GetOffset(3, xc_curTime); - ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb) * (tb - ta); + ret.x8_deltas.x0_posDelta = zeus::CMatrix3f(rb.inverse()) * (tb - ta); } return ret; diff --git a/Runtime/Character/CAnimation.cpp b/Runtime/Character/CAnimation.cpp index d7de743bb..eb216e020 100644 --- a/Runtime/Character/CAnimation.cpp +++ b/Runtime/Character/CAnimation.cpp @@ -5,7 +5,7 @@ namespace metaforce { CAnimation::CAnimation(CInputStream& in) { - x0_name = in.readString(); + x0_name = in.Get(); x10_anim = CMetaAnimFactory::CreateMetaAnim(in); } diff --git a/Runtime/Character/CAnimation.hpp b/Runtime/Character/CAnimation.hpp index 696d7e1cb..1c04f40e6 100644 --- a/Runtime/Character/CAnimation.hpp +++ b/Runtime/Character/CAnimation.hpp @@ -3,7 +3,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CMetaAnimFactory.hpp" namespace metaforce { diff --git a/Runtime/Character/CAnimationSet.cpp b/Runtime/Character/CAnimationSet.cpp index 690b1a3c7..135658004 100644 --- a/Runtime/Character/CAnimationSet.cpp +++ b/Runtime/Character/CAnimationSet.cpp @@ -4,13 +4,13 @@ namespace metaforce { -CAnimationSet::CAnimationSet(CInputStream& in) : x0_tableCount(in.readUint16Big()) { - u32 animationCount = in.readUint32Big(); +CAnimationSet::CAnimationSet(CInputStream& in) : x0_tableCount(in.ReadShort()) { + u32 animationCount = in.ReadLong(); x4_animations.reserve(animationCount); for (u32 i = 0; i < animationCount; ++i) x4_animations.emplace_back(in); - u32 transitionCount = in.readUint32Big(); + u32 transitionCount = in.ReadLong(); x14_transitions.reserve(transitionCount); for (u32 i = 0; i < transitionCount; ++i) x14_transitions.emplace_back(in); @@ -18,28 +18,28 @@ CAnimationSet::CAnimationSet(CInputStream& in) : x0_tableCount(in.readUint16Big( x24_defaultTransition = CMetaTransFactory::CreateMetaTrans(in); if (x0_tableCount > 1) { - u32 additiveAnimCount = in.readUint32Big(); + u32 additiveAnimCount = in.ReadLong(); x28_additiveInfo.reserve(additiveAnimCount); for (u32 i = 0; i < additiveAnimCount; ++i) { - u32 id = in.readUint32Big(); + u32 id = in.ReadLong(); x28_additiveInfo.emplace_back(id, in); } x38_defaultAdditiveInfo.read(in); } if (x0_tableCount > 2) { - u32 halfTransitionCount = in.readUint32Big(); + u32 halfTransitionCount = in.ReadLong(); x40_halfTransitions.reserve(halfTransitionCount); for (u32 i = 0; i < halfTransitionCount; ++i) x40_halfTransitions.emplace_back(in); } if (x0_tableCount > 3) { - u32 animResourcesCount = in.readUint32Big(); + u32 animResourcesCount = in.ReadLong(); x50_animRes.reserve(animResourcesCount); for (u32 i = 0; i < animResourcesCount; ++i) { - CAssetId anim = in.readUint32Big(); - CAssetId evnt = in.readUint32Big(); + CAssetId anim = in.Get(); + CAssetId evnt = in.Get(); x50_animRes.emplace_back(anim, evnt); } } diff --git a/Runtime/Character/CAnimationSet.hpp b/Runtime/Character/CAnimationSet.hpp index 18cdd5e0a..10688dcc0 100644 --- a/Runtime/Character/CAnimationSet.hpp +++ b/Runtime/Character/CAnimationSet.hpp @@ -4,7 +4,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/Character/CAdditiveAnimPlayback.hpp" #include "Runtime/Character/CAnimation.hpp" diff --git a/Runtime/Character/CBodyState.cpp b/Runtime/Character/CBodyState.cpp index 47c769c7c..83850dc13 100644 --- a/Runtime/Character/CBodyState.cpp +++ b/Runtime/Character/CBodyState.cpp @@ -209,7 +209,7 @@ pas::EAnimationState CBSDie::UpdateBody(float dt, CBodyController& bc, CStateMan void CBSFall::Start(CBodyController& bc, CStateManager& mgr) { const auto* cmd = static_cast(bc.GetCommandMgr().GetCmd(EBodyStateCmd::KnockDown)); zeus::CVector3f localDir = bc.GetOwner().GetTransform().transposeRotate(cmd->GetHitDirection()); - zeus::CRelAngle angle = std::atan2(localDir.y(), localDir.z()); + zeus::CRelAngle angle = std::atan2(localDir.y(), localDir.x()); angle.makeRel(); const CPASAnimParmData parms(pas::EAnimationState::Fall, CPASAnimParm::FromReal32(angle.asDegrees()), CPASAnimParm::FromEnum(s32(cmd->GetHitSeverity()))); @@ -586,6 +586,7 @@ void CBSLoopAttack::Start(CBodyController& bc, CStateManager& mgr) { xc_25_advance = false; if (bc.GetLocomotionType() == pas::ELocomotionType::Crouch) { + x4_state = pas::ELoopState::Loop; const CPASAnimParmData parms(pas::EAnimationState::LoopAttack, CPASAnimParm::FromEnum(s32(x4_state)), CPASAnimParm::FromEnum(s32(x8_loopAttackType))); bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); @@ -715,7 +716,8 @@ void CBSLoopReaction::Start(CBodyController& bc, CStateManager& mgr) { x4_state = pas::ELoopState::Loop; const CPASAnimParmData loopParms(pas::EAnimationState::LoopReaction, CPASAnimParm::FromEnum(s32(x8_reactionType)), CPASAnimParm::FromEnum(s32(x4_state))); - bc.LoopBestAnimation(loopParms, *mgr.GetActiveRandom()); + // Intentionally using parms instead of loopParms + bc.LoopBestAnimation(parms, *mgr.GetActiveRandom()); } } @@ -1408,10 +1410,11 @@ pas::EAnimationState CBSScripted::GetBodyStateTransition(float dt, const CBodyCo if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::Scripted)) { return pas::EAnimationState::Scripted; } - if (x4_24_loopAnim && bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) { - return pas::EAnimationState::Locomotion; - } - if (bc.IsAnimationOver()) { + if (x4_24_loopAnim) { + if (bc.GetCommandMgr().GetCmd(EBodyStateCmd::ExitState)) { + return pas::EAnimationState::Locomotion; + } + } else if (bc.IsAnimationOver()) { return pas::EAnimationState::Locomotion; } return pas::EAnimationState::Invalid; @@ -1536,7 +1539,7 @@ pas::EAnimationState CBSWallHang::GetBodyStateTransition(float dt, const CBodyCo } void CBSWallHang::FixInPlace(CBodyController& bc) { - if (const TCastToPtr ai = bc.GetOwner()) { + if (const TCastToPtr ai = bc.GetOwner()) { ai->SetConstantForce(zeus::skZero3f); ai->SetVelocityWR(zeus::skZero3f); } diff --git a/Runtime/Character/CBoolPOINode.cpp b/Runtime/Character/CBoolPOINode.cpp index 50e847dfe..f65ae2f94 100644 --- a/Runtime/Character/CBoolPOINode.cpp +++ b/Runtime/Character/CBoolPOINode.cpp @@ -6,7 +6,7 @@ namespace metaforce { CBoolPOINode::CBoolPOINode() : CPOINode("root", EPOIType::EmptyBool, CCharAnimTime(), -1, false, 1.f, -1, 0) {} -CBoolPOINode::CBoolPOINode(CInputStream& in) : CPOINode(in), x38_val(in.readBool()) {} +CBoolPOINode::CBoolPOINode(CInputStream& in) : CPOINode(in), x38_val(in.ReadBool()) {} CBoolPOINode CBoolPOINode::CopyNodeMinusStartTime(const CBoolPOINode& node, const CCharAnimTime& startTime) { CBoolPOINode ret = node; diff --git a/Runtime/Character/CCharAnimTime.hpp b/Runtime/Character/CCharAnimTime.hpp index e2aa45e3b..e1ec7991f 100644 --- a/Runtime/Character/CCharAnimTime.hpp +++ b/Runtime/Character/CCharAnimTime.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #undef min #undef max @@ -19,7 +19,7 @@ public: constexpr CCharAnimTime() = default; constexpr CCharAnimTime(float time) : x0_time(time), x4_type(x0_time != 0.f ? EType::NonZero : EType::ZeroSteady) {} constexpr CCharAnimTime(EType type, float t) : x0_time(t), x4_type(type) {} - explicit CCharAnimTime(CInputStream& in) : x0_time(in.readFloatBig()), x4_type(EType(in.readUint32Big())) {} + explicit CCharAnimTime(CInputStream& in) : x0_time(in.ReadFloat()), x4_type(EType(in.ReadLong())) {} static constexpr CCharAnimTime Infinity() { return {EType::Infinity, 1.0f}; } float GetSeconds() const { return x0_time; } diff --git a/Runtime/Character/CCharLayoutInfo.cpp b/Runtime/Character/CCharLayoutInfo.cpp index 64b1941d5..65163c595 100644 --- a/Runtime/Character/CCharLayoutInfo.cpp +++ b/Runtime/Character/CCharLayoutInfo.cpp @@ -32,30 +32,30 @@ CSegId CCharLayoutInfo::GetSegIdFromString(std::string_view name) const { void CCharLayoutNode::Bone::read(CInputStream& in) { x0_parentId = CSegId(in); - x4_origin.readBig(in); + x4_origin = in.Get(); - const u32 chCount = in.readUint32Big(); + const u32 chCount = in.ReadLong(); x10_children.reserve(chCount); for (u32 i = 0; i < chCount; ++i) { x10_children.emplace_back(in); } } -CCharLayoutNode::CCharLayoutNode(CInputStream& in) : x0_boneMap(in.readUint32Big()) { +CCharLayoutNode::CCharLayoutNode(CInputStream& in) : x0_boneMap(in.ReadLong()) { const u32 cap = x0_boneMap.GetCapacity(); for (u32 i = 0; i < cap; ++i) { - const u32 thisId = in.readUint32Big(); + const u32 thisId = in.ReadLong(); Bone& bone = x0_boneMap[thisId]; bone.read(in); } } CCharLayoutInfo::CCharLayoutInfo(CInputStream& in) : x0_node(std::make_shared(in)), x8_segIdList(in) { - const atUint32 mapCount = in.readUint32Big(); + const u32 mapCount = in.ReadLong(); - for (atUint32 i = 0; i < mapCount; ++i) { - std::string key = in.readString(); + for (u32 i = 0; i < mapCount; ++i) { + std::string key = in.Get(); x18_segIdMap.emplace(std::move(key), in); } } diff --git a/Runtime/Character/CCharLayoutInfo.hpp b/Runtime/Character/CCharLayoutInfo.hpp index 1678f3281..70641e8b8 100644 --- a/Runtime/Character/CCharLayoutInfo.hpp +++ b/Runtime/Character/CCharLayoutInfo.hpp @@ -6,7 +6,7 @@ #include #include "Runtime/CFactoryMgr.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CSegId.hpp" #include "Runtime/Character/CSegIdList.hpp" #include "Runtime/Character/TSegIdMap.hpp" diff --git a/Runtime/Character/CCharacterFactory.cpp b/Runtime/Character/CCharacterFactory.cpp index 1469a8b7e..fbaeb1bbe 100644 --- a/Runtime/Character/CCharacterFactory.cpp +++ b/Runtime/Character/CCharacterFactory.cpp @@ -22,15 +22,13 @@ CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag, const CCharacterInfo& charInfo = *params.GetOwnedObj(); - switch (tag.type.toUint32() & 0x1) { + switch (tag.type.toUint32()) { case 0: - return TToken::GetIObjObjectFor( - std::make_unique(*g_SimplePool, charInfo.GetModelId(), charInfo.GetSkinRulesId(), - charInfo.GetCharLayoutInfoId(), 0, tag.type.toUint32() >> 16)); + return TToken::GetIObjObjectFor(std::make_unique( + *g_SimplePool, charInfo.GetModelId(), charInfo.GetSkinRulesId(), charInfo.GetCharLayoutInfoId())); case 1: - return TToken::GetIObjObjectFor( - std::make_unique(*g_SimplePool, charInfo.GetIceModelId(), charInfo.GetIceSkinRulesId(), - charInfo.GetCharLayoutInfoId(), 0, tag.type.toUint32() >> 16)); + return TToken::GetIObjObjectFor(std::make_unique( + *g_SimplePool, charInfo.GetIceModelId(), charInfo.GetIceSkinRulesId(), charInfo.GetCharLayoutInfoId())); default: break; } @@ -78,21 +76,20 @@ std::unique_ptr CCharacterFactory::CDummyFactory::LoadNewResourcePartSync( std::unique_ptr CCharacterFactory::CreateCharacter(int charIdx, bool loop, const TLockedToken& factory, - int defaultAnim, int drawInsts) { + int defaultAnim) { const CCharacterInfo& charInfo = x4_charInfoDB[charIdx]; const CVParamTransfer charParm(new TObjOwnerParam(&charInfo)); - TToken skinnedModel = - x70_cacheResPool.GetObj({FourCC(drawInsts << 16), charInfo.GetModelId()}, charParm); + TToken skinnedModel = x70_cacheResPool.GetObj({FourCC(0u), charInfo.GetModelId()}, charParm); - std::optional> iceModel; + std::optional> iceModel; if (charInfo.GetIceModelId().IsValid() && charInfo.GetIceSkinRulesId().IsValid()) { - iceModel.emplace(x70_cacheResPool.GetObj({FourCC((drawInsts << 16) | 1), charInfo.GetIceModelId()}, charParm)); + iceModel.emplace(x70_cacheResPool.GetObj({FourCC(1u), charInfo.GetIceModelId()}, charParm)); } return std::make_unique(x68_selfId, charInfo, defaultAnim, charIdx, loop, x14_charLayoutInfoDB[charIdx], std::move(skinnedModel), iceModel, x24_sysContext, x28_animMgr, x2c_transMgr, - factory, drawInsts); + factory); } CAssetId CCharacterFactory::GetEventResourceIdForAnimResourceId(CAssetId id) const { @@ -156,8 +153,9 @@ CCharacterFactory::CCharacterFactory(CSimplePool& store, const CAnimCharacterSet std::vector primitives; x28_animMgr->GetAnimationDatabase()->GetAllUniquePrimitives(primitives); x30_animSourceDB.reserve(primitives.size()); - for (const CPrimitive& prim : primitives) - x30_animSourceDB.push_back(store.GetObj({SBIG('ANIM'), prim.GetAnimResId()})); + for (const CPrimitive& prim : primitives) { + x30_animSourceDB.emplace_back(store.GetObj({SBIG('ANIM'), prim.GetAnimResId()})); + } } } // namespace metaforce diff --git a/Runtime/Character/CCharacterFactory.hpp b/Runtime/Character/CCharacterFactory.hpp index a4ac2ba47..ea14f8b6c 100644 --- a/Runtime/Character/CCharacterFactory.hpp +++ b/Runtime/Character/CCharacterFactory.hpp @@ -10,6 +10,7 @@ #include "Runtime/IFactory.hpp" #include "Runtime/IObjFactory.hpp" #include "Runtime/Character/CAnimationSet.hpp" +#include "Runtime/Character/CCharacterInfo.hpp" namespace metaforce { class CAdditiveAnimationInfo; @@ -18,7 +19,6 @@ class CAnimCharacterSet; class CAnimData; class CAnimationManager; class CCharLayoutInfo; -class CCharacterInfo; class CSimplePool; class CTransitionDatabaseGame; class CTransitionManager; @@ -68,7 +68,7 @@ public: CCharacterFactory(CSimplePool& store, const CAnimCharacterSet& ancs, CAssetId); std::unique_ptr CreateCharacter(int charIdx, bool loop, const TLockedToken& factory, - int defaultAnim, int drawInsts); + int defaultAnim); CAssetId GetEventResourceIdForAnimResourceId(CAssetId animId) const; const CCharacterInfo& GetCharInfo(int charIdx) const { return x4_charInfoDB[charIdx]; } diff --git a/Runtime/Character/CCharacterInfo.cpp b/Runtime/Character/CCharacterInfo.cpp index 7dec11562..02b965a0e 100644 --- a/Runtime/Character/CCharacterInfo.cpp +++ b/Runtime/Character/CCharacterInfo.cpp @@ -1,76 +1,77 @@ #include "Runtime/Character/CCharacterInfo.hpp" +#include "Runtime/Streams/IOStreams.hpp" namespace metaforce { CCharacterInfo::CParticleResData::CParticleResData(CInputStream& in, u16 tableCount) { - const u32 partCount = in.readUint32Big(); + const u32 partCount = in.ReadLong(); x0_part.reserve(partCount); for (u32 i = 0; i < partCount; ++i) { - x0_part.emplace_back(in.readUint32Big()); + x0_part.emplace_back(in.Get()); } - const u32 swhcCount = in.readUint32Big(); + const u32 swhcCount = in.ReadLong(); x10_swhc.reserve(swhcCount); for (u32 i = 0; i < swhcCount; ++i) { - x10_swhc.emplace_back(in.readUint32Big()); + x10_swhc.emplace_back(in.Get()); } - const u32 unkCount = in.readUint32Big(); + const u32 unkCount = in.ReadLong(); x20_elsc.reserve(unkCount); for (u32 i = 0; i < unkCount; ++i) { - x20_elsc.emplace_back(in.readUint32Big()); + x20_elsc.emplace_back(in.Get()); } if (tableCount > 5) { - const u32 elscCount = in.readUint32Big(); + const u32 elscCount = in.ReadLong(); x30_elsc.reserve(elscCount); for (u32 i = 0; i < elscCount; ++i) { - x30_elsc.emplace_back(in.readUint32Big()); + x30_elsc.emplace_back(in.Get()); } } } static std::vector>> MakeAnimInfoVector(CInputStream& in) { std::vector>> ret; - const u32 animInfoCount = in.readUint32Big(); + const u32 animInfoCount = in.ReadLong(); ret.reserve(animInfoCount); for (u32 i = 0; i < animInfoCount; ++i) { - const s32 idx = in.readInt32Big(); - std::string a = in.readString(); - std::string b = in.readString(); + const s32 idx = in.ReadLong(); + std::string a = in.Get(); + std::string b = in.Get(); ret.emplace_back(idx, std::make_pair(std::move(a), std::move(b))); } return ret; } CCharacterInfo::CCharacterInfo(CInputStream& in) -: x0_tableCount(in.readUint16Big()) -, x4_name(in.readString()) -, x14_cmdl(in.readUint32Big()) -, x18_cskr(in.readUint32Big()) -, x1c_cinf(in.readUint32Big()) +: x0_tableCount(in.ReadShort()) +, x4_name(in.Get()) +, x14_cmdl(in) +, x18_cskr(in) +, x1c_cinf(in) , x20_animInfo(MakeAnimInfoVector(in)) , x30_pasDatabase(in) , x44_partRes(in, x0_tableCount) -, x84_unk(in.readUint32Big()) { +, x84_unk(in.ReadLong()) { if (x0_tableCount > 1) { - const u32 aabbCount = in.readUint32Big(); + const u32 aabbCount = in.ReadLong(); x88_aabbs.reserve(aabbCount); for (u32 i = 0; i < aabbCount; ++i) { - std::string name = in.readString(); + std::string name = in.Get(); x88_aabbs.emplace_back(std::move(name), zeus::CAABox()); - x88_aabbs.back().second.readBoundingBoxBig(in); + x88_aabbs.back().second = in.Get(); } } if (x0_tableCount > 2) { - const u32 effectCount = in.readUint32Big(); + const u32 effectCount = in.ReadLong(); x98_effects.reserve(effectCount); for (u32 i = 0; i < effectCount; ++i) { - std::string name = in.readString(); + std::string name = in.Get(); x98_effects.emplace_back(std::move(name), std::vector()); std::vector& comps = x98_effects.back().second; - const u32 compCount = in.readUint32Big(); + const u32 compCount = in.ReadLong(); comps.reserve(compCount); for (u32 j = 0; j < compCount; ++j) { comps.emplace_back(in); @@ -79,15 +80,15 @@ CCharacterInfo::CCharacterInfo(CInputStream& in) } if (x0_tableCount > 3) { - xa8_cmdlOverlay = in.readUint32Big(); - xac_cskrOverlay = in.readUint32Big(); + xa8_cmdlOverlay = in.Get(); + xac_cskrOverlay = in.Get(); } if (x0_tableCount > 4) { - const u32 aidxCount = in.readUint32Big(); + const u32 aidxCount = in.ReadLong(); xb0_animIdxs.reserve(aidxCount); for (u32 i = 0; i < aidxCount; ++i) { - xb0_animIdxs.push_back(in.readInt32Big()); + xb0_animIdxs.push_back(in.ReadLong()); } } } diff --git a/Runtime/Character/CCharacterInfo.hpp b/Runtime/Character/CCharacterInfo.hpp index 81dd92902..0ba54758c 100644 --- a/Runtime/Character/CCharacterInfo.hpp +++ b/Runtime/Character/CCharacterInfo.hpp @@ -4,7 +4,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/Character/CEffectComponent.hpp" #include "Runtime/Character/CPASDatabase.hpp" @@ -41,8 +41,8 @@ private: std::vector> x88_aabbs; std::vector>> x98_effects; - CAssetId xa8_cmdlOverlay = 0; - CAssetId xac_cskrOverlay = 0; + CAssetId xa8_cmdlOverlay; + CAssetId xac_cskrOverlay; std::vector xb0_animIdxs; diff --git a/Runtime/Character/CCharacterSet.cpp b/Runtime/Character/CCharacterSet.cpp index a0bc9bbdc..4cc652b4d 100644 --- a/Runtime/Character/CCharacterSet.cpp +++ b/Runtime/Character/CCharacterSet.cpp @@ -2,10 +2,10 @@ namespace metaforce { -CCharacterSet::CCharacterSet(CInputStream& in) : x0_version(in.readUint16Big()) { - u32 charCount = in.readUint32Big(); +CCharacterSet::CCharacterSet(CInputStream& in) : x0_version(in.ReadShort()) { + u32 charCount = in.ReadLong(); for (u32 i = 0; i < charCount; ++i) { - u32 id = in.readUint32Big(); + u32 id = in.ReadLong(); x4_characters.emplace(id, in); } } diff --git a/Runtime/Character/CCharacterSet.hpp b/Runtime/Character/CCharacterSet.hpp index 2addb1bc7..fc1fc4ec3 100644 --- a/Runtime/Character/CCharacterSet.hpp +++ b/Runtime/Character/CCharacterSet.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/GCNTypes.hpp" #include "Runtime/Character/CCharacterInfo.hpp" diff --git a/Runtime/Character/CEffectComponent.cpp b/Runtime/Character/CEffectComponent.cpp index 050a960d9..17f79d617 100644 --- a/Runtime/Character/CEffectComponent.cpp +++ b/Runtime/Character/CEffectComponent.cpp @@ -2,15 +2,15 @@ namespace metaforce { -SObjectTag CEffectComponent::GetSObjectTagFromStream(CInputStream& in) { return SObjectTag(in); } +SObjectTag CEffectComponent::GetSObjectTagFromStream(CInputStream& in) { return in.Get(); } CEffectComponent::CEffectComponent(CInputStream& in) { - x0_name = in.readString(); + x0_name = in.Get(); x10_tag = GetSObjectTagFromStream(in); - x18_boneName = in.readString(); - x28_scale = in.readFloatBig(); - x2c_parentedMode = CParticleData::EParentedMode(in.readUint32Big()); - x30_flags = in.readUint32Big(); + x18_boneName = in.Get(); + x28_scale = in.ReadFloat(); + x2c_parentedMode = CParticleData::EParentedMode(in.ReadLong()); + x30_flags = in.ReadLong(); } } // namespace metaforce diff --git a/Runtime/Character/CEffectComponent.hpp b/Runtime/Character/CEffectComponent.hpp index 856d33ab1..b691680ed 100644 --- a/Runtime/Character/CEffectComponent.hpp +++ b/Runtime/Character/CEffectComponent.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/Character/CParticleData.hpp" diff --git a/Runtime/Character/CFBStreamedAnimReader.cpp b/Runtime/Character/CFBStreamedAnimReader.cpp index a2a80ff6c..b50d79b8f 100644 --- a/Runtime/Character/CFBStreamedAnimReader.cpp +++ b/Runtime/Character/CFBStreamedAnimReader.cpp @@ -139,7 +139,7 @@ void CFBStreamedAnimReaderTotals::IncrementInto(CBitLevelLoader& loader, const C if (tCount) { cumulativesOut[4] = cumulativesIn[4] + loader.LoadSigned(*reinterpret_cast(chans + 2)); cumulativesOut[5] = cumulativesIn[5] + loader.LoadSigned(*reinterpret_cast(chans + 5)); - cumulativesOut[6] = cumulativesIn[5] + loader.LoadSigned(*reinterpret_cast(chans + 8)); + cumulativesOut[6] = cumulativesIn[6] + loader.LoadSigned(*reinterpret_cast(chans + 8)); chans += 9; } } diff --git a/Runtime/Character/CFBStreamedCompression.cpp b/Runtime/Character/CFBStreamedCompression.cpp index a2be29412..f1aaade56 100644 --- a/Runtime/Character/CFBStreamedCompression.cpp +++ b/Runtime/Character/CFBStreamedCompression.cpp @@ -23,8 +23,8 @@ void WriteValue(u8* data, T value) { } // Anonymous namespace CFBStreamedCompression::CFBStreamedCompression(CInputStream& in, IObjectStore& objStore, bool pc) : m_pc(pc) { - x0_scratchSize = in.readUint32Big(); - x4_evnt = in.readUint32Big(); + x0_scratchSize = in.ReadLong(); + x4_evnt = in.Get(); xc_rotsAndOffs = GetRotationsAndOffsets(x0_scratchSize / 4 + 1, in); @@ -86,78 +86,78 @@ std::unique_ptr CFBStreamedCompression::GetRotationsAndOffsets(u32 words, std::memcpy(ret.get(), &head, sizeof(head)); u32* bitmapOut = &ret[9]; - const u32 bitmapBitCount = in.readUint32Big(); + const u32 bitmapBitCount = in.ReadLong(); bitmapOut[0] = bitmapBitCount; const u32 bitmapWordCount = (bitmapBitCount + 31) / 32; for (u32 i = 0; i < bitmapWordCount; ++i) { - bitmapOut[i + 1] = in.readUint32Big(); + bitmapOut[i + 1] = in.ReadLong(); } - in.readUint32Big(); + in.ReadLong(); u8* chans = reinterpret_cast(bitmapOut + bitmapWordCount + 1); u8* bs = ReadBoneChannelDescriptors(chans, in); const u32 bsWords = ComputeBitstreamWords(chans); u32* bsPtr = reinterpret_cast(bs); for (u32 w = 0; w < bsWords; ++w) - bsPtr[w] = in.readUint32Big(); + bsPtr[w] = in.ReadLong(); return ret; } u8* CFBStreamedCompression::ReadBoneChannelDescriptors(u8* out, CInputStream& in) const { - const u32 boneChanCount = in.readUint32Big(); + const u32 boneChanCount = in.ReadLong(); WriteValue(out, boneChanCount); out += 4; if (m_pc) { for (u32 b = 0; b < boneChanCount; ++b) { - WriteValue(out, in.readUint32Big()); + WriteValue(out, in.ReadLong()); out += 4; - WriteValue(out, in.readUint32Big()); + WriteValue(out, in.ReadLong()); out += 4; for (int i = 0; i < 3; ++i) { - WriteValue(out, in.readUint32Big()); + WriteValue(out, in.ReadLong()); out += 4; } - const u32 tCount = in.readUint32Big(); + const u32 tCount = in.ReadLong(); WriteValue(out, tCount); out += 4; if (tCount != 0) { for (int i = 0; i < 3; ++i) { - WriteValue(out, in.readUint32Big()); + WriteValue(out, in.ReadLong()); out += 4; } } } } else { for (u32 b = 0; b < boneChanCount; ++b) { - WriteValue(out, in.readUint32Big()); + WriteValue(out, in.ReadLong()); out += 4; - WriteValue(out, in.readUint16Big()); + WriteValue(out, in.ReadShort()); out += 2; for (int i = 0; i < 3; ++i) { - WriteValue(out, in.readInt16Big()); + WriteValue(out, in.ReadShort()); out += 2; - WriteValue(out, in.readUByte()); + WriteValue(out, in.ReadUint8()); out += 1; } - const u16 tCount = in.readUint16Big(); + const u16 tCount = in.ReadShort(); WriteValue(out, tCount); out += 2; if (tCount != 0) { for (int i = 0; i < 3; ++i) { - WriteValue(out, in.readInt16Big()); + WriteValue(out, in.ReadShort()); out += 2; - WriteValue(out, in.readUByte()); + WriteValue(out, in.ReadUint8()); out += 1; } } diff --git a/Runtime/Character/CFBStreamedCompression.hpp b/Runtime/Character/CFBStreamedCompression.hpp index 2d06cd1cc..a6aca4390 100644 --- a/Runtime/Character/CFBStreamedCompression.hpp +++ b/Runtime/Character/CFBStreamedCompression.hpp @@ -31,23 +31,23 @@ public: void read(CInputStream& in) { /* unk0 */ - unk0 = in.readUint32Big(); + unk0 = in.ReadLong(); /* duration */ - duration = in.readFloatBig(); + duration = in.ReadFloat(); /* interval */ - interval = in.readFloatBig(); + interval = in.ReadFloat(); /* rootBoneId */ - rootBoneId = in.readUint32Big(); + rootBoneId = in.ReadLong(); /* looping */ - looping = in.readUint32Big(); + looping = in.ReadLong(); /* rotDiv */ - rotDiv = in.readUint32Big(); + rotDiv = in.ReadLong(); /* translationMult */ - translationMult = in.readFloatBig(); + translationMult = in.ReadFloat(); /* boneChannelCount */ - boneChannelCount = in.readUint32Big(); + boneChannelCount = in.ReadLong(); /* unk3 */ - unk3 = in.readUint32Big(); + unk3 = in.ReadLong(); } }; diff --git a/Runtime/Character/CHalfTransition.cpp b/Runtime/Character/CHalfTransition.cpp index 36a00f1e3..43025512f 100644 --- a/Runtime/Character/CHalfTransition.cpp +++ b/Runtime/Character/CHalfTransition.cpp @@ -5,7 +5,7 @@ namespace metaforce { CHalfTransition::CHalfTransition(CInputStream& in) { - x0_id = in.readUint32Big(); + x0_id = in.ReadLong(); x4_trans = CMetaTransFactory::CreateMetaTrans(in); } diff --git a/Runtime/Character/CHalfTransition.hpp b/Runtime/Character/CHalfTransition.hpp index 6d6150fb3..f653ff1cf 100644 --- a/Runtime/Character/CHalfTransition.hpp +++ b/Runtime/Character/CHalfTransition.hpp @@ -3,7 +3,7 @@ #include #include "Runtime/GCNTypes.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaTrans.hpp" namespace metaforce { diff --git a/Runtime/Character/CHierarchyPoseBuilder.cpp b/Runtime/Character/CHierarchyPoseBuilder.cpp index a06e2b468..4adc0046d 100644 --- a/Runtime/Character/CHierarchyPoseBuilder.cpp +++ b/Runtime/Character/CHierarchyPoseBuilder.cpp @@ -33,17 +33,10 @@ void CHierarchyPoseBuilder::RecursivelyBuildNoScale(const CSegId& boneId, const CPoseAsTransforms& pose, const zeus::CQuaternion& parentRot, const zeus::CMatrix3f& parentXf, const zeus::CVector3f& parentOffset) const { - zeus::CVector3f bindOffset; - if (x0_layoutDesc.GetScaledLayoutDescription()) { - const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription(); - bindOffset = desc.ScaledLayout()->GetFromRootUnrotated(boneId); - } else - bindOffset = x0_layoutDesc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId); - zeus::CQuaternion quat = parentRot * node.x4_rotation; zeus::CMatrix3f xf = quat; zeus::CVector3f xfOffset = parentXf * node.x14_offset + parentOffset; - pose.Insert(boneId, quat, xfOffset, bindOffset); + pose.Insert(boneId, quat, xfOffset); CSegId curBone = node.x0_child; while (curBone != 0) { @@ -59,29 +52,25 @@ void CHierarchyPoseBuilder::RecursivelyBuild(const CSegId& boneId, const CTreeNo zeus::CQuaternion quat = parentRot * node.x4_rotation; float scale; - zeus::CVector3f bindOffset; if (x0_layoutDesc.GetScaledLayoutDescription()) { - const CLayoutDescription::CScaledLayoutDescription& desc = *x0_layoutDesc.GetScaledLayoutDescription(); - scale = desc.GlobalScale(); - bindOffset = desc.ScaledLayout()->GetFromRootUnrotated(boneId); + scale = x0_layoutDesc.GetScaledLayoutDescription()->GlobalScale(); } else { scale = 1.f; - bindOffset = x0_layoutDesc.GetCharLayoutInfo()->GetFromRootUnrotated(boneId); } - zeus::CMatrix3f mtxXf; + zeus::CMatrix3f rotation; if (scale == 1.f) - mtxXf = quat; + rotation = quat; else - mtxXf = parentXf * zeus::CMatrix3f(scale); + rotation = parentXf * (zeus::CMatrix3f{node.x4_rotation} * zeus::CMatrix3f{scale}); - zeus::CVector3f xfOffset = parentXf * node.x14_offset + parentOffset; - pose.Insert(boneId, mtxXf, xfOffset, bindOffset); + zeus::CVector3f offset = parentOffset + (parentXf * node.x14_offset); + pose.Insert(boneId, rotation, offset); CSegId curBone = node.x0_child; while (curBone != 0) { const CTreeNode& node = x38_treeMap[curBone]; - RecursivelyBuild(curBone, node, pose, quat, quat, xfOffset); + RecursivelyBuild(curBone, node, pose, quat, quat, offset); curBone = node.x1_sibling; } } diff --git a/Runtime/Character/CInt32POINode.cpp b/Runtime/Character/CInt32POINode.cpp index 324ff54f4..3e0cd218b 100644 --- a/Runtime/Character/CInt32POINode.cpp +++ b/Runtime/Character/CInt32POINode.cpp @@ -11,7 +11,7 @@ CInt32POINode::CInt32POINode(std::string_view name, EPOIType type, const CCharAn : CPOINode(name, type, time, index, unique, weight, charIndex, flags), x38_val(val), x3c_locatorName(locator) {} CInt32POINode::CInt32POINode(CInputStream& in) -: CPOINode(in), x38_val(in.readUint32Big()), x3c_locatorName(in.readString()) {} +: CPOINode(in), x38_val(in.ReadLong()), x3c_locatorName(in.Get()) {} CInt32POINode CInt32POINode::CopyNodeMinusStartTime(const CInt32POINode& node, const CCharAnimTime& startTime) { CInt32POINode ret = node; diff --git a/Runtime/Character/CMakeLists.txt b/Runtime/Character/CMakeLists.txt index 2b79fb83e..2b3e3a316 100644 --- a/Runtime/Character/CMakeLists.txt +++ b/Runtime/Character/CMakeLists.txt @@ -14,7 +14,6 @@ set(CHARACTER_SOURCES CTransitionDatabaseGame.hpp CTransitionDatabaseGame.cpp CHierarchyPoseBuilder.hpp CHierarchyPoseBuilder.cpp CPoseAsTransforms.hpp CPoseAsTransforms.cpp - CSkinBank.hpp CSkinBank.cpp CCharLayoutInfo.hpp CCharLayoutInfo.cpp CLayoutDescription.hpp CSegIdList.hpp CSegIdList.cpp diff --git a/Runtime/Character/CMetaAnimBlend.cpp b/Runtime/Character/CMetaAnimBlend.cpp index 67d81f3d2..30c988ec2 100644 --- a/Runtime/Character/CMetaAnimBlend.cpp +++ b/Runtime/Character/CMetaAnimBlend.cpp @@ -8,8 +8,8 @@ namespace metaforce { CMetaAnimBlend::CMetaAnimBlend(CInputStream& in) { x4_animA = CMetaAnimFactory::CreateMetaAnim(in); x8_animB = CMetaAnimFactory::CreateMetaAnim(in); - xc_blend = in.readFloatBig(); - x10_ = in.readBool(); + xc_blend = in.ReadFloat(); + x10_ = in.ReadBool(); } void CMetaAnimBlend::GetUniquePrimitives(std::set& primsOut) const { diff --git a/Runtime/Character/CMetaAnimBlend.hpp b/Runtime/Character/CMetaAnimBlend.hpp index 8b9997465..ef1d7de9b 100644 --- a/Runtime/Character/CMetaAnimBlend.hpp +++ b/Runtime/Character/CMetaAnimBlend.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaAnim.hpp" namespace metaforce { diff --git a/Runtime/Character/CMetaAnimFactory.cpp b/Runtime/Character/CMetaAnimFactory.cpp index daf92802e..b41bc3c11 100644 --- a/Runtime/Character/CMetaAnimFactory.cpp +++ b/Runtime/Character/CMetaAnimFactory.cpp @@ -9,7 +9,7 @@ namespace metaforce { std::shared_ptr CMetaAnimFactory::CreateMetaAnim(CInputStream& in) { - EMetaAnimType type = EMetaAnimType(in.readUint32Big()); + EMetaAnimType type = EMetaAnimType(in.ReadLong()); switch (type) { case EMetaAnimType::Play: diff --git a/Runtime/Character/CMetaAnimFactory.hpp b/Runtime/Character/CMetaAnimFactory.hpp index 8f2d423ee..ea43d0683 100644 --- a/Runtime/Character/CMetaAnimFactory.hpp +++ b/Runtime/Character/CMetaAnimFactory.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaAnim.hpp" namespace metaforce { diff --git a/Runtime/Character/CMetaAnimPhaseBlend.cpp b/Runtime/Character/CMetaAnimPhaseBlend.cpp index da9d00cde..42095d332 100644 --- a/Runtime/Character/CMetaAnimPhaseBlend.cpp +++ b/Runtime/Character/CMetaAnimPhaseBlend.cpp @@ -9,8 +9,8 @@ namespace metaforce { CMetaAnimPhaseBlend::CMetaAnimPhaseBlend(CInputStream& in) { x4_animA = CMetaAnimFactory::CreateMetaAnim(in); x8_animB = CMetaAnimFactory::CreateMetaAnim(in); - xc_blend = in.readFloatBig(); - x10_ = in.readBool(); + xc_blend = in.ReadFloat(); + x10_ = in.ReadBool(); } void CMetaAnimPhaseBlend::GetUniquePrimitives(std::set& primsOut) const { diff --git a/Runtime/Character/CMetaAnimPhaseBlend.hpp b/Runtime/Character/CMetaAnimPhaseBlend.hpp index df612b3c2..d798f745d 100644 --- a/Runtime/Character/CMetaAnimPhaseBlend.hpp +++ b/Runtime/Character/CMetaAnimPhaseBlend.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaAnim.hpp" namespace metaforce { diff --git a/Runtime/Character/CMetaAnimPlay.hpp b/Runtime/Character/CMetaAnimPlay.hpp index 0508ea1ee..2134bdfc4 100644 --- a/Runtime/Character/CMetaAnimPlay.hpp +++ b/Runtime/Character/CMetaAnimPlay.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CPrimitive.hpp" #include "Runtime/Character/IMetaAnim.hpp" diff --git a/Runtime/Character/CMetaAnimRandom.cpp b/Runtime/Character/CMetaAnimRandom.cpp index 02f1f1342..74cdac9c1 100644 --- a/Runtime/Character/CMetaAnimRandom.cpp +++ b/Runtime/Character/CMetaAnimRandom.cpp @@ -7,12 +7,12 @@ namespace metaforce { CMetaAnimRandom::RandomData CMetaAnimRandom::CreateRandomData(CInputStream& in) { CMetaAnimRandom::RandomData ret; - u32 randCount = in.readUint32Big(); + u32 randCount = in.ReadLong(); ret.reserve(randCount); for (u32 i = 0; i < randCount; ++i) { std::shared_ptr metaAnim = CMetaAnimFactory::CreateMetaAnim(in); - ret.emplace_back(std::move(metaAnim), in.readUint32Big()); + ret.emplace_back(std::move(metaAnim), in.ReadLong()); } return ret; diff --git a/Runtime/Character/CMetaAnimRandom.hpp b/Runtime/Character/CMetaAnimRandom.hpp index 272c01bb6..cf59ebfdc 100644 --- a/Runtime/Character/CMetaAnimRandom.hpp +++ b/Runtime/Character/CMetaAnimRandom.hpp @@ -4,7 +4,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaAnim.hpp" namespace metaforce { diff --git a/Runtime/Character/CMetaAnimSequence.cpp b/Runtime/Character/CMetaAnimSequence.cpp index a96539731..ffa717670 100644 --- a/Runtime/Character/CMetaAnimSequence.cpp +++ b/Runtime/Character/CMetaAnimSequence.cpp @@ -7,7 +7,7 @@ namespace metaforce { std::vector> CMetaAnimSequence::CreateSequence(CInputStream& in) { std::vector> ret; - u32 seqCount = in.readUint32Big(); + u32 seqCount = in.ReadLong(); ret.reserve(seqCount); for (u32 i = 0; i < seqCount; ++i) diff --git a/Runtime/Character/CMetaAnimSequence.hpp b/Runtime/Character/CMetaAnimSequence.hpp index f937cce8c..a4d176b9c 100644 --- a/Runtime/Character/CMetaAnimSequence.hpp +++ b/Runtime/Character/CMetaAnimSequence.hpp @@ -3,7 +3,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaAnim.hpp" namespace metaforce { diff --git a/Runtime/Character/CMetaTransFactory.cpp b/Runtime/Character/CMetaTransFactory.cpp index 1ae7d87fd..b408d00f1 100644 --- a/Runtime/Character/CMetaTransFactory.cpp +++ b/Runtime/Character/CMetaTransFactory.cpp @@ -8,7 +8,7 @@ namespace metaforce { std::shared_ptr CMetaTransFactory::CreateMetaTrans(CInputStream& in) { - EMetaTransType type = EMetaTransType(in.readUint32Big()); + EMetaTransType type = EMetaTransType(in.ReadLong()); switch (type) { case EMetaTransType::MetaAnim: diff --git a/Runtime/Character/CMetaTransFactory.hpp b/Runtime/Character/CMetaTransFactory.hpp index 503c8331f..b3a80159c 100644 --- a/Runtime/Character/CMetaTransFactory.hpp +++ b/Runtime/Character/CMetaTransFactory.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaTrans.hpp" namespace metaforce { diff --git a/Runtime/Character/CMetaTransMetaAnim.hpp b/Runtime/Character/CMetaTransMetaAnim.hpp index 55400a798..201bef08f 100644 --- a/Runtime/Character/CMetaTransMetaAnim.hpp +++ b/Runtime/Character/CMetaTransMetaAnim.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaAnim.hpp" #include "Runtime/Character/IMetaTrans.hpp" diff --git a/Runtime/Character/CMetaTransPhaseTrans.cpp b/Runtime/Character/CMetaTransPhaseTrans.cpp index f158da0aa..7a09cee6b 100644 --- a/Runtime/Character/CMetaTransPhaseTrans.cpp +++ b/Runtime/Character/CMetaTransPhaseTrans.cpp @@ -9,9 +9,9 @@ namespace metaforce { CMetaTransPhaseTrans::CMetaTransPhaseTrans(CInputStream& in) { x4_transDur = CCharAnimTime(in); - xc_ = in.readBool(); - xd_runA = in.readBool(); - x10_flags = in.readUint32Big(); + xc_ = in.ReadBool(); + xd_runA = in.ReadBool(); + x10_flags = in.ReadLong(); } std::shared_ptr CMetaTransPhaseTrans::VGetTransitionTree(const std::weak_ptr& a, diff --git a/Runtime/Character/CMetaTransPhaseTrans.hpp b/Runtime/Character/CMetaTransPhaseTrans.hpp index 08fd2ba98..695824d0a 100644 --- a/Runtime/Character/CMetaTransPhaseTrans.hpp +++ b/Runtime/Character/CMetaTransPhaseTrans.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CCharAnimTime.hpp" #include "Runtime/Character/IMetaTrans.hpp" diff --git a/Runtime/Character/CMetaTransSnap.hpp b/Runtime/Character/CMetaTransSnap.hpp index 091b73f68..5a000bae4 100644 --- a/Runtime/Character/CMetaTransSnap.hpp +++ b/Runtime/Character/CMetaTransSnap.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/IMetaTrans.hpp" namespace metaforce { diff --git a/Runtime/Character/CMetaTransTrans.cpp b/Runtime/Character/CMetaTransTrans.cpp index a64b86b30..914d1755c 100644 --- a/Runtime/Character/CMetaTransTrans.cpp +++ b/Runtime/Character/CMetaTransTrans.cpp @@ -5,10 +5,10 @@ namespace metaforce { CMetaTransTrans::CMetaTransTrans(CInputStream& in) { - x4_transDur = CCharAnimTime(in); - xc_ = in.readBool(); - xd_runA = in.readBool(); - x10_flags = in.readUint32Big(); + x4_transDur = in.Get(); + xc_ = in.ReadBool(); + xd_runA = in.ReadBool(); + x10_flags = in.ReadLong(); } std::shared_ptr CMetaTransTrans::VGetTransitionTree(const std::weak_ptr& a, diff --git a/Runtime/Character/CMetaTransTrans.hpp b/Runtime/Character/CMetaTransTrans.hpp index 5a0b0f2a7..a2e5def1c 100644 --- a/Runtime/Character/CMetaTransTrans.hpp +++ b/Runtime/Character/CMetaTransTrans.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CCharAnimTime.hpp" #include "Runtime/Character/IMetaTrans.hpp" diff --git a/Runtime/Character/CModelData.cpp b/Runtime/Character/CModelData.cpp index 37eb1bbfa..c5c912293 100644 --- a/Runtime/Character/CModelData.cpp +++ b/Runtime/Character/CModelData.cpp @@ -12,6 +12,7 @@ #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CSkinnedModel.hpp" #include "Runtime/Graphics/CVertexMorphEffect.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include @@ -23,17 +24,15 @@ CModelData::~CModelData() = default; CModelData::CModelData() {} CModelData CModelData::CModelDataNull() { return CModelData(); } -CModelData::CModelData(const CStaticRes& res, int instCount) : x0_scale(res.GetScale()), m_drawInstCount(instCount) { +CModelData::CModelData(const CStaticRes& res) : x0_scale(res.GetScale()) { x1c_normalModel = g_SimplePool->GetObj({SBIG('CMDL'), res.GetId()}); if (!x1c_normalModel) Log.report(logvisor::Fatal, FMT_STRING("unable to find CMDL {}"), res.GetId()); - m_normalModelInst = x1c_normalModel->MakeNewInstance(0, instCount); } -CModelData::CModelData(const CAnimRes& res, int instCount) : x0_scale(res.GetScale()), m_drawInstCount(instCount) { +CModelData::CModelData(const CAnimRes& res) : x0_scale(res.GetScale()) { TToken factory = g_CharFactoryBuilder->GetFactory(res); - x10_animData = - factory->CreateCharacter(res.GetCharacterNodeId(), res.CanLoop(), factory, res.GetDefaultAnim(), instCount); + x10_animData = factory->CreateCharacter(res.GetCharacterNodeId(), res.CanLoop(), factory, res.GetDefaultAnim()); } SAdvancementDeltas CModelData::GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const { @@ -48,25 +47,25 @@ void CModelData::Render(const CStateManager& stateMgr, const zeus::CTransform& x Render(GetRenderingModel(stateMgr), xf, lights, drawFlags); } -bool CModelData::IsLoaded(int shaderIdx) const { +bool CModelData::IsLoaded(int shaderIdx) { if (x10_animData) { if (!x10_animData->xd8_modelData->GetModel()->IsLoaded(shaderIdx)) return false; - if (const CSkinnedModel* model = x10_animData->xf4_xrayModel.get()) + if (auto* model = x10_animData->xf4_xrayModel.get()) if (!model->GetModel()->IsLoaded(shaderIdx)) return false; - if (const CSkinnedModel* model = x10_animData->xf8_infraModel.get()) + if (auto* model = x10_animData->xf8_infraModel.get()) if (!model->GetModel()->IsLoaded(shaderIdx)) return false; } - if (const CModel* model = x1c_normalModel.GetObj()) + if (auto* model = x1c_normalModel.GetObj()) if (!model->IsLoaded(shaderIdx)) return false; - if (const CModel* model = x2c_xrayModel.GetObj()) + if (auto* model = x2c_xrayModel.GetObj()) if (!model->IsLoaded(shaderIdx)) return false; - if (const CModel* model = x3c_infraModel.GetObj()) + if (auto* model = x3c_infraModel.GetObj()) if (!model->IsLoaded(shaderIdx)) return false; @@ -114,22 +113,23 @@ CSkinnedModel& CModelData::PickAnimatedModel(EWhichModel which) const { return *x10_animData->xd8_modelData.GetObj(); } -const std::unique_ptr& CModelData::PickStaticModel(EWhichModel which) const { - const std::unique_ptr* ret = nullptr; +TLockedToken& CModelData::PickStaticModel(EWhichModel which) { switch (which) { case EWhichModel::XRay: - ret = &m_xrayModelInst; + if (x2c_xrayModel) { + return x2c_xrayModel; + } break; case EWhichModel::Thermal: case EWhichModel::ThermalHot: - ret = &m_infraModelInst; + if (x3c_infraModel) { + return x3c_infraModel; + } break; default: break; } - if (ret && *ret) - return *ret; - return m_normalModelInst; + return x1c_normalModel; } void CModelData::SetXRayModel(const std::pair& modelSkin) { @@ -143,7 +143,6 @@ void CModelData::SetXRayModel(const std::pair& modelSkin) { x2c_xrayModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first}); if (!x2c_xrayModel) Log.report(logvisor::Fatal, FMT_STRING("unable to find CMDL {}"), modelSkin.first); - m_xrayModelInst = x2c_xrayModel->MakeNewInstance(0, m_drawInstCount); } } } @@ -160,7 +159,6 @@ void CModelData::SetInfraModel(const std::pair& modelSkin) { x3c_infraModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first}); if (!x3c_infraModel) Log.report(logvisor::Fatal, FMT_STRING("unable to find CMDL {}"), modelSkin.first); - m_infraModelInst = x3c_infraModel->MakeNewInstance(0, m_drawInstCount); } } } @@ -169,7 +167,7 @@ void CModelData::SetInfraModel(const std::pair& modelSkin) { bool CModelData::IsDefinitelyOpaque(EWhichModel which) const { if (x10_animData) { CSkinnedModel& model = PickAnimatedModel(which); - return model.GetModelInst()->IsOpaque(); + return model.GetModel()->IsOpaque(); } else { const auto& model = PickStaticModel(which); return model->IsOpaque(); @@ -274,41 +272,30 @@ void CModelData::RenderParticles(const zeus::CFrustum& frustum) const { x10_animData->RenderAuxiliary(frustum); } -void CModelData::Touch(EWhichModel which, int shaderIdx) const { +void CModelData::Touch(EWhichModel which, int shaderIdx) { if (x10_animData) x10_animData->Touch(PickAnimatedModel(which), shaderIdx); else PickStaticModel(which)->Touch(shaderIdx); } -void CModelData::Touch(const CStateManager& stateMgr, int shaderIdx) const { - Touch(GetRenderingModel(stateMgr), shaderIdx); -} +void CModelData::Touch(const CStateManager& stateMgr, int shaderIdx) { Touch(GetRenderingModel(stateMgr), shaderIdx); } -void CModelData::RenderThermal(const zeus::CColor& mulColor, const zeus::CColor& addColor, - const CModelFlags& flags) const { - CModelFlags drawFlags = flags; - drawFlags.x4_color *= mulColor; - drawFlags.addColor = addColor; - drawFlags.m_extendedShader = EExtendedShader::ThermalModel; +void CModelData::RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor, const zeus::CColor& addColor, + const CModelFlags& flags) { + CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); + CGraphics::DisableAllLights(); if (x10_animData) { CSkinnedModel& model = PickAnimatedModel(EWhichModel::ThermalHot); - x10_animData->SetupRender(model, drawFlags, {}, nullptr); - model.Draw(drawFlags); + x10_animData->SetupRender(model, nullptr, nullptr); + ThermalDraw(model, mulColor, addColor, flags); } else { - const auto& model = PickStaticModel(EWhichModel::ThermalHot); - model->Draw(drawFlags, nullptr, nullptr); + auto& model = PickStaticModel(EWhichModel::ThermalHot); + g_Renderer->DrawThermalModel(*model, mulColor, addColor, {}, {}, flags); } } -void CModelData::RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor, const zeus::CColor& addColor, - const CModelFlags& flags) const { - CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); - CGraphics::DisableAllLights(); - RenderThermal(mulColor, addColor, flags); -} - void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, const CModelFlags& drawFlags) { if ((x14_25_sortThermal && which == EWhichModel::ThermalHot) || x10_animData || !x1c_normalModel || @@ -319,17 +306,15 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform& CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); - const auto& model = PickStaticModel(which); - if (lights) { - lights->ActivateLights(*model); + if (lights != nullptr) { + lights->ActivateLights(); } else { - std::vector useLights; - useLights.push_back(CLight::BuildLocalAmbient(zeus::skZero3f, x18_ambientColor)); - model->ActivateLights(useLights); + CGraphics::DisableAllLights(); + g_Renderer->SetAmbientColor(x18_ambientColor); } - model->DrawNormal(drawFlags, nullptr, nullptr); - // Set ambient to white + PickStaticModel(which)->DrawUnsortedParts(drawFlags); + g_Renderer->SetAmbientColor(zeus::skWhite); CGraphics::DisableAllLights(); x14_24_renderSorted = true; } @@ -339,111 +324,146 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf, const CAc if (x14_25_sortThermal && which == EWhichModel::ThermalHot) { zeus::CColor mul(drawFlags.x4_color.a(), drawFlags.x4_color.a()); RenderThermal(xf, mul, {0.f, 0.f, 0.f, 0.25f}, drawFlags); + return; + } + + CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); + + if (lights != nullptr) { + lights->ActivateLights(); } else { - CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); - - if (x10_animData) { - CSkinnedModel& model = PickAnimatedModel(which); - if (lights) { - lights->ActivateLights(*model.GetModelInst()); - } else { - std::vector useLights; - useLights.push_back(CLight::BuildLocalAmbient(zeus::skZero3f, x18_ambientColor)); - model.GetModelInst()->ActivateLights(useLights); - } - - x10_animData->Render(model, drawFlags, std::nullopt, nullptr); - } else { - const auto& model = PickStaticModel(which); - if (lights) { - lights->ActivateLights(*model); - } else { - std::vector useLights; - useLights.push_back(CLight::BuildLocalAmbient(zeus::skZero3f, x18_ambientColor)); - model->ActivateLights(useLights); - } - - if (x14_24_renderSorted) - model->DrawAlpha(drawFlags, nullptr, nullptr); - else - model->Draw(drawFlags, nullptr, nullptr); - } - - // Set ambient to white CGraphics::DisableAllLights(); - x14_24_renderSorted = false; + g_Renderer->SetAmbientColor(x18_ambientColor); + } + + if (x10_animData) { + x10_animData->Render(PickAnimatedModel(which), drawFlags, nullptr, nullptr); + } else { + // TODO supposed to be optional_object? + if (x1c_normalModel) { + auto& model = PickStaticModel(which); + if (x14_24_renderSorted) { + model->DrawSortedParts(drawFlags); + } else { + model->Draw(drawFlags); + } + } + } + + g_Renderer->SetAmbientColor(zeus::skWhite); + CGraphics::DisableAllLights(); + x14_24_renderSorted = false; +} + +void CModelData::FlatDraw(EWhichModel which, const zeus::CTransform& xf, bool unsortedOnly, const CModelFlags& flags) { + g_Renderer->SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); + CGraphics::DisableAllLights(); + if (!x10_animData) { + g_Renderer->DrawModelFlat(*PickStaticModel(which), flags, unsortedOnly, nullptr, nullptr); + } else { + auto model = PickAnimatedModel(which); + x10_animData->SetupRender(model, nullptr, nullptr); + model.DoDrawCallback([=](TConstVectorRef positions, TConstVectorRef normals) { + auto m = model.GetModel(); + g_Renderer->DrawModelFlat(*m, flags, unsortedOnly, positions, normals); + }); } } -void CModelData::InvSuitDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, - const zeus::CColor& alphaColor, const zeus::CColor& additiveColor) { +void CModelData::MultiLightingDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, + const zeus::CColor& alphaColor, const zeus::CColor& additiveColor) { + CModel* model = nullptr; + const auto callback = [&](auto positions, auto normals) { + CGraphics::DisableAllLights(); + constexpr CModelFlags flags1{5, 0, 3, zeus::CColor{1.f, 0.f}}; + const CModelFlags flags2{5, 0, 1, alphaColor}; + const CModelFlags flags3{7, 0, 1, additiveColor}; + if (positions == nullptr) { + model->Draw(flags1); + if (lights != nullptr) { + lights->ActivateLights(); + } + model->Draw(flags2); + model->Draw(flags3); + } else { + model->Draw(positions, normals, flags1); + if (lights != nullptr) { + lights->ActivateLights(); + } + model->Draw(positions, normals, flags2); + model->Draw(positions, normals, flags3); + } + }; CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); if (x10_animData) { - CSkinnedModel& model = PickAnimatedModel(which); - model.GetModelInst()->DisableAllLights(); - CModelFlags flags = {}; - - /* Z-prime */ - flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly; - flags.x4_color = zeus::skWhite; - x10_animData->Render(model, flags, std::nullopt, nullptr); - - /* Normal Blended */ - lights->ActivateLights(*model.GetModelInst()); - flags.m_extendedShader = EExtendedShader::ForcedAlpha; - flags.x4_color = alphaColor; - x10_animData->Render(model, flags, std::nullopt, nullptr); - - /* Selection Additive */ - flags.m_extendedShader = EExtendedShader::ForcedAdditive; - flags.x4_color = additiveColor; - x10_animData->Render(model, flags, std::nullopt, nullptr); + auto& skinnedModel = PickAnimatedModel(which); + x10_animData->SetupRender(skinnedModel, nullptr, nullptr); + model = skinnedModel.GetModel().GetObj(); + skinnedModel.DoDrawCallback(callback); } else { - CBooModel& model = *PickStaticModel(which); - model.DisableAllLights(); - CModelFlags flags = {}; - - /* Z-prime */ - flags.m_extendedShader = EExtendedShader::SolidColorBackfaceCullLEqualAlphaOnly; - flags.x4_color = zeus::skWhite; - model.Draw(flags, nullptr, nullptr); - - /* Normal Blended */ - lights->ActivateLights(model); - flags.m_extendedShader = EExtendedShader::ForcedAlpha; - flags.x4_color = alphaColor; - model.Draw(flags, nullptr, nullptr); - - /* Selection Additive */ - flags.m_extendedShader = EExtendedShader::ForcedAdditive; - flags.x4_color = additiveColor; - model.Draw(flags, nullptr, nullptr); + model = PickStaticModel(which).GetObj(); + callback(nullptr, nullptr); } } -void CModelData::DisintegrateDraw(const CStateManager& mgr, const zeus::CTransform& xf, const CTexture& tex, +void CModelData::MultiPassDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, + const CModelFlags* flags, u32 count) { + CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); + if (lights == nullptr) { + CGraphics::DisableAllLights(); + g_Renderer->SetAmbientColor(x18_ambientColor); + } else { + lights->ActivateLights(); + } + if (x10_animData) { + auto& skinnedModel = PickAnimatedModel(which); + x10_animData->SetupRender(skinnedModel, nullptr, nullptr); + auto& model = *skinnedModel.GetModel(); + skinnedModel.DoDrawCallback([&](auto positions, auto normals) { + for (int i = 0; i < count; ++i) { + model.Draw(positions, normals, flags[i]); + } + }); + } else { + auto& model = *PickStaticModel(which); + for (int i = 0; i < count; ++i) { + model.Draw(flags[i]); + } + } +} + +void CModelData::DisintegrateDraw(const CStateManager& mgr, const zeus::CTransform& xf, CTexture& tex, const zeus::CColor& addColor, float t) { DisintegrateDraw(GetRenderingModel(mgr), xf, tex, addColor, t); } -void CModelData::DisintegrateDraw(EWhichModel which, const zeus::CTransform& xf, const CTexture& tex, +void CModelData::DisintegrateDraw(EWhichModel which, const zeus::CTransform& xf, CTexture& tex, const zeus::CColor& addColor, float t) { zeus::CTransform scaledXf = xf * zeus::CTransform::Scale(x0_scale); CGraphics::SetModelMatrix(scaledXf); - - CBooModel::SetDisintegrateTexture(tex.GetBooTexture()); - CModelFlags flags(5, 0, 3, zeus::skWhite); - flags.m_extendedShader = EExtendedShader::Disintegrate; - flags.addColor = addColor; - flags.addColor.a() = t; // Stash T value in here (shader does not care) - + CGraphics::DisableAllLights(); + const auto aabb = GetBounds(scaledXf); if (x10_animData) { - CSkinnedModel& sModel = PickAnimatedModel(which); - x10_animData->Render(sModel, flags, std::nullopt, nullptr); + auto& model = PickAnimatedModel(which); + x10_animData->SetupRender(model, nullptr, nullptr); + model.DoDrawCallback([&](auto positions, auto normals) { + g_Renderer->DrawModelDisintegrate(*model.GetModel(), tex, addColor, positions, normals, t); + }); } else { - CBooModel& model = *PickStaticModel(which); - model.Draw(flags, nullptr, nullptr); + g_Renderer->DrawModelDisintegrate(*PickStaticModel(which), tex, addColor, nullptr, nullptr, t); } } +void CModelData::ThermalDraw(CSkinnedModel& model, const zeus::CColor& mulColor, const zeus::CColor& addColor, + const CModelFlags& flags) { + model.DoDrawCallback([&](auto positions, auto normals) { + g_Renderer->DrawThermalModel(*model.GetModel(), mulColor, addColor, positions, normals, flags); + }); +} + +void CModelData::ThermalDraw(CSkinnedModel& model, TConstVectorRef positions, TConstVectorRef normals, + const zeus::CColor& mulColor, const zeus::CColor& addColor, const CModelFlags& flags) { + g_Renderer->DrawThermalModel(*model.GetModel(), mulColor, addColor, positions, normals, flags); +} + } // namespace metaforce diff --git a/Runtime/Character/CModelData.hpp b/Runtime/Character/CModelData.hpp index 19b6dadcf..75e2c34b2 100644 --- a/Runtime/Character/CModelData.hpp +++ b/Runtime/Character/CModelData.hpp @@ -23,7 +23,7 @@ struct CModelFlags; struct SAdvancementDeltas; class CStaticRes { - CAssetId x0_cmdlId = 0; + CAssetId x0_cmdlId; zeus::CVector3f x4_scale; public: @@ -60,7 +60,6 @@ public: class CModelData { friend class CActor; zeus::CVector3f x0_scale; - bool xc_ = false; std::unique_ptr x10_animData; bool x14_24_renderSorted : 1 = false; bool x14_25_sortThermal : 1 = false; @@ -71,12 +70,6 @@ class CModelData { TLockedToken x2c_xrayModel; TLockedToken x3c_infraModel; - std::unique_ptr m_normalModelInst; - std::unique_ptr m_xrayModelInst; - std::unique_ptr m_infraModelInst; - - int m_drawInstCount = 0; - public: enum class EWhichModel { Normal, XRay, Thermal, ThermalHot }; @@ -84,20 +77,21 @@ public: bool GetSortThermal() const { return x14_25_sortThermal; } ~CModelData(); - explicit CModelData(const CStaticRes& res, int instCount = 1); - explicit CModelData(const CAnimRes& res, int instCount = 1); + explicit CModelData(const CStaticRes& res); + explicit CModelData(const CAnimRes& res); CModelData(CModelData&&) = default; CModelData& operator=(CModelData&&) = default; CModelData(); static CModelData CModelDataNull(); SAdvancementDeltas GetAdvancementDeltas(const CCharAnimTime& a, const CCharAnimTime& b) const; - void Render(const CStateManager& stateMgr, const zeus::CTransform& xf, const CActorLights* lights, - const CModelFlags& drawFlags); - bool IsLoaded(int shaderIdx) const; + bool IsLoaded(int shaderIdx); static EWhichModel GetRenderingModel(const CStateManager& stateMgr); CSkinnedModel& PickAnimatedModel(EWhichModel which) const; - const std::unique_ptr& PickStaticModel(EWhichModel which) const; + TLockedToken& PickStaticModel(EWhichModel which); + const TLockedToken& PickStaticModel(EWhichModel which) const { + return const_cast(this)->PickStaticModel(which); + } void SetXRayModel(const std::pair& modelSkin); void SetInfraModel(const std::pair& modelSkin); bool IsDefinitelyOpaque(EWhichModel) const; @@ -116,21 +110,29 @@ public: bool IsAnimating() const; bool IsInFrustum(const zeus::CTransform& xf, const zeus::CFrustum& frustum) const; void RenderParticles(const zeus::CFrustum& frustum) const; - void Touch(EWhichModel, int shaderIdx) const; - void Touch(const CStateManager& stateMgr, int shaderIdx) const; - void RenderThermal(const zeus::CColor& mulColor, const zeus::CColor& addColor, const CModelFlags& flags) const; + void Touch(EWhichModel, int shaderIdx); + void Touch(const CStateManager& stateMgr, int shaderIdx); void RenderThermal(const zeus::CTransform& xf, const zeus::CColor& mulColor, const zeus::CColor& addColor, - const CModelFlags& flags) const; + const CModelFlags& flags); void RenderUnsortedParts(EWhichModel, const zeus::CTransform& xf, const CActorLights* lights, const CModelFlags& drawFlags); + void Render(const CStateManager& stateMgr, const zeus::CTransform& xf, const CActorLights* lights, + const CModelFlags& drawFlags); void Render(EWhichModel, const zeus::CTransform& xf, const CActorLights* lights, const CModelFlags& drawFlags); + void FlatDraw(EWhichModel which, const zeus::CTransform& xf, bool unsortedOnly, const CModelFlags& flags); - void InvSuitDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, - const zeus::CColor& color0, const zeus::CColor& color1); - void DisintegrateDraw(const CStateManager& mgr, const zeus::CTransform& xf, const CTexture& tex, - const zeus::CColor& addColor, float t); - void DisintegrateDraw(EWhichModel which, const zeus::CTransform& xf, const CTexture& tex, + void MultiLightingDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, + const zeus::CColor& alphaColor, const zeus::CColor& additiveColor); + void MultiPassDraw(EWhichModel which, const zeus::CTransform& xf, const CActorLights* lights, + const CModelFlags* flags, u32 count); + void DisintegrateDraw(const CStateManager& mgr, const zeus::CTransform& xf, CTexture& tex, const zeus::CColor& addColor, float t); + void DisintegrateDraw(EWhichModel which, const zeus::CTransform& xf, CTexture& tex, const zeus::CColor& addColor, + float t); + static void ThermalDraw(CSkinnedModel& model, const zeus::CColor& mulColor, const zeus::CColor& addColor, + const CModelFlags& flags); + static void ThermalDraw(CSkinnedModel& model, TConstVectorRef positions, TConstVectorRef normals, + const zeus::CColor& mulColor, const zeus::CColor& addColor, const CModelFlags& flags); CAnimData* GetAnimationData() { return x10_animData.get(); } const CAnimData* GetAnimationData() const { return x10_animData.get(); } diff --git a/Runtime/Character/CPASAnimInfo.hpp b/Runtime/Character/CPASAnimInfo.hpp index bcf3f17fd..ff10e4edd 100644 --- a/Runtime/Character/CPASAnimInfo.hpp +++ b/Runtime/Character/CPASAnimInfo.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Character/CPASAnimParm.hpp" diff --git a/Runtime/Character/CPASAnimState.cpp b/Runtime/Character/CPASAnimState.cpp index 1c02ffd78..8781f94e2 100644 --- a/Runtime/Character/CPASAnimState.cpp +++ b/Runtime/Character/CPASAnimState.cpp @@ -14,9 +14,9 @@ namespace metaforce { CPASAnimState::CPASAnimState(CInputStream& in) { - x0_id = static_cast(in.readUint32Big()); - u32 parmCount = in.readUint32Big(); - u32 animCount = in.readUint32Big(); + x0_id = static_cast(in.ReadLong()); + u32 parmCount = in.ReadLong(); + u32 animCount = in.ReadLong(); x4_parms.reserve(parmCount); x14_anims.reserve(animCount); @@ -26,25 +26,25 @@ CPASAnimState::CPASAnimState(CInputStream& in) { x4_parms.emplace_back(in); for (u32 i = 0; i < animCount; ++i) { - s32 id = in.readUint32Big(); + s32 id = in.ReadLong(); rstl::reserved_vector parms; for (const CPASParmInfo& parm : x4_parms) { CPASAnimParm::UParmValue val = {}; switch (parm.GetParameterType()) { case CPASAnimParm::EParmType::Int32: - val.m_int = in.readInt32Big(); + val.m_int = in.ReadInt32(); break; case CPASAnimParm::EParmType::UInt32: - val.m_uint = in.readUint32Big(); + val.m_uint = in.ReadLong(); break; case CPASAnimParm::EParmType::Float: - val.m_float = in.readFloatBig(); + val.m_float = in.ReadFloat(); break; case CPASAnimParm::EParmType::Bool: - val.m_bool = in.readBool(); + val.m_bool = in.ReadBool(); break; case CPASAnimParm::EParmType::Enum: - val.m_int = in.readInt32Big(); + val.m_int = in.ReadInt32(); break; default: break; diff --git a/Runtime/Character/CPASAnimState.hpp b/Runtime/Character/CPASAnimState.hpp index 98c258acc..c32329f14 100644 --- a/Runtime/Character/CPASAnimState.hpp +++ b/Runtime/Character/CPASAnimState.hpp @@ -3,7 +3,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CharacterCommon.hpp" #include "Runtime/Character/CPASAnimInfo.hpp" #include "Runtime/Character/CPASParmInfo.hpp" diff --git a/Runtime/Character/CPASDatabase.cpp b/Runtime/Character/CPASDatabase.cpp index d6d922684..d661116e0 100644 --- a/Runtime/Character/CPASDatabase.cpp +++ b/Runtime/Character/CPASDatabase.cpp @@ -17,9 +17,9 @@ void CPASDatabase::AddAnimState(CPASAnimState&& state) { } CPASDatabase::CPASDatabase(CInputStream& in) { - in.readUint32Big(); - u32 animStateCount = in.readUint32Big(); - u32 defaultState = in.readUint32Big(); + in.ReadLong(); + u32 animStateCount = in.ReadLong(); + u32 defaultState = in.ReadLong(); x0_states.reserve(animStateCount); for (u32 i = 0; i < animStateCount; ++i) { diff --git a/Runtime/Character/CPASDatabase.hpp b/Runtime/Character/CPASDatabase.hpp index ddd7d786d..377de5fab 100644 --- a/Runtime/Character/CPASDatabase.hpp +++ b/Runtime/Character/CPASDatabase.hpp @@ -4,7 +4,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CPASAnimState.hpp" namespace metaforce { diff --git a/Runtime/Character/CPASParmInfo.cpp b/Runtime/Character/CPASParmInfo.cpp index 80920c0b4..919f1ff5f 100644 --- a/Runtime/Character/CPASParmInfo.cpp +++ b/Runtime/Character/CPASParmInfo.cpp @@ -2,33 +2,33 @@ namespace metaforce { -CPASParmInfo::CPASParmInfo(CInputStream& in) { +CPASParmInfo::CPASParmInfo(CInputStream& in) +: x0_type(CPASAnimParm::EParmType(in.ReadLong())), x4_weightFunction(EWeightFunction(in.ReadLong())) { xc_min.m_int = 0; x10_max.m_int = 0; - x0_type = CPASAnimParm::EParmType(in.readUint32Big()); - x4_weightFunction = EWeightFunction(in.readUint32Big()); - x8_weight = in.readFloatBig(); + + x8_weight = in.ReadFloat(); switch (x0_type) { case CPASAnimParm::EParmType::Int32: - xc_min.m_int = in.readInt32Big(); - x10_max.m_int = in.readInt32Big(); + xc_min.m_int = in.ReadInt32(); + x10_max.m_int = in.ReadInt32(); break; case CPASAnimParm::EParmType::UInt32: - xc_min.m_uint = in.readUint32Big(); - x10_max.m_uint = in.readUint32Big(); + xc_min.m_uint = in.ReadLong(); + x10_max.m_uint = in.ReadLong(); break; case CPASAnimParm::EParmType::Float: - xc_min.m_float = in.readFloatBig(); - x10_max.m_float = in.readFloatBig(); + xc_min.m_float = in.ReadFloat(); + x10_max.m_float = in.ReadFloat(); break; case CPASAnimParm::EParmType::Bool: - xc_min.m_bool = in.readBool(); - x10_max.m_bool = in.readBool(); + xc_min.m_bool = in.ReadBool(); + x10_max.m_bool = in.ReadBool(); break; case CPASAnimParm::EParmType::Enum: - xc_min.m_int = in.readInt32Big(); - x10_max.m_int = in.readInt32Big(); + xc_min.m_int = in.ReadInt32(); + x10_max.m_int = in.ReadInt32(); break; default: break; diff --git a/Runtime/Character/CPASParmInfo.hpp b/Runtime/Character/CPASParmInfo.hpp index 6b10b5dd0..2254be364 100644 --- a/Runtime/Character/CPASParmInfo.hpp +++ b/Runtime/Character/CPASParmInfo.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CPASAnimParm.hpp" namespace metaforce { diff --git a/Runtime/Character/CPOINode.cpp b/Runtime/Character/CPOINode.cpp index 9e3ece784..911c1c107 100644 --- a/Runtime/Character/CPOINode.cpp +++ b/Runtime/Character/CPOINode.cpp @@ -21,15 +21,15 @@ CPOINode::CPOINode(std::string_view name, EPOIType type, const CCharAnimTime& ti , x34_flags(f) {} CPOINode::CPOINode(CInputStream& in) -: x4_(in.readUint16Big()) -, x8_name(in.readString()) -, x18_type(EPOIType(in.readUint16Big())) +: x4_(in.ReadShort()) +, x8_name(in.Get()) +, x18_type(EPOIType(in.ReadShort())) , x1c_time(in) -, x24_index(in.readInt32Big()) -, x28_unique(in.readBool()) -, x2c_weight(in.readFloatBig()) -, x30_charIdx(in.readInt32Big()) -, x34_flags(in.readInt32Big()) {} +, x24_index(in.ReadInt32()) +, x28_unique(in.ReadBool()) +, x2c_weight(in.ReadFloat()) +, x30_charIdx(in.ReadInt32()) +, x34_flags(in.ReadInt32()) {} bool CPOINode::operator>(const CPOINode& other) const { return x1c_time > other.x1c_time; } diff --git a/Runtime/Character/CPOINode.hpp b/Runtime/Character/CPOINode.hpp index c7e2bdbff..1ff7dd796 100644 --- a/Runtime/Character/CPOINode.hpp +++ b/Runtime/Character/CPOINode.hpp @@ -3,7 +3,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CCharAnimTime.hpp" namespace metaforce { diff --git a/Runtime/Character/CParticleData.cpp b/Runtime/Character/CParticleData.cpp index c54b8bc26..3b0b11905 100644 --- a/Runtime/Character/CParticleData.cpp +++ b/Runtime/Character/CParticleData.cpp @@ -3,10 +3,10 @@ namespace metaforce { CParticleData::CParticleData(CInputStream& in) -: x0_duration(in.readUint32Big()) +: x0_duration(in.ReadLong()) , x4_particle(in) -, xc_boneName(in.readString()) -, x1c_scale(in.readFloatBig()) -, x20_parentMode(EParentedMode(in.readUint32Big())) {} +, xc_boneName(in.Get()) +, x1c_scale(in.ReadFloat()) +, x20_parentMode(EParentedMode(in.ReadLong())) {} } // namespace metaforce diff --git a/Runtime/Character/CParticleData.hpp b/Runtime/Character/CParticleData.hpp index 80f14dbd7..c74836b2e 100644 --- a/Runtime/Character/CParticleData.hpp +++ b/Runtime/Character/CParticleData.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" #include diff --git a/Runtime/Character/CParticleDatabase.cpp b/Runtime/Character/CParticleDatabase.cpp index 8e3d02146..75f8f08ad 100644 --- a/Runtime/Character/CParticleDatabase.cpp +++ b/Runtime/Character/CParticleDatabase.cpp @@ -99,7 +99,7 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p switch (info.GetParentedMode()) { case CParticleData::EParentedMode::Initial: { if (info.GetIsGrabInitialData()) { - zeus::CTransform segXf((info.GetFlags() & 0x10) ? zeus::CMatrix3f() : pose.GetTransformMinusOffset(segId), + zeus::CTransform segXf((info.GetFlags() & 0x10) ? zeus::CMatrix3f() : pose.GetRotation(segId), off * scale); zeus::CTransform compXf = xf * segXf; info.SetCurTransform(compXf.getRotation()); @@ -125,7 +125,7 @@ void CParticleDatabase::UpdateParticleGenDB(float dt, const CPoseAsTransforms& p info.SetIsGrabInitialData(false); } - zeus::CTransform segXf(pose.GetTransformMinusOffset(segId), off * scale); + zeus::CTransform segXf(pose.GetRotation(segId), off * scale); zeus::CTransform compXf = xf * segXf; if (info.GetParentedMode() == CParticleData::EParentedMode::ContinuousEmitter) { diff --git a/Runtime/Character/CParticleGenInfo.cpp b/Runtime/Character/CParticleGenInfo.cpp index a76fcfba2..b83d3967e 100644 --- a/Runtime/Character/CParticleGenInfo.cpp +++ b/Runtime/Character/CParticleGenInfo.cpp @@ -2,7 +2,7 @@ #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/IRenderer.hpp" #include "Runtime/Particle/CParticleGen.hpp" #include "Runtime/World/CGameLight.hpp" diff --git a/Runtime/Character/CPoseAsTransforms.cpp b/Runtime/Character/CPoseAsTransforms.cpp index 1631476e2..584668f16 100644 --- a/Runtime/Character/CPoseAsTransforms.cpp +++ b/Runtime/Character/CPoseAsTransforms.cpp @@ -4,7 +4,8 @@ namespace metaforce { -CPoseAsTransforms::CPoseAsTransforms(u8 boneCount) : x1_count(boneCount), xd0_transformArr(new Transform[boneCount]) {} +CPoseAsTransforms::CPoseAsTransforms(u8 boneCount) +: x1_count(boneCount), xd0_transformArr(std::make_unique(boneCount)) {} bool CPoseAsTransforms::ContainsDataFor(const CSegId& id) const { const std::pair& link = x8_links[id]; @@ -24,32 +25,23 @@ void CPoseAsTransforms::AccumulateScaledTransform(const CSegId& id, zeus::CMatri const zeus::CTransform& CPoseAsTransforms::GetTransform(const CSegId& id) const { const std::pair& link = x8_links[id]; assert(link.second.IsValid()); - return xd0_transformArr[link.second].m_originToAccum; -} - -const zeus::CTransform& CPoseAsTransforms::GetRestToAccumTransform(const CSegId& id) const { - const std::pair& link = x8_links[id]; - assert(link.second.IsValid()); - return xd0_transformArr[link.second].m_restPoseToAccum; + return xd0_transformArr[link.second]; } const zeus::CVector3f& CPoseAsTransforms::GetOffset(const CSegId& id) const { const std::pair& link = x8_links[id]; assert(link.second.IsValid()); - return xd0_transformArr[link.second].m_originToAccum.origin; + return xd0_transformArr[link.second].origin; } const zeus::CMatrix3f& CPoseAsTransforms::GetRotation(const CSegId& id) const { const std::pair& link = x8_links[id]; assert(link.second.IsValid()); - return xd0_transformArr[link.second].m_originToAccum.basis; + return xd0_transformArr[link.second].basis; } -void CPoseAsTransforms::Insert(const CSegId& id, const zeus::CMatrix3f& rotation, const zeus::CVector3f& offset, - const zeus::CVector3f& restOffset) { - Transform& xfOut = xd0_transformArr[x0_nextId]; - xfOut.m_originToAccum = zeus::CTransform(rotation, offset); - xfOut.m_restPoseToAccum = xfOut.m_originToAccum * zeus::CTransform::Translate(-restOffset); +void CPoseAsTransforms::Insert(const CSegId& id, const zeus::CMatrix3f& rotation, const zeus::CVector3f& offset) { + xd0_transformArr[x0_nextId] = zeus::CTransform(rotation, offset); std::pair& link = x8_links[id]; link.first = xd4_lastInserted; @@ -58,4 +50,10 @@ void CPoseAsTransforms::Insert(const CSegId& id, const zeus::CMatrix3f& rotation ++x0_nextId; } +CSegId CPoseAsTransforms::GetParent(const CSegId& id) const { + const std::pair& link = x8_links[id]; + assert(link.first.IsValid()); + return link.first; +} + } // namespace metaforce diff --git a/Runtime/Character/CPoseAsTransforms.hpp b/Runtime/Character/CPoseAsTransforms.hpp index 96ebd13d2..45947fc0e 100644 --- a/Runtime/Character/CPoseAsTransforms.hpp +++ b/Runtime/Character/CPoseAsTransforms.hpp @@ -4,9 +4,9 @@ #include #include -#include "Runtime/RetroTypes.hpp" #include "Runtime/Character/CCharLayoutInfo.hpp" #include "Runtime/Character/CSegId.hpp" +#include "Runtime/RetroTypes.hpp" #include #include @@ -16,31 +16,26 @@ namespace metaforce { class CPoseAsTransforms { friend class CAnimData; -public: - struct Transform { - zeus::CTransform m_originToAccum; - zeus::CTransform m_restPoseToAccum; - }; - private: CSegId x0_nextId = 0; CSegId x1_count; std::array, 100> x8_links; - std::unique_ptr xd0_transformArr; + std::unique_ptr xd0_transformArr; CSegId xd4_lastInserted = 0; public: explicit CPoseAsTransforms(u8 boneCount); - bool ContainsDataFor(const CSegId& id) const; + void Clear(); void AccumulateScaledTransform(const CSegId& id, zeus::CMatrix3f& rotation, float scale) const; - const zeus::CTransform& GetTransform(const CSegId& id) const; - const zeus::CTransform& GetRestToAccumTransform(const CSegId& id) const; - const zeus::CVector3f& GetOffset(const CSegId& id) const; - const zeus::CMatrix3f& GetRotation(const CSegId& id) const; - const zeus::CMatrix3f& GetTransformMinusOffset(const CSegId& id) const { return GetRotation(id); } - void Insert(const CSegId& id, const zeus::CMatrix3f& rotation, const zeus::CVector3f& offset, - const zeus::CVector3f& restOffset); + void Insert(const CSegId& id, const zeus::CMatrix3f& rotation, const zeus::CVector3f& offset); + + [[nodiscard]] bool ContainsDataFor(const CSegId& id) const; + [[nodiscard]] const zeus::CTransform& GetTransform(const CSegId& id) const; + [[nodiscard]] const zeus::CVector3f& GetOffset(const CSegId& id) const; + [[nodiscard]] const zeus::CMatrix3f& GetRotation(const CSegId& id) const; + [[nodiscard]] CSegId GetLastInserted() const { return xd4_lastInserted; } + [[nodiscard]] CSegId GetParent(const CSegId& id) const; }; } // namespace metaforce diff --git a/Runtime/Character/CPrimitive.cpp b/Runtime/Character/CPrimitive.cpp index 3857528c0..8963e19f4 100644 --- a/Runtime/Character/CPrimitive.cpp +++ b/Runtime/Character/CPrimitive.cpp @@ -3,9 +3,9 @@ namespace metaforce { CPrimitive::CPrimitive(CInputStream& in) { - x0_animId = in.readUint32Big(); - x4_animIdx = in.readUint32Big(); - x8_animName = in.readString(); + x0_animId = in.Get(); + x4_animIdx = in.ReadLong(); + x8_animName = in.Get(); } } // namespace metaforce diff --git a/Runtime/Character/CPrimitive.hpp b/Runtime/Character/CPrimitive.hpp index 0fcf01c49..4ea7eefda 100644 --- a/Runtime/Character/CPrimitive.hpp +++ b/Runtime/Character/CPrimitive.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" namespace metaforce { diff --git a/Runtime/Character/CSegId.hpp b/Runtime/Character/CSegId.hpp index 3bcaa78d2..2721df78d 100644 --- a/Runtime/Character/CSegId.hpp +++ b/Runtime/Character/CSegId.hpp @@ -1,6 +1,6 @@ #pragma once -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/RetroTypes.hpp" namespace metaforce { @@ -11,7 +11,7 @@ class CSegId { public: constexpr CSegId() noexcept = default; constexpr CSegId(u8 id) noexcept : x0_segId(id) {} - explicit CSegId(CInputStream& in) : x0_segId(in.readUint32Big()) {} + explicit CSegId(CInputStream& in) : x0_segId(in.ReadLong()) {} constexpr CSegId& operator++() noexcept { ++x0_segId; return *this; diff --git a/Runtime/Character/CSegIdList.cpp b/Runtime/Character/CSegIdList.cpp index aecb44d48..9ece5f11d 100644 --- a/Runtime/Character/CSegIdList.cpp +++ b/Runtime/Character/CSegIdList.cpp @@ -3,7 +3,7 @@ namespace metaforce { CSegIdList::CSegIdList(CInputStream& in) { - u32 count = in.readUint32Big(); + u32 count = in.ReadLong(); x0_list.reserve(count); for (u32 i = 0; i < count; ++i) x0_list.emplace_back(in); diff --git a/Runtime/Character/CSegIdList.hpp b/Runtime/Character/CSegIdList.hpp index 8ff76daa3..079973e6d 100644 --- a/Runtime/Character/CSegIdList.hpp +++ b/Runtime/Character/CSegIdList.hpp @@ -2,7 +2,7 @@ #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CSegId.hpp" namespace metaforce { diff --git a/Runtime/Character/CSkinBank.cpp b/Runtime/Character/CSkinBank.cpp deleted file mode 100644 index 487a58875..000000000 --- a/Runtime/Character/CSkinBank.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "Runtime/Character/CSkinBank.hpp" - -#include "Runtime/Character/CPoseAsTransforms.hpp" - -namespace metaforce { - -CSkinBank::CSkinBank(CInputStream& in) { - u32 boneCount = in.readUint32Big(); - x0_segments.reserve(boneCount); - for (u32 i = 0; i < boneCount; ++i) - x0_segments.emplace_back(in); -} - -void CSkinBank::GetBankTransforms(std::vector& out, const CPoseAsTransforms& pose) const { - for (CSegId id : x0_segments) { - const zeus::CTransform& xf = pose.GetRestToAccumTransform(id); - out.push_back(&xf); - } -} - -} // namespace metaforce diff --git a/Runtime/Character/CSkinBank.hpp b/Runtime/Character/CSkinBank.hpp deleted file mode 100644 index 843a12c1e..000000000 --- a/Runtime/Character/CSkinBank.hpp +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -#include "Runtime/IOStreams.hpp" -#include "Runtime/Character/CSegId.hpp" - -namespace metaforce { -class CPoseAsTransforms; - -class CSkinBank { - std::vector x0_segments; - -public: - explicit CSkinBank(CInputStream& in); - void GetBankTransforms(std::vector& out, const CPoseAsTransforms& pose) const; -}; - -} // namespace metaforce diff --git a/Runtime/Character/CSkinRules.cpp b/Runtime/Character/CSkinRules.cpp index 8ce0ca4c9..41022a0d4 100644 --- a/Runtime/Character/CSkinRules.cpp +++ b/Runtime/Character/CSkinRules.cpp @@ -6,39 +6,63 @@ namespace metaforce { -CSkinRules::CSkinRules(CInputStream& in) { - u32 bankCount = in.readUint32Big(); - x0_skinBanks.reserve(bankCount); - for (u32 i = 0; i < bankCount; ++i) - x0_skinBanks.emplace_back(in); - - u32 virtualBoneCount = in.readUint32Big(); - m_virtualBones.reserve(virtualBoneCount); - for (u32 i = 0; i < virtualBoneCount; ++i) - m_virtualBones.emplace_back(in); - - u32 poolSz = in.readUint32Big(); - m_poolToSkinIdx.reserve(poolSz); - for (u32 i = 0; i < poolSz; ++i) - m_poolToSkinIdx.push_back(in.readUint32Big()); +static u32 ReadCount(CInputStream& in) { + s32 result = in.ReadLong(); + if (result == -1) { + return in.ReadLong(); + } + u8 junk[784]; + u32 iVar2 = 0; + for (u32 i = 0; i < (result * 3); i += iVar2) { + iVar2 = ((result * 3) - i); + iVar2 = 192 < iVar2 ? 192 : iVar2; + in.Get(junk, iVar2 * 4); + } + return result; } -void CSkinRules::TransformVerticesCPU(std::vector>& vnOut, - const CPoseAsTransforms& pose, const CModel& model) const { - OPTICK_EVENT(); - vnOut.resize(m_poolToSkinIdx.size()); - for (size_t i = 0; i < m_poolToSkinIdx.size(); ++i) { - const CVirtualBone& vb = m_virtualBones[m_poolToSkinIdx[i]]; - zeus::CVector3f origVertex = model.GetPoolVertex(i); - zeus::CVector3f vertex; - zeus::CVector3f origNormal = model.GetPoolNormal(i); - zeus::CVector3f normal; - for (const SSkinWeighting& w : vb.GetWeights()) { - const zeus::CTransform& xf = pose.GetRestToAccumTransform(w.m_id); - vertex += (xf * origVertex) * w.m_weight; - normal += (xf.basis.inverted().transposed() * origNormal) * w.m_weight; +CSkinRules::CSkinRules(CInputStream& in) { + u32 weightCount = in.ReadLong(); + x0_bones.reserve(weightCount); + for (int i = 0; i < weightCount; ++i) { + x0_bones.emplace_back(in); + } + x10_vertexCount = ReadCount(in); + x14_normalCount = ReadCount(in); +} + +void CSkinRules::BuildAccumulatedTransforms(const CPoseAsTransforms& pose, const CCharLayoutInfo& info) { + std::array points; + CSegId segId = pose.GetLastInserted(); + while (segId != 0) { + zeus::CVector3f origin; + if (segId != 3) { // root ID + origin = info.GetFromRootUnrotated(segId); } - vnOut[i] = std::make_pair(vertex, normal.normalized()); + const auto rotatedOrigin = pose.GetRotation(segId) * origin; + points[segId] = pose.GetOffset(segId) - rotatedOrigin; + segId = pose.GetParent(segId); + } + for (auto& bone : x0_bones) { + bone.BuildAccumulatedTransform(pose, points.data()); + } +} + +void CSkinRules::BuildPoints(TConstVectorRef positions, TVectorRef out) { + size_t offset = 0; + for (auto& bone : x0_bones) { + u32 vertexCount = bone.GetVertexCount(); + bone.BuildPoints(positions->data() + offset, out, vertexCount); + offset += vertexCount; + } +} + +void CSkinRules::BuildNormals(TConstVectorRef normals, TVectorRef out) { + size_t offset = 0; + for (auto& bone : x0_bones) { + u32 vertexCount = bone.GetVertexCount(); + bone.BuildNormals(normals->data() + offset, out, vertexCount); + offset += vertexCount; } } @@ -47,4 +71,70 @@ CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, cons return TToken::GetIObjObjectFor(std::make_unique(in)); } +static inline auto StreamInSkinWeighting(CInputStream& in) { + rstl::reserved_vector weights; + u32 weightCount = in.ReadLong(); + for (int i = 0; i < std::min(3u, weightCount); ++i) { + weights.emplace_back(in); + } + for (int i = 3; i < weightCount; ++i) { + SSkinWeighting{in}; + } + return weights; +} + +CVirtualBone::CVirtualBone(CInputStream& in) : x0_weights(StreamInSkinWeighting(in)), x1c_vertexCount(in.ReadLong()) {} + +void CVirtualBone::BuildPoints(const zeus::CVector3f* in, TVectorRef out, u32 count) const { + for (u32 i = 0; i < count; ++i) { + out->emplace_back(x20_xf * in[i]); + } +} + +void CVirtualBone::BuildNormals(const zeus::CVector3f* in, TVectorRef out, u32 count) const { + for (u32 i = 0; i < count; ++i) { + out->emplace_back(x50_rotation * in[i]); + } +} + +void CVirtualBone::BuildAccumulatedTransform(const CPoseAsTransforms& pose, const zeus::CVector3f* points) { + BuildFinalPosMatrix(pose, points); + x50_rotation = pose.GetRotation(x0_weights[0].x0_id); +} + +static inline zeus::CMatrix3f WeightedMatrix(const zeus::CMatrix3f& m1, float w1, const zeus::CMatrix3f& m2, float w2) { + return { + m1[0] * w1 + m2[0] * w2, + m1[1] * w1 + m2[1] * w2, + m1[2] * w1 + m2[2] * w2, + }; +} + +static inline zeus::CVector3f WeightedVector(const zeus::CVector3f& v1, float w1, const zeus::CVector3f& v2, float w2) { + return v1 * w1 + v2 * w2; +} + +void CVirtualBone::BuildFinalPosMatrix(const CPoseAsTransforms& pose, const zeus::CVector3f* points) { + if (x0_weights.size() == 1) { + const auto id = x0_weights[0].x0_id; + x20_xf = {pose.GetRotation(id), points[id]}; + } else if (x0_weights.size() == 2) { + const auto w0 = x0_weights[0]; + const auto w1 = x0_weights[1]; + x20_xf = { + WeightedMatrix(pose.GetRotation(w0.x0_id), w0.x4_weight, pose.GetRotation(w1.x0_id), w1.x4_weight), + WeightedVector(points[w0.x0_id], w0.x4_weight, points[w1.x0_id], w1.x4_weight), + }; + } else if (x0_weights.size() == 3) { + const auto w0 = x0_weights[0]; + const auto w1 = x0_weights[1]; + const auto w2 = x0_weights[2]; + auto rot = WeightedMatrix(pose.GetRotation(w0.x0_id), w0.x4_weight, pose.GetRotation(w1.x0_id), w1.x4_weight); + auto pos = WeightedVector(points[w0.x0_id], w0.x4_weight, points[w1.x0_id], w1.x4_weight); + pose.AccumulateScaledTransform(w2.x0_id, rot, w2.x4_weight); + x20_xf = {rot, pos + points[w2.x0_id] * w2.x4_weight}; + } else { + x20_xf = {}; + } +} } // namespace metaforce diff --git a/Runtime/Character/CSkinRules.hpp b/Runtime/Character/CSkinRules.hpp index bdca237c8..8c728f645 100644 --- a/Runtime/Character/CSkinRules.hpp +++ b/Runtime/Character/CSkinRules.hpp @@ -3,57 +3,61 @@ #include #include "Runtime/CFactoryMgr.hpp" +#include "Runtime/Character/CSegId.hpp" +#include "Runtime/Graphics/CCubeModel.hpp" #include "Runtime/RetroTypes.hpp" -#include "Runtime/Character/CSkinBank.hpp" -#include #include namespace metaforce { +class CCharLayoutInfo; class CPoseAsTransforms; class CModel; struct SSkinWeighting { - CSegId m_id; - float m_weight; - explicit SSkinWeighting(CInputStream& in) : m_id(in), m_weight(in.readFloatBig()) {} + CSegId x0_id; + float x4_weight; + explicit SSkinWeighting(CInputStream& in) : x0_id(in), x4_weight(in.ReadFloat()) {} }; class CVirtualBone { - std::vector m_weights; + friend class CSkinnedModel; + + rstl::reserved_vector x0_weights; + u32 x1c_vertexCount; + zeus::CTransform x20_xf; + zeus::CMatrix3f x50_rotation; public: - explicit CVirtualBone(CInputStream& in) { - u32 weightCount = in.readUint32Big(); - m_weights.reserve(weightCount); - for (u32 i = 0; i < weightCount; ++i) - m_weights.emplace_back(in); - } + explicit CVirtualBone(CInputStream& in); - const std::vector& GetWeights() const { return m_weights; } + void BuildPoints(const zeus::CVector3f* in, TVectorRef out, u32 count) const; + void BuildNormals(const zeus::CVector3f* in, TVectorRef out, u32 count) const; + void BuildAccumulatedTransform(const CPoseAsTransforms& pose, const zeus::CVector3f* points); + + [[nodiscard]] const auto& GetWeights() const { return x0_weights; } + [[nodiscard]] u32 GetVertexCount() const { return x1c_vertexCount; } + +private: + void BuildFinalPosMatrix(const CPoseAsTransforms& pose, const zeus::CVector3f* points); }; class CSkinRules { - std::vector x0_skinBanks; - // u32 x10_vertexCount; - // u32 x14_normalCount; - std::vector m_virtualBones; - std::vector m_poolToSkinIdx; + friend class CSkinnedModel; + + std::vector x0_bones; + u32 x10_vertexCount = 0; + u32 x14_normalCount = 0; public: explicit CSkinRules(CInputStream& in); - void GetBankTransforms(std::vector& out, const CPoseAsTransforms& pose, - int skinBankIdx) const { - // FIXME: This is definitely not proper behavior, this is here to fix the phazon suit crashing - if (x0_skinBanks.size() <= skinBankIdx) { - return; - } - x0_skinBanks[skinBankIdx].GetBankTransforms(out, pose); - } + void BuildPoints(TConstVectorRef positions, TVectorRef out); + void BuildNormals(TConstVectorRef normals, TVectorRef out); + void BuildAccumulatedTransforms(const CPoseAsTransforms& pose, const CCharLayoutInfo& info); - void TransformVerticesCPU(std::vector>& vnOut, - const CPoseAsTransforms& pose, const CModel& model) const; + [[nodiscard]] u32 GetVertexCount() const { return x10_vertexCount; } + [[nodiscard]] u32 GetNormalCount() const { return x14_normalCount; } }; CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params, diff --git a/Runtime/Character/CSoundPOINode.cpp b/Runtime/Character/CSoundPOINode.cpp index 53a2b3c1f..3f65d7c4b 100644 --- a/Runtime/Character/CSoundPOINode.cpp +++ b/Runtime/Character/CSoundPOINode.cpp @@ -11,7 +11,7 @@ CSoundPOINode::CSoundPOINode() , x40_maxDist(0.f) {} CSoundPOINode::CSoundPOINode(CInputStream& in) -: CPOINode(in), x38_sfxId(in.readUint32Big()), x3c_falloff(in.readFloatBig()), x40_maxDist(in.readFloatBig()) {} +: CPOINode(in), x38_sfxId(in.ReadLong()), x3c_falloff(in.ReadFloat()), x40_maxDist(in.ReadFloat()) {} CSoundPOINode::CSoundPOINode(std::string_view name, EPOIType a, const CCharAnimTime& time, u32 b, bool c, float d, u32 e, u32 f, u32 sfxId, float falloff, float maxDist) diff --git a/Runtime/Character/CTransition.cpp b/Runtime/Character/CTransition.cpp index db98cd867..358fb1745 100644 --- a/Runtime/Character/CTransition.cpp +++ b/Runtime/Character/CTransition.cpp @@ -3,9 +3,9 @@ namespace metaforce { CTransition::CTransition(CInputStream& in) -: x0_id(in.readUint32Big()) -, x4_animA(in.readUint32Big()) -, x8_animB(in.readUint32Big()) +: x0_id(in.ReadLong()) +, x4_animA(in.ReadLong()) +, x8_animB(in.ReadLong()) , xc_trans(CMetaTransFactory::CreateMetaTrans(in)) {} } // namespace metaforce diff --git a/Runtime/Character/CTransition.hpp b/Runtime/Character/CTransition.hpp index 8a062f03f..c79209a1b 100644 --- a/Runtime/Character/CTransition.hpp +++ b/Runtime/Character/CTransition.hpp @@ -3,7 +3,7 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Character/CMetaTransFactory.hpp" namespace metaforce { diff --git a/Runtime/Collision/CAreaOctTree.cpp b/Runtime/Collision/CAreaOctTree.cpp index 045dd4081..b9d29297a 100644 --- a/Runtime/Collision/CAreaOctTree.cpp +++ b/Runtime/Collision/CAreaOctTree.cpp @@ -1,13 +1,14 @@ #include "Runtime/Collision/CAreaOctTree.hpp" +#include "Runtime/CBasics.hpp" #include "Runtime/Collision/CMaterialFilter.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include #include #include #include -#include #include namespace metaforce { @@ -478,27 +479,27 @@ CAreaOctTree::Node CAreaOctTree::Node::GetChild(int idx) const { void CAreaOctTree::SwapTreeNode(u8* ptr, Node::ETreeType type) { if (type == Node::ETreeType::Branch) { u16* typeBits = reinterpret_cast(ptr); - *typeBits = hecl::SBig(*typeBits); + *typeBits = CBasics::SwapBytes(*typeBits); u32* offsets = reinterpret_cast(ptr + 4); for (int i = 0; i < 8; ++i) { Node::ETreeType ctype = Node::ETreeType((*typeBits >> (2 * i)) & 0x3); - offsets[i] = hecl::SBig(offsets[i]); + offsets[i] = CBasics::SwapBytes(offsets[i]); SwapTreeNode(ptr + offsets[i] + 36, ctype); } } else if (type == Node::ETreeType::Leaf) { float* aabb = reinterpret_cast(ptr); - aabb[0] = hecl::SBig(aabb[0]); - aabb[1] = hecl::SBig(aabb[1]); - aabb[2] = hecl::SBig(aabb[2]); - aabb[3] = hecl::SBig(aabb[3]); - aabb[4] = hecl::SBig(aabb[4]); - aabb[5] = hecl::SBig(aabb[5]); + aabb[0] = CBasics::SwapBytes(aabb[0]); + aabb[1] = CBasics::SwapBytes(aabb[1]); + aabb[2] = CBasics::SwapBytes(aabb[2]); + aabb[3] = CBasics::SwapBytes(aabb[3]); + aabb[4] = CBasics::SwapBytes(aabb[4]); + aabb[5] = CBasics::SwapBytes(aabb[5]); u16* countIdxs = reinterpret_cast(ptr + 24); - *countIdxs = hecl::SBig(*countIdxs); + *countIdxs = CBasics::SwapBytes(*countIdxs); for (u16 i = 0; i < *countIdxs; ++i) - countIdxs[i + 1] = hecl::SBig(countIdxs[i + 1]); + countIdxs[i + 1] = CBasics::SwapBytes(countIdxs[i + 1]); } } @@ -524,62 +525,61 @@ CAreaOctTree::CAreaOctTree(const zeus::CAABox& aabb, Node::ETreeType treeType, c SwapTreeNode(const_cast(x20_treeBuf), treeType); for (u32 i = 0; i < matCount; ++i) - const_cast(x28_materials)[i] = hecl::SBig(x28_materials[i]); + const_cast(x28_materials)[i] = CBasics::SwapBytes(x28_materials[i]); for (u32 i = 0; i < edgeCount; ++i) const_cast(x3c_edges)[i].swapBig(); for (u32 i = 0; i < polyCount; ++i) - const_cast(x44_polyEdges)[i] = hecl::SBig(x44_polyEdges[i]); + const_cast(x44_polyEdges)[i] = CBasics::SwapBytes(x44_polyEdges[i]); for (u32 i = 0; i < vertCount * 3; ++i) - const_cast(x4c_verts)[i] = hecl::SBig(x4c_verts[i]); + const_cast(x4c_verts)[i] = CBasics::SwapBytes(x4c_verts[i]); } std::unique_ptr CAreaOctTree::MakeFromMemory(const u8* buf, unsigned int size) { - athena::io::MemoryReader r(buf + 8, size - 8); - r.readUint32Big(); - r.readUint32Big(); - zeus::CAABox aabb; - aabb.readBoundingBoxBig(r); - Node::ETreeType nodeType = Node::ETreeType(r.readUint32Big()); - u32 treeSize = r.readUint32Big(); - const u8* cur = reinterpret_cast(buf) + 8 + r.position(); + CMemoryInStream r(buf + 8, size - 8, CMemoryInStream::EOwnerShip::NotOwned); + r.ReadLong(); + r.ReadLong(); + zeus::CAABox aabb = r.Get(); + Node::ETreeType nodeType = Node::ETreeType(r.ReadLong()); + u32 treeSize = r.ReadLong(); + const u8* cur = reinterpret_cast(buf) + 8 + r.GetReadPosition(); const u8* treeBuf = cur; cur += treeSize; - u32 matCount = hecl::SBig(*reinterpret_cast(cur)); + u32 matCount = CBasics::SwapBytes(*reinterpret_cast(cur)); cur += 4; const u32* matBuf = reinterpret_cast(cur); cur += 4 * matCount; - u32 vertMatsCount = hecl::SBig(*reinterpret_cast(cur)); + u32 vertMatsCount = CBasics::SwapBytes(*reinterpret_cast(cur)); cur += 4; const u8* vertMatsBuf = cur; cur += vertMatsCount; - u32 edgeMatsCount = hecl::SBig(*reinterpret_cast(cur)); + u32 edgeMatsCount = CBasics::SwapBytes(*reinterpret_cast(cur)); cur += 4; const u8* edgeMatsBuf = cur; cur += edgeMatsCount; - u32 polyMatsCount = hecl::SBig(*reinterpret_cast(cur)); + u32 polyMatsCount = CBasics::SwapBytes(*reinterpret_cast(cur)); cur += 4; const u8* polyMatsBuf = cur; cur += polyMatsCount; - u32 edgeCount = hecl::SBig(*reinterpret_cast(cur)); + u32 edgeCount = CBasics::SwapBytes(*reinterpret_cast(cur)); cur += 4; const CCollisionEdge* edgeBuf = reinterpret_cast(cur); cur += edgeCount * sizeof(edgeCount); - u32 polyCount = hecl::SBig(*reinterpret_cast(cur)); + u32 polyCount = CBasics::SwapBytes(*reinterpret_cast(cur)); cur += 4; const u16* polyBuf = reinterpret_cast(cur); cur += polyCount * 2; - u32 vertCount = hecl::SBig(*reinterpret_cast(cur)); + u32 vertCount = CBasics::SwapBytes(*reinterpret_cast(cur)); cur += 4; const float* vertBuf = reinterpret_cast(cur); diff --git a/Runtime/Collision/CCollidableOBBTreeGroup.cpp b/Runtime/Collision/CCollidableOBBTreeGroup.cpp index fcedbe3c4..8d59ccc5b 100644 --- a/Runtime/Collision/CCollidableOBBTreeGroup.cpp +++ b/Runtime/Collision/CCollidableOBBTreeGroup.cpp @@ -11,7 +11,7 @@ namespace metaforce { constexpr CCollisionPrimitive::Type sType(CCollidableOBBTreeGroup::SetStaticTableIndex, "CCollidableOBBTreeGroup"); CCollidableOBBTreeGroupContainer::CCollidableOBBTreeGroupContainer(CInputStream& in) { - const u32 treeCount = in.readUint32Big(); + const u32 treeCount = in.ReadLong(); x0_trees.reserve(treeCount); for (u32 i = 0; i < treeCount; i++) { diff --git a/Runtime/Collision/CCollidableOBBTreeGroup.hpp b/Runtime/Collision/CCollidableOBBTreeGroup.hpp index 27e43045b..8b445d69f 100644 --- a/Runtime/Collision/CCollidableOBBTreeGroup.hpp +++ b/Runtime/Collision/CCollidableOBBTreeGroup.hpp @@ -4,7 +4,7 @@ #include #include "Runtime/CFactoryMgr.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Collision/COBBTree.hpp" #include "Runtime/Collision/CCollisionPrimitive.hpp" diff --git a/Runtime/Collision/CCollisionEdge.cpp b/Runtime/Collision/CCollisionEdge.cpp index d7733136b..aa107b558 100644 --- a/Runtime/Collision/CCollisionEdge.cpp +++ b/Runtime/Collision/CCollisionEdge.cpp @@ -1,8 +1,9 @@ #include "Runtime/Collision/CCollisionEdge.hpp" +#include "Runtime/Streams/CInputStream.hpp" namespace metaforce { CCollisionEdge::CCollisionEdge(CInputStream& in) { - x0_index1 = in.readUint16Big(); - x2_index2 = in.readUint16Big(); + x0_index1 = in.ReadShort(); + x2_index2 = in.ReadShort(); } } // namespace metaforce diff --git a/Runtime/Collision/CCollisionEdge.hpp b/Runtime/Collision/CCollisionEdge.hpp index 10d9e90e3..8735fe009 100644 --- a/Runtime/Collision/CCollisionEdge.hpp +++ b/Runtime/Collision/CCollisionEdge.hpp @@ -16,8 +16,8 @@ public: [[nodiscard]] constexpr u16 GetVertIndex2() const noexcept { return x2_index2; } constexpr void swapBig() noexcept { - x0_index1 = hecl::SBig(x0_index1); - x2_index2 = hecl::SBig(x2_index2); + x0_index1 = SBig(x0_index1); + x2_index2 = SBig(x2_index2); } }; } // namespace metaforce diff --git a/Runtime/Collision/CCollisionResponseData.cpp b/Runtime/Collision/CCollisionResponseData.cpp index e99c8fbc1..a25433441 100644 --- a/Runtime/Collision/CCollisionResponseData.cpp +++ b/Runtime/Collision/CCollisionResponseData.cpp @@ -88,7 +88,7 @@ void CCollisionResponseData::AddParticleSystemToResponse(EWeaponCollisionRespons CSimplePool* resPool) { const auto i = size_t(type); const std::vector tracker(8); - x0_generators[i].emplace(CPF::GetChildGeneratorDesc(in, resPool, tracker).m_token); + x0_generators[i] = CPF::GetChildGeneratorDesc(in, resPool, tracker).x0_res; } bool CCollisionResponseData::CheckAndAddDecalToResponse(FourCC clsId, CInputStream& in, CSimplePool* resPool) { @@ -100,7 +100,7 @@ bool CCollisionResponseData::CheckAndAddDecalToResponse(FourCC clsId, CInputStre return true; } - const CAssetId id{u64(in.readUint32Big())}; + const CAssetId id = in.Get(); if (!id.IsValid()) { return true; } diff --git a/Runtime/Collision/CCollisionResponseData.hpp b/Runtime/Collision/CCollisionResponseData.hpp index 351f367c4..4901e0c69 100644 --- a/Runtime/Collision/CCollisionResponseData.hpp +++ b/Runtime/Collision/CCollisionResponseData.hpp @@ -5,7 +5,7 @@ #include "Runtime/CFactoryMgr.hpp" #include "Runtime/CToken.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/IObj.hpp" #include "Runtime/RetroTypes.hpp" #include "Runtime/Collision/CMaterialList.hpp" diff --git a/Runtime/Collision/CMaterialList.hpp b/Runtime/Collision/CMaterialList.hpp index 12684a67b..e4a99b10e 100644 --- a/Runtime/Collision/CMaterialList.hpp +++ b/Runtime/Collision/CMaterialList.hpp @@ -102,11 +102,13 @@ public: constexpr u64 GetValue() const noexcept { return x0_list; } - static constexpr s32 BitPosition(u64 flag) noexcept { - for (u32 i = 0; i < 64; ++i) { - if ((flag & (u64{1} << i)) != 0) { - return static_cast(i); + static constexpr s32 BitPosition(u64 flags) noexcept { + for (s32 ret = 0, i = 0; i < 32; ++i) { + if ((flags & 1) != 0u) { + return ret; } + flags >>= 1; + ++ret; } return -1; } @@ -122,13 +124,7 @@ public: constexpr bool HasMaterial(EMaterialTypes type) const noexcept { return (x0_list & (u64{1} << u64(type))) != 0; } constexpr bool SharesMaterials(const CMaterialList& other) const noexcept { - for (u32 i = 0; i < 64; i++) { - if ((x0_list & (u64{1} << i)) != 0 && (other.x0_list & (u64{1} << i)) != 0) { - return true; - } - } - - return false; + return (other.x0_list & x0_list) ? true : false; } constexpr u64 Intersection(const CMaterialList& other) const noexcept { return other.x0_list & x0_list; } diff --git a/Runtime/Collision/COBBTree.cpp b/Runtime/Collision/COBBTree.cpp index fec3facd0..aa54e57b9 100644 --- a/Runtime/Collision/COBBTree.cpp +++ b/Runtime/Collision/COBBTree.cpp @@ -41,16 +41,16 @@ constexpr std::array DefaultSurfaceIndices{ }; /* This is exactly what retro did >.< */ -u32 verify_deaf_babe(CInputStream& in) { return in.readUint32Big(); } +u32 verify_deaf_babe(CInputStream& in) { return in.ReadLong(); } /* This is exactly what retro did >.< */ -u32 verify_version(CInputStream& in) { return in.readUint32Big(); } +u32 verify_version(CInputStream& in) { return in.ReadLong(); } } // Anonymous namespace COBBTree::COBBTree(CInputStream& in) : x0_magic(verify_deaf_babe(in)) , x4_version(verify_version(in)) -, x8_memsize(in.readUint32()) +, x8_memsize(in.ReadLong()) , x18_indexData(in) , x88_root(std::make_unique(in)) {} @@ -158,38 +158,38 @@ zeus::CAABox COBBTree::CalculateAABox(const zeus::CTransform& xf) const { } COBBTree::SIndexData::SIndexData(CInputStream& in) { - u32 count = in.readUint32Big(); + u32 count = in.ReadLong(); x0_materials.reserve(count); for (u32 i = 0; i < count; i++) { - x0_materials.emplace_back(in.readUint32Big()); + x0_materials.emplace_back(in.ReadLong()); } - count = in.readUint32Big(); + count = in.ReadLong(); for (u32 i = 0; i < count; i++) { - x10_vertMaterials.emplace_back(in.readUByte()); + x10_vertMaterials.emplace_back(in.ReadUint8()); } - count = in.readUint32Big(); + count = in.ReadLong(); for (u32 i = 0; i < count; i++) { - x20_edgeMaterials.emplace_back(in.readUByte()); + x20_edgeMaterials.emplace_back(in.ReadUint8()); } - count = in.readUint32Big(); + count = in.ReadLong(); for (u32 i = 0; i < count; i++) { - x30_surfaceMaterials.emplace_back(in.readUByte()); + x30_surfaceMaterials.emplace_back(in.ReadUint8()); } - count = in.readUint32Big(); + count = in.ReadLong(); for (u32 i = 0; i < count; i++) { x40_edges.emplace_back(in); } - count = in.readUint32Big(); + count = in.ReadLong(); for (u32 i = 0; i < count; i++) { - x50_surfaceIndices.emplace_back(in.readUint16Big()); + x50_surfaceIndices.emplace_back(in.ReadShort()); } - count = in.readUint32Big(); + count = in.ReadLong(); for (u32 i = 0; i < count; i++) { - x60_vertices.emplace_back(zeus::CVector3f::ReadBig(in)); + x60_vertices.emplace_back(in.Get()); } } @@ -202,8 +202,8 @@ COBBTree::CNode::CNode(const zeus::CTransform& xf, const zeus::CVector3f& point, , x48_leaf(std::move(leaf)) {} COBBTree::CNode::CNode(CInputStream& in) { - x0_obb = zeus::COBBox::ReadBig(in); - x3c_isLeaf = in.readBool(); + x0_obb = in.Get(); + x3c_isLeaf = in.ReadBool(); if (x3c_isLeaf) x48_leaf = std::make_unique(in); else { @@ -236,9 +236,9 @@ size_t COBBTree::CLeafData::GetMemoryUsage() const { } COBBTree::CLeafData::CLeafData(CInputStream& in) { - const u32 edgeCount = in.readUint32Big(); + const u32 edgeCount = in.ReadLong(); for (u32 i = 0; i < edgeCount; i++) { - x0_surface.emplace_back(in.readUint16Big()); + x0_surface.emplace_back(in.ReadShort()); } } diff --git a/hecl/lib/CVar.cpp b/Runtime/ConsoleVariables/CVar.cpp similarity index 72% rename from hecl/lib/CVar.cpp rename to Runtime/ConsoleVariables/CVar.cpp index 6c7934285..701e3403b 100644 --- a/hecl/lib/CVar.cpp +++ b/Runtime/ConsoleVariables/CVar.cpp @@ -1,13 +1,14 @@ -#include "hecl/CVar.hpp" +#include "Runtime/ConsoleVariables/CVar.hpp" +#include "Runtime/CBasics.hpp" +#include "Runtime/CStringExtras.hpp" + +#include #include -#include "hecl/CVarManager.hpp" -#include "hecl/hecl.hpp" +#include "Runtime/ConsoleVariables/CVarManager.hpp" -#include - -namespace hecl { +namespace metaforce { extern CVar* com_developer; extern CVar* com_enableCheats; @@ -19,38 +20,44 @@ CVar::CVar(std::string_view name, std::string_view value, std::string_view help, init(flags); } -CVar::CVar(std::string_view name, const atVec2f& value, std::string_view help, EFlags flags) +CVar::CVar(std::string_view name, const zeus::CVector2i& value, std::string_view help, EFlags flags) +: CVar(name, help, EType::Vec2i) { + fromVec2i(value); + init(flags); +} + +CVar::CVar(std::string_view name, const zeus::CVector2f& value, std::string_view help, EFlags flags) : CVar(name, help, EType::Vec2f) { fromVec2f(value); init(flags); } -CVar::CVar(std::string_view name, const atVec2d& value, std::string_view help, EFlags flags) +CVar::CVar(std::string_view name, const zeus::CVector2d& value, std::string_view help, EFlags flags) : CVar(name, help, EType::Vec2d) { fromVec2d(value); init(flags); } -CVar::CVar(std::string_view name, const atVec3f& value, std::string_view help, EFlags flags) +CVar::CVar(std::string_view name, const zeus::CVector3f& value, std::string_view help, EFlags flags) : CVar(name, help, EType::Vec3f) { fromVec3f(value); init(flags, false); } -CVar::CVar(std::string_view name, const atVec3d& value, std::string_view help, EFlags flags) +CVar::CVar(std::string_view name, const zeus::CVector3d& value, std::string_view help, EFlags flags) : CVar(name, help, EType::Vec3d) { fromVec3d(value); init(flags, false); } -CVar::CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags) +CVar::CVar(std::string_view name, const zeus::CVector4f& value, std::string_view help, EFlags flags) : CVar(name, help, EType::Vec4f) { fromVec4f(value); init(flags, false); } -CVar::CVar(std::string_view name, const atVec4d& value, std::string_view help, EFlags flags) +CVar::CVar(std::string_view name, const zeus::CVector4d& value, std::string_view help, EFlags flags) : CVar(name, help, EType::Vec4d) { fromVec4d(value); init(flags, false); @@ -83,118 +90,117 @@ std::string CVar::help() const { return m_help + (m_defaultValue.empty() ? "" : "\ndefault: " + m_defaultValue) + (isReadOnly() ? " [ReadOnly]" : ""); } -atVec2f CVar::toVec2f(bool* isValid) const { +zeus::CVector2i CVar::toVec2i(bool* isValid) const { + if (m_type != EType::Vec2i) { + if (isValid != nullptr) + *isValid = false; + + return {}; + } + + if (isValid != nullptr) + *isValid = true; + + std::array f; + std::sscanf(m_value.c_str(), "%i %i", &f[0], &f[1]); + return {f[0], f[1]}; +} + + +zeus::CVector2f CVar::toVec2f(bool* isValid) const { if (m_type != EType::Vec2f) { if (isValid != nullptr) *isValid = false; - return atVec2f{}; + return {}; } if (isValid != nullptr) *isValid = true; - atVec2f vec{}; - athena::simd_floats f; + std::array f; std::sscanf(m_value.c_str(), "%g %g", &f[0], &f[1]); - vec.simd.copy_from(f); - - return vec; + return {f[0], f[1]}; } -atVec2d CVar::toVec2d(bool* isValid) const { +zeus::CVector2d CVar::toVec2d(bool* isValid) const { if (m_type != EType::Vec2d) { if (isValid != nullptr) *isValid = false; - return atVec2d{}; + return {}; } if (isValid != nullptr) *isValid = true; - atVec2d vec{}; - athena::simd_doubles f; + std::array f; std::sscanf(m_value.c_str(), "%lg %lg", &f[0], &f[1]); - vec.simd.copy_from(f); - - return vec; + return {f[0], f[1]}; } -atVec3f CVar::toVec3f(bool* isValid) const { +zeus::CVector3f CVar::toVec3f(bool* isValid) const { if (m_type != EType::Vec3f) { if (isValid != nullptr) *isValid = false; - return atVec3f{}; + return {}; } if (isValid != nullptr) *isValid = true; - atVec3f vec{}; - athena::simd_floats f; + std::array f; std::sscanf(m_value.c_str(), "%g %g %g", &f[0], &f[1], &f[2]); - vec.simd.copy_from(f); - - return vec; + return {f[0], f[1], f[2]}; } -atVec3d CVar::toVec3d(bool* isValid) const { +zeus::CVector3d CVar::toVec3d(bool* isValid) const { if (m_type != EType::Vec3d) { if (isValid != nullptr) *isValid = false; - return atVec3d{}; + return {}; } if (isValid != nullptr) *isValid = true; - atVec3d vec{}; - athena::simd_doubles f; + std::array f; std::sscanf(m_value.c_str(), "%lg %lg %lg", &f[0], &f[1], &f[2]); - vec.simd.copy_from(f); - - return vec; + return {f[0], f[1], f[2]}; } -atVec4f CVar::toVec4f(bool* isValid) const { +zeus::CVector4f CVar::toVec4f(bool* isValid) const { if (m_type != EType::Vec4f) { if (isValid != nullptr) *isValid = false; - return atVec4f{}; + return {}; } if (isValid != nullptr) *isValid = true; - atVec4f vec{}; - athena::simd_floats f; + std::array f; std::sscanf(m_value.c_str(), "%g %g %g %g", &f[0], &f[1], &f[2], &f[3]); - vec.simd.copy_from(f); - - return vec; + return {f[0], f[1], f[2], f[3]}; } -atVec4d CVar::toVec4d(bool* isValid) const { +zeus::CVector4d CVar::toVec4d(bool* isValid) const { if (m_type != EType::Vec4d) { if (isValid != nullptr) *isValid = false; - return atVec4d{}; + return {}; } if (isValid != nullptr) *isValid = true; - atVec4d vec{}; - athena::simd_doubles f; + std::array f{}; std::sscanf(m_value.c_str(), "%lg %lg %lg %lg", &f[0], &f[1], &f[2], &f[3]); - vec.simd.copy_from(f); - - return vec; + return {f[0], f[1], f[2], f[3]}; } double CVar::toReal(bool* isValid) const { @@ -218,7 +224,7 @@ bool CVar::toBoolean(bool* isValid) const { return false; } - return athena::utility::parseBool(m_value, isValid); + return CStringExtras::ParseBool(m_value, isValid); } int32_t CVar::toSigned(bool* isValid) const { @@ -259,62 +265,65 @@ std::string CVar::toLiteral(bool* isValid) const { return m_value; } -bool CVar::fromVec2f(const atVec2f& val) { +bool CVar::fromVec2i(const zeus::CVector2i& val) { + if (!safeToModify(EType::Vec2i)) + return false; + + m_value.assign(fmt::format(FMT_STRING("{} {}"), val.x, val.y)); + m_flags |= EFlags::Modified; + return true; +} + +bool CVar::fromVec2f(const zeus::CVector2f& val) { if (!safeToModify(EType::Vec2f)) return false; - athena::simd_floats f(val.simd); - m_value.assign(fmt::format(FMT_STRING("{} {}"), f[0], f[1])); + m_value.assign(fmt::format(FMT_STRING("{} {}"), val.x(), val.y())); m_flags |= EFlags::Modified; return true; } -bool CVar::fromVec2d(const atVec2d& val) { +bool CVar::fromVec2d(const zeus::CVector2d& val) { if (!safeToModify(EType::Vec2d)) return false; - athena::simd_doubles f(val.simd); - m_value.assign(fmt::format(FMT_STRING("{} {}"), f[0], f[1])); + m_value.assign(fmt::format(FMT_STRING("{} {}"), val.x(), val.y())); m_flags |= EFlags::Modified; return true; } -bool CVar::fromVec3f(const atVec3f& val) { +bool CVar::fromVec3f(const zeus::CVector3f& val) { if (!safeToModify(EType::Vec3f)) return false; - athena::simd_floats f(val.simd); - m_value.assign(fmt::format(FMT_STRING("{} {} {}"), f[0], f[1], f[2])); + m_value.assign(fmt::format(FMT_STRING("{} {} {}"), val.x(), val.y(), val.z())); m_flags |= EFlags::Modified; return true; } -bool CVar::fromVec3d(const atVec3d& val) { +bool CVar::fromVec3d(const zeus::CVector3d& val) { if (!safeToModify(EType::Vec3d)) return false; - athena::simd_doubles f(val.simd); - m_value.assign(fmt::format(FMT_STRING("{} {} {}"), f[0], f[1], f[2])); + m_value.assign(fmt::format(FMT_STRING("{} {} {}"), val.x(), val.y(), val.z())); m_flags |= EFlags::Modified; return true; } -bool CVar::fromVec4f(const atVec4f& val) { +bool CVar::fromVec4f(const zeus::CVector4f& val) { if (!safeToModify(EType::Vec4f)) return false; - athena::simd_floats f(val.simd); - m_value.assign(fmt::format(FMT_STRING("{} {} {} {}"), f[0], f[1], f[2], f[3])); + m_value.assign(fmt::format(FMT_STRING("{} {} {} {}"), val.x(), val.y(), val.z(), val.w())); m_flags |= EFlags::Modified; return true; } -bool CVar::fromVec4d(const atVec4d& val) { +bool CVar::fromVec4d(const zeus::CVector4d& val) { if (!safeToModify(EType::Vec4d)) return false; - athena::simd_doubles f(val.simd); - m_value.assign(fmt::format(FMT_STRING("{} {} {} {}"), f[0], f[1], f[2], f[3])); + m_value.assign(fmt::format(FMT_STRING("{} {} {} {}"), val.x(), val.y(), val.z(), val.w())); m_flags |= EFlags::Modified; return true; } @@ -423,6 +432,8 @@ void CVar::clearModified() { m_flags &= ~EFlags::Modified; } +void CVar::forceClearModified() { m_flags &= ~EFlags::Modified; } + void CVar::setModified() { m_flags |= EFlags::Modified; } void CVar::unlock() { @@ -454,10 +465,24 @@ void CVar::dispatch() { } } +bool isInt(std::string_view v) { + char* p; + std::strtol(v.data(), &p, 10); + return p != nullptr && *p == 0; +} + +bool isInt(const std::vector& v) { + for (auto& s : v) { + if (!isInt(s)) + return false; + } + return true; +} + bool isReal(std::string_view v) { char* p; std::strtod(v.data(), &p); - return *p == 0; + return p != nullptr && *p == 0; } bool isReal(const std::vector& v) { for (auto& s : v) { @@ -468,20 +493,20 @@ bool isReal(const std::vector& v) { } bool CVar::isValidInput(std::string_view input) const { - std::vector parts = athena::utility::split(input, ' '); + std::vector parts = CStringExtras::Split(input, ' '); char* p; switch (m_type) { case EType::Boolean: { bool valid = false; - athena::utility::parseBool(input, &valid); + CStringExtras::ParseBool(input, &valid); return valid; } case EType::Signed: std::strtol(input.data(), &p, 0); - return p == nullptr; + return p != nullptr && *p == 0; case EType::Unsigned: std::strtoul(input.data(), &p, 0); - return p == nullptr; + return p != nullptr && *p == 0; case EType::Real: { bool size = parts.size() == 1; bool ret = isReal(input); @@ -489,6 +514,8 @@ bool CVar::isValidInput(std::string_view input) const { } case EType::Literal: return true; + case EType::Vec2i: + return parts.size() == 2 && isInt(parts); case EType::Vec2f: case EType::Vec2d: return parts.size() == 2 && isReal(parts); @@ -529,4 +556,4 @@ void CVar::init(EFlags flags, bool removeColor) { } } -} // namespace hecl +} // namespace metaforce diff --git a/hecl/include/hecl/CVar.hpp b/Runtime/ConsoleVariables/CVar.hpp similarity index 74% rename from hecl/include/hecl/CVar.hpp rename to Runtime/ConsoleVariables/CVar.hpp index a47b584fd..772392783 100644 --- a/hecl/include/hecl/CVar.hpp +++ b/Runtime/ConsoleVariables/CVar.hpp @@ -1,16 +1,14 @@ #pragma once +#include "Runtime/GCNTypes.hpp" +#include "zeus/zeus.hpp" + #include #include #include - -#include -#include -#include - -namespace hecl { -namespace DNACVAR { -enum class EType : atUint8 { Boolean, Signed, Unsigned, Real, Literal, Vec2f, Vec2d, Vec3f, Vec3d, Vec4f, Vec4d }; +namespace metaforce { +namespace StoreCVar { +enum class EType : uint32_t { Boolean, Signed, Unsigned, Real, Literal, Vec2i, Vec2f, Vec2d, Vec3f, Vec3d, Vec4f, Vec4d }; enum class EFlags { None = 0, System = (1 << 0), @@ -30,41 +28,38 @@ enum class EFlags { }; ENABLE_BITWISE_ENUM(EFlags) -class CVar : public athena::io::DNA { +class CVar { public: - AT_DECL_DNA - String<-1> m_name; - String<-1> m_value; + std::string m_name; + std::string m_value; }; -struct CVarContainer : public athena::io::DNA { - AT_DECL_DNA - Value magic = 'CVAR'; - Value cvarCount; - Vector cvars; +struct CVarContainer { + u32 magic = 'CVAR'; + std::vector cvars; }; -} // namespace DNACVAR +} // namespace StoreCVar class CVarManager; class ICVarValueReference; -class CVar : protected DNACVAR::CVar { +class CVar : protected StoreCVar::CVar { friend class CVarManager; - Delete _d; public: typedef std::function ListenerFunc; - using EType = DNACVAR::EType; - using EFlags = DNACVAR::EFlags; + using EType = StoreCVar::EType; + using EFlags = StoreCVar::EFlags; CVar(std::string_view name, std::string_view value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec2f& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec2d& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec3f& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec3d& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec4f& value, std::string_view help, EFlags flags); - CVar(std::string_view name, const atVec4d& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const zeus::CVector2i& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const zeus::CVector2f& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const zeus::CVector2d& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const zeus::CVector3f& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const zeus::CVector3d& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const zeus::CVector4f& value, std::string_view help, EFlags flags); + CVar(std::string_view name, const zeus::CVector4d& value, std::string_view help, EFlags flags); CVar(std::string_view name, double value, std::string_view help, EFlags flags); CVar(std::string_view name, bool value, std::string_view help, EFlags flags); CVar(std::string_view name, int32_t value, std::string_view help, EFlags flags); @@ -78,12 +73,13 @@ public: template inline bool toValue(T& value) const; - atVec2f toVec2f(bool* isValid = nullptr) const; - atVec2d toVec2d(bool* isValid = nullptr) const; - atVec3f toVec3f(bool* isValid = nullptr) const; - atVec3d toVec3d(bool* isValid = nullptr) const; - atVec4f toVec4f(bool* isValid = nullptr) const; - atVec4d toVec4d(bool* isValid = nullptr) const; + zeus::CVector2i toVec2i(bool* isValid = nullptr) const; + zeus::CVector2f toVec2f(bool* isValid = nullptr) const; + zeus::CVector2d toVec2d(bool* isValid = nullptr) const; + zeus::CVector3f toVec3f(bool* isValid = nullptr) const; + zeus::CVector3d toVec3d(bool* isValid = nullptr) const; + zeus::CVector4f toVec4f(bool* isValid = nullptr) const; + zeus::CVector4d toVec4d(bool* isValid = nullptr) const; double toReal(bool* isValid = nullptr) const; bool toBoolean(bool* isValid = nullptr) const; int32_t toSigned(bool* isValid = nullptr) const; @@ -94,12 +90,13 @@ public: inline bool fromValue(T value) { return false; } - bool fromVec2f(const atVec2f& val); - bool fromVec2d(const atVec2d& val); - bool fromVec3f(const atVec3f& val); - bool fromVec3d(const atVec3d& val); - bool fromVec4f(const atVec4f& val); - bool fromVec4d(const atVec4d& val); + bool fromVec2i(const zeus::CVector2i& val); + bool fromVec2f(const zeus::CVector2f& val); + bool fromVec2d(const zeus::CVector2d& val); + bool fromVec3f(const zeus::CVector3f& val); + bool fromVec3d(const zeus::CVector3d& val); + bool fromVec4f(const zeus::CVector4f& val); + bool fromVec4d(const zeus::CVector4d& val); bool fromReal(double val); bool fromBoolean(bool val); bool fromInteger(int32_t val); @@ -107,6 +104,7 @@ public: bool fromLiteral(std::string_view val); bool fromLiteralToType(std::string_view val); + bool isVec2i() const { return m_type == EType::Vec2i; } bool isVec2f() const { return m_type == EType::Vec2f; } bool isVec2d() const { return m_type == EType::Vec2d; } bool isVec3f() const { return m_type == EType::Vec3f; } @@ -162,6 +160,7 @@ private: CVar(std::string_view name, std::string_view help, EType type) : m_help(help), m_type(type) { m_name = name; } void dispatch(); void clearModified(); + void forceClearModified(); void setModified(); std::string m_help; EType m_type; @@ -177,37 +176,37 @@ private: }; template <> -inline bool CVar::toValue(atVec2f& value) const { +inline bool CVar::toValue(zeus::CVector2f& value) const { bool isValid = false; value = toVec2f(&isValid); return isValid; } template <> -inline bool CVar::toValue(atVec2d& value) const { +inline bool CVar::toValue(zeus::CVector2d& value) const { bool isValid = false; value = toVec2d(&isValid); return isValid; } template <> -inline bool CVar::toValue(atVec3f& value) const { +inline bool CVar::toValue(zeus::CVector3f& value) const { bool isValid = false; value = toVec3f(&isValid); return isValid; } template <> -inline bool CVar::toValue(atVec3d& value) const { +inline bool CVar::toValue(zeus::CVector3d& value) const { bool isValid = false; value = toVec3d(&isValid); return isValid; } template <> -inline bool CVar::toValue(atVec4f& value) const { +inline bool CVar::toValue(zeus::CVector4f& value) const { bool isValid = false; value = toVec4f(&isValid); return isValid; } template <> -inline bool CVar::toValue(atVec4d& value) const { +inline bool CVar::toValue(zeus::CVector4d& value) const { bool isValid = false; value = toVec4d(&isValid); return isValid; @@ -250,27 +249,27 @@ inline bool CVar::toValue(std::string& value) const { } template <> -inline bool CVar::fromValue(const atVec2f& val) { +inline bool CVar::fromValue(const zeus::CVector2f& val) { return fromVec2f(val); } template <> -inline bool CVar::fromValue(const atVec2d& val) { +inline bool CVar::fromValue(const zeus::CVector2d& val) { return fromVec2d(val); } template <> -inline bool CVar::fromValue(const atVec3f& val) { +inline bool CVar::fromValue(const zeus::CVector3f& val) { return fromVec3f(val); } template <> -inline bool CVar::fromValue(const atVec3d& val) { +inline bool CVar::fromValue(const zeus::CVector3d& val) { return fromVec3d(val); } template <> -inline bool CVar::fromValue(const atVec4f& val) { +inline bool CVar::fromValue(const zeus::CVector4f& val) { return fromVec4f(val); } template <> -inline bool CVar::fromValue(const atVec4d& val) { +inline bool CVar::fromValue(const zeus::CVector4d& val) { return fromVec4d(val); } template <> @@ -350,4 +349,4 @@ public: } } }; -} // namespace hecl +} // namespace metaforce diff --git a/Runtime/ConsoleVariables/CVarCommons.cpp b/Runtime/ConsoleVariables/CVarCommons.cpp new file mode 100644 index 000000000..aadd27d5f --- /dev/null +++ b/Runtime/ConsoleVariables/CVarCommons.cpp @@ -0,0 +1,100 @@ +#include "Runtime/ConsoleVariables/CVarCommons.hpp" + +namespace metaforce { +namespace { +CVarCommons* m_instance = nullptr; +} + +CVarCommons::CVarCommons(CVarManager& manager) : m_mgr(manager) { + m_fullscreen = m_mgr.findOrMakeCVar("fullscreen"sv, "Start in fullscreen"sv, false, + CVar::EFlags::System | CVar::EFlags::Archive); + m_allowJoystickInBackground = + m_mgr.findOrMakeCVar("allowJoystickInBackground"sv, "Enable joystick input while window does not have focus"sv, + true, CVar::EFlags::System | CVar::EFlags::Archive); + m_graphicsApi = m_mgr.findOrMakeCVar("graphicsApi"sv, "API to use for rendering graphics"sv, DEFAULT_GRAPHICS_API, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::ModifyRestart); + m_drawSamples = m_mgr.findOrMakeCVar("drawSamples"sv, "Number of MSAA samples to use for render targets"sv, 1, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::ModifyRestart); + m_texAnisotropy = + m_mgr.findOrMakeCVar("texAnisotropy"sv, "Number of anisotropic samples to use for sampling textures"sv, 1, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::ModifyRestart); + m_deepColor = m_mgr.findOrMakeCVar("deepColor"sv, "Allow framebuffer with color depth greater-then 24-bits"sv, false, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::ModifyRestart); + m_variableDt = m_mgr.findOrMakeCVar("variableDt", "Enable variable delta time (experimental)", false, + (CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::ModifyRestart)); + m_windowSize = m_mgr.findOrMakeCVar("windowSize", "Stores the last known window size", zeus::CVector2i(1280, 960), + (CVar::EFlags::System | CVar::EFlags::Archive)); + m_windowPos = m_mgr.findOrMakeCVar("windowPos", "Stores the last known window position", zeus::CVector2i(-1, -1), + (CVar::EFlags::System | CVar::EFlags::Archive)); + + m_debugOverlayPlayerInfo = m_mgr.findOrMakeCVar( + "debugOverlay.playerInfo"sv, "Displays information about the player, such as location and orientation"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayWorldInfo = m_mgr.findOrMakeCVar( + "debugOverlay.worldInfo"sv, "Displays information about the current world, such as world asset ID, and areaId"sv, + false, CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayAreaInfo = m_mgr.findOrMakeCVar( + "debugOverlay.areaInfo"sv, + "Displays information about the current area, such as asset ID, object/layer counts, and active layer bits"sv, + false, CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayLayerInfo = + m_mgr.findOrMakeCVar("debugOverlay.layerInfo"sv, "Displays information about the currently active area layers"sv, + false, CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayShowFrameCounter = + m_mgr.findOrMakeCVar("debugOverlay.showFrameCounter"sv, "Displays the current frame index"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayShowFramerate = + m_mgr.findOrMakeCVar("debugOverlay.showFramerate"sv, "Displays the current framerate"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayShowInGameTime = + m_mgr.findOrMakeCVar("debugOverlay.showInGameTime"sv, "Displays the current in game time"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayShowRoomTimer = m_mgr.findOrMakeCVar( + "debugOverlay.showRoomTimer", "Displays the current/last room timers in seconds and frames"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayShowResourceStats = m_mgr.findOrMakeCVar( + "debugOverlay.showResourceStats"sv, "Displays the current live resource object and token counts"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayShowRandomStats = + m_mgr.findOrMakeCVar("debugOverlay.showRandomStats", "Displays the current number of random calls per frame"sv, + false, CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayPipelineInfo = + m_mgr.findOrMakeCVar("debugOverlay.pipelineInfo"sv, "Displays the current pipeline memory usage per frame"sv, + false, CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayDrawCallInfo = + m_mgr.findOrMakeCVar("debugOverlay.drawCallInfo"sv, "Displays the current number of draw calls per frame"sv, + false, CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayBufferInfo = + m_mgr.findOrMakeCVar("debugOverlay.bufferInfo"sv, "Displays the current buffer memory usage per frame"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayShowInput = m_mgr.findOrMakeCVar("debugOverlay.showInput"sv, "Displays controller input"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugOverlayCorner = + m_mgr.findOrMakeCVar("debugOverlay.overlayCorner"sv, "ImGui debug overlay corner"sv, 2 /* bottom-left */, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::Hidden); + m_debugInputOverlayCorner = + m_mgr.findOrMakeCVar("debugOverlay.inputOverlayCorner"sv, "ImGui input overlay corner"sv, 3 /* bottom-right */, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::Hidden); + + m_debugToolDrawAiPath = + m_mgr.findOrMakeCVar("debugTool.drawAiPath", "Draws the selected paths of any AI in the room"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugToolDrawLighting = m_mgr.findOrMakeCVar("debugTool.drawLighting", "Draws the lighting setup in a room"sv, + false, CVar::EFlags::Game | CVar::EFlags::ReadOnly); + m_debugToolDrawCollisionActors = + m_mgr.findOrMakeCVar("debugTool.drawCollisionActors", "Draws the collision actors for enemies and objects"sv, + false, CVar::EFlags::Game | CVar::EFlags::ReadOnly); + m_debugToolDrawMazePath = m_mgr.findOrMakeCVar("debugTool.drawMazePath", "Draws the maze path in Dynamo"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_debugToolDrawPlatformCollision = + m_mgr.findOrMakeCVar("debugTool.drawPlatformCollision", "Draws the bounding boxes of platforms"sv, false, + CVar::EFlags::Game | CVar::EFlags::Archive | CVar::EFlags::ReadOnly); + m_logFile = m_mgr.findOrMakeCVar("logFile"sv, "Any log prints will be stored to this file upon exit"sv, "app.log"sv, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::ModifyRestart); + m_lastDiscPath = m_mgr.findOrMakeCVar("lastDiscPath"sv, "Most recently loaded disc image path"sv, ""sv, + CVar::EFlags::System | CVar::EFlags::Archive | CVar::EFlags::Hidden); + m_instance = this; +} + +CVarCommons* CVarCommons::instance() { return m_instance; } +} // namespace metaforce diff --git a/hecl/include/hecl/CVarCommons.hpp b/Runtime/ConsoleVariables/CVarCommons.hpp similarity index 78% rename from hecl/include/hecl/CVarCommons.hpp rename to Runtime/ConsoleVariables/CVarCommons.hpp index 5dc39170c..7da5d6548 100644 --- a/hecl/include/hecl/CVarCommons.hpp +++ b/Runtime/ConsoleVariables/CVarCommons.hpp @@ -4,12 +4,12 @@ #include #include -#include "hecl/CVarManager.hpp" +#include "Runtime/ConsoleVariables/CVarManager.hpp" #undef min #undef max -namespace hecl { +namespace metaforce { using namespace std::literals; @@ -22,12 +22,14 @@ using namespace std::literals; struct CVarCommons { CVarManager& m_mgr; CVar* m_fullscreen = nullptr; + CVar* m_allowJoystickInBackground = nullptr; CVar* m_graphicsApi = nullptr; CVar* m_drawSamples = nullptr; CVar* m_texAnisotropy = nullptr; CVar* m_deepColor = nullptr; CVar* m_variableDt = nullptr; - CVar* m_lazyCommitResources = nullptr; + CVar* m_windowSize = nullptr; + CVar* m_windowPos = nullptr; CVar* m_debugOverlayPlayerInfo = nullptr; CVar* m_debugOverlayWorldInfo = nullptr; @@ -39,17 +41,24 @@ struct CVarCommons { CVar* m_debugOverlayShowResourceStats = nullptr; CVar* m_debugOverlayShowRandomStats = nullptr; CVar* m_debugOverlayShowRoomTimer = nullptr; + CVar* m_debugOverlayPipelineInfo = nullptr; + CVar* m_debugOverlayDrawCallInfo = nullptr; + CVar* m_debugOverlayBufferInfo = nullptr; CVar* m_debugOverlayShowInput = nullptr; + CVar* m_debugOverlayCorner = nullptr; + CVar* m_debugInputOverlayCorner = nullptr; CVar* m_debugToolDrawAiPath = nullptr; CVar* m_debugToolDrawLighting = nullptr; CVar* m_debugToolDrawCollisionActors = nullptr; CVar* m_debugToolDrawMazePath = nullptr; CVar* m_debugToolDrawPlatformCollision = nullptr; CVar* m_logFile = nullptr; + CVar* m_lastDiscPath = nullptr; CVarCommons(CVarManager& manager); bool getFullscreen() const { return m_fullscreen->toBoolean(); } + bool getAllowJoystickInBackground() const { return m_allowJoystickInBackground->toBoolean(); } void setFullscreen(bool b) { m_fullscreen->fromBoolean(b); } @@ -62,6 +71,8 @@ struct CVarCommons { void setSamples(uint32_t v) { m_drawSamples->fromInteger(std::max(uint32_t(1), v)); } uint32_t getAnisotropy() const { return std::max(1u, uint32_t(m_texAnisotropy->toUnsigned())); } + zeus::CVector2i getWindowSize() const { return m_windowSize->toVec2i(); } + zeus::CVector2i getWindowPos() const { return m_windowPos->toVec2i(); } void setAnisotropy(uint32_t v) { m_texAnisotropy->fromInteger(std::max(1u, v)); } diff --git a/hecl/lib/CVarManager.cpp b/Runtime/ConsoleVariables/CVarManager.cpp similarity index 52% rename from hecl/lib/CVarManager.cpp rename to Runtime/ConsoleVariables/CVarManager.cpp index 2f45acc82..0252c1efd 100644 --- a/hecl/lib/CVarManager.cpp +++ b/Runtime/ConsoleVariables/CVarManager.cpp @@ -1,17 +1,26 @@ -#include "hecl/CVarManager.hpp" +#include "Runtime/ConsoleVariables/CVarManager.hpp" +#include "Runtime/ConsoleVariables/FileStoreManager.hpp" +#include "Runtime/CBasics.hpp" +#include "Runtime/Streams/CTextInStream.hpp" +#include "Runtime/Streams/CTextOutStream.hpp" +#include "Runtime/Streams/CMemoryInStream.hpp" +#include "Runtime/Streams/CMemoryStreamOut.hpp" +#include "Runtime/CStringExtras.hpp" +#include #include #include #include -#include "hecl/Console.hpp" -#include "hecl/hecl.hpp" -#include "hecl/Runtime.hpp" +#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) +#endif -#include -#include +#if !defined(S_ISDIR) && defined(S_IFMT) && defined(S_IFDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) +#endif -namespace hecl { +namespace metaforce { CVar* com_developer = nullptr; CVar* com_configfile = nullptr; @@ -22,8 +31,7 @@ static const std::regex cmdLineRegex(R"(\+([\w\.]+)([=])?([\/\\\s\w\.\-]+)?)"); CVarManager* CVarManager::m_instance = nullptr; static logvisor::Module CVarLog("CVarManager"); -CVarManager::CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary) -: m_store(store), m_useBinary(useBinary) { +CVarManager::CVarManager(FileStoreManager& store, bool useBinary) : m_store(store), m_useBinary(useBinary) { m_instance = this; com_configfile = newCVar("config", "File to store configuration", std::string("config"), @@ -41,7 +49,7 @@ CVarManager::~CVarManager() {} CVar* CVarManager::registerCVar(std::unique_ptr&& cvar) { std::string tmp(cvar->name()); - athena::utility::tolower(tmp); + CStringExtras::ToLower(tmp); if (m_cvars.find(tmp) != m_cvars.end()) { return nullptr; @@ -54,7 +62,7 @@ CVar* CVarManager::registerCVar(std::unique_ptr&& cvar) { CVar* CVarManager::findCVar(std::string_view name) { std::string lower(name); - athena::utility::tolower(lower); + CStringExtras::ToLower(lower); auto search = m_cvars.find(lower); if (search == m_cvars.end()) return nullptr; @@ -81,15 +89,14 @@ std::vector CVarManager::cvars(CVar::EFlags filter) const { } void CVarManager::deserialize(CVar* cvar) { - /* Make sure we're not trying to deserialize a CVar that is invalid or not exposed, unless it's been specified on the - * command line (i.e deferred) */ + /* Make sure we're not trying to deserialize a CVar that is invalid*/ if (!cvar) { return; } /* First let's check for a deferred value */ std::string lowName = cvar->name().data(); - athena::utility::tolower(lowName); + CStringExtras::ToLower(lowName); if (const auto iter = m_deferedCVars.find(lowName); iter != m_deferedCVars.end()) { std::string val = std::move(iter->second); m_deferedCVars.erase(lowName); @@ -109,160 +116,124 @@ void CVarManager::deserialize(CVar* cvar) { if (!cvar->isArchive() && !cvar->isInternalArchivable()) { return; } - /* We were either unable to find a deferred value or got an invalid value */ - std::string filename = - std::string(m_store.getStoreRoot()) + '/' + com_configfile->toLiteral(); - hecl::Sstat st; - - if (m_useBinary) { - CVarContainer container; - filename += ".bin"; - if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode)) - return; - athena::io::FileReader reader(filename); - if (reader.isOpen()) - container.read(reader); - - if (container.cvars.size() > 0) { - auto serialized = std::find_if(container.cvars.begin(), container.cvars.end(), - [&cvar](const DNACVAR::CVar& c) { return c.m_name == cvar->name(); }); - - if (serialized != container.cvars.end()) { - DNACVAR::CVar& tmp = *serialized; - - if (cvar->m_value != tmp.m_value) { - CVarUnlocker lc(cvar); - cvar->fromLiteralToType(tmp.m_value); - cvar->m_wasDeserialized = true; - } + std::string filename = std::string(m_store.getStoreRoot()) + '/' + com_configfile->toLiteral() + ".yaml"; + auto container = loadCVars(filename); + auto serialized = + std::find_if(container.cbegin(), container.cend(), [&cvar](const auto& c) { return c.m_name == cvar->name(); }); + if (serialized != container.cend()) { + if (cvar->m_value != serialized->m_value) { + { + CVarUnlocker lc(cvar); + cvar->fromLiteralToType(serialized->m_value); + cvar->m_wasDeserialized = true; } - } - } else { - filename += ".yaml"; - if (hecl::Stat(filename.c_str(), &st) || !S_ISREG(st.st_mode)) - return; - athena::io::FileReader reader(filename); - if (reader.isOpen()) { - athena::io::YAMLDocReader docReader; - if (docReader.parse(&reader)) { - std::unique_ptr root = docReader.releaseRootNode(); - auto serialized = std::find_if(root->m_mapChildren.begin(), root->m_mapChildren.end(), - [&cvar](const auto& c) { return c.first == cvar->name(); }); - - if (serialized != root->m_mapChildren.end()) { - const std::unique_ptr& tmp = serialized->second; - - if (cvar->m_value != tmp->m_scalarString) { - CVarUnlocker lc(cvar); - cvar->fromLiteralToType(tmp->m_scalarString); - cvar->m_wasDeserialized = true; - } - } + if (cvar->modificationRequiresRestart()) { + cvar->dispatch(); + cvar->forceClearModified(); } } } } void CVarManager::serialize() { - std::string filename = - std::string(m_store.getStoreRoot()) + '/' + com_configfile->toLiteral(); + std::string filename = std::string(m_store.getStoreRoot()) + '/' + com_configfile->toLiteral() + ".yaml"; - if (m_useBinary) { - CVarContainer container; - for (const auto& pair : m_cvars) { - const auto& cvar = pair.second; + /* If we have an existing config load it in, so we can update it */ + auto container = loadCVars(filename); - if (cvar->isArchive() || (cvar->isInternalArchivable() && cvar->wasDeserialized() && !cvar->hasDefaultValue())) { - container.cvars.push_back(*cvar); + u32 minLength = 0; + bool write = false; + for (const auto& pair : m_cvars) { + const auto& cvar = pair.second; + + if (cvar->isArchive() || (cvar->isInternalArchivable() && cvar->wasDeserialized() && !cvar->hasDefaultValue())) { + write = true; + /* Look for an existing CVar in the file... */ + auto serialized = + std::find_if(container.begin(), container.end(), [&cvar](const auto& c) { return c.m_name == cvar->name(); }); + if (serialized != container.end()) { + /* Found it! Update the value */ + serialized->m_value = cvar->value(); + } else { + /* Store this value as a new CVar in the config */ + container.emplace_back(StoreCVar::CVar{std::string(cvar->name()), cvar->value()}); } } - container.cvarCount = atUint32(container.cvars.size()); - - filename += ".bin"; - athena::io::FileWriter writer(filename); - if (writer.isOpen()) - container.write(writer); - } else { - filename += ".yaml"; - - athena::io::FileReader r(filename); - athena::io::YAMLDocWriter docWriter(r.isOpen() ? &r : nullptr); - r.close(); - - docWriter.setStyle(athena::io::YAMLNodeStyle::Block); - for (const auto& pair : m_cvars) { - const auto& cvar = pair.second; - - if (cvar->isArchive() || (cvar->isInternalArchivable() && cvar->wasDeserialized() && !cvar->hasDefaultValue())) { - docWriter.writeString(cvar->name().data(), cvar->toLiteral()); - } - } - - athena::io::FileWriter w(filename); - if (w.isOpen()) - docWriter.finish(&w); } + /* Compute length needed for all cvars */ + std::for_each(container.cbegin(), container.cend(), + [&minLength](const auto& cvar) { minLength += cvar.m_name.length() + cvar.m_value.length() + 2; }); + /* Only write the CVars if any have been modified */ + if (!write) { + return; + } + + // Allocate enough space to write all the strings with some space to spare + const auto requiredLen = minLength + (4 * container.size()); + std::unique_ptr workBuf(new u8[requiredLen]); + CMemoryStreamOut memOut(workBuf.get(), requiredLen, CMemoryStreamOut::EOwnerShip::NotOwned, 32); + CTextOutStream textOut(memOut); + for (const auto& cvar : container) { + auto str = fmt::format(FMT_STRING("{}: {}"), cvar.m_name, cvar.m_value); + textOut.WriteString(str); + } + + auto* file = fopen(filename.c_str(), +#ifdef _MSC_VER + "wb" +#else + "wbe" +#endif + ); + if (file != nullptr) { + u32 writeLen = memOut.GetWritePosition(); + u32 offset = 0; + while (offset < writeLen) { + offset += fwrite(workBuf.get() + offset, 1, writeLen - offset, file); + } + fflush(file); + } + fclose(file); +} + +std::vector CVarManager::loadCVars(const std::string& filename) const { + std::vector ret; + CBasics::Sstat st; + if (CBasics::Stat(filename.c_str(), &st) == 0 && S_ISREG(st.st_mode)) { + + auto* file = fopen(filename.c_str(), +#ifdef _MSC_VER + "rb" +#else + "rbe" +#endif + ); + if (file != nullptr) { + + std::unique_ptr inBuf(new u8[st.st_size]); + fread(inBuf.get(), 1, st.st_size, file); + fclose(file); + CMemoryInStream mem(inBuf.get(), st.st_size, CMemoryInStream::EOwnerShip::NotOwned); + CTextInStream textIn(mem, st.st_size); + while (!textIn.IsEOF()) { + auto cvString = textIn.GetNextLine(); + if (cvString.empty()) { + continue; + } + auto parts = CStringExtras::Split(cvString, ':'); + if (parts.size() < 2) { + continue; + } + ret.emplace_back(StoreCVar::CVar{CStringExtras::Trim(parts[0]), CStringExtras::Trim(parts[1])}); + } + } + } + return ret; } CVarManager* CVarManager::instance() { return m_instance; } -void CVarManager::list(Console* con, const std::vector& /*args*/) { - for (const auto& cvar : m_cvars) { - if (!cvar.second->isHidden()) - con->report(Console::Level::Info, FMT_STRING("{}: {}"), cvar.second->name(), cvar.second->help()); - } -} - -void CVarManager::setCVar(Console* con, const std::vector& args) { - if (args.size() < 2) { - con->report(Console::Level::Info, FMT_STRING("Usage setCvar ")); - return; - } - - std::string cvName = args[0]; - athena::utility::tolower(cvName); - const auto iter = m_cvars.find(cvName); - if (iter == m_cvars.end()) { - con->report(Console::Level::Error, FMT_STRING("CVar '{}' does not exist"), args[0]); - return; - } - - const auto& cv = iter->second; - std::string oldVal = cv->value(); - std::string value = args[1]; - auto it = args.begin() + 2; - for (; it != args.end(); ++it) - value += " " + *it; - - /* Check to make sure we're not redundantly assigning the value */ - if (cv->value() == value) - return; - - if (!cv->fromLiteralToType(value)) - con->report(Console::Level::Warning, FMT_STRING("Unable to set cvar '{}' to value '{}'"), cv->name(), value); - else - con->report(Console::Level::Info, FMT_STRING("Set '{}' from '{}' to '{}'"), cv->name(), oldVal, value); -} - -void CVarManager::getCVar(Console* con, const std::vector& args) { - if (args.empty()) { - con->report(Console::Level::Info, FMT_STRING("Usage getCVar ")); - return; - } - - std::string cvName = args[0]; - athena::utility::tolower(cvName); - const auto iter = m_cvars.find(cvName); - if (iter == m_cvars.end()) { - con->report(Console::Level::Error, FMT_STRING("CVar '{}' does not exist"), args[0]); - return; - } - - const auto& cv = iter->second; - con->report(Console::Level::Info, FMT_STRING("'{}' = '{}'"), cv->name(), cv->value()); -} - void CVarManager::setDeveloperMode(bool v, bool setDeserialized) { com_developer->unlock(); com_developer->fromBoolean(v); @@ -290,7 +261,7 @@ bool CVarManager::restartRequired() const { void CVarManager::parseCommandLine(const std::vector& args) { bool oldDeveloper = suppressDeveloper(); std::string developerName(com_developer->name()); - athena::utility::tolower(developerName); + CStringExtras::ToLower(developerName); for (const std::string& arg : args) { if (arg[0] != '+') { continue; @@ -323,14 +294,18 @@ void CVarManager::parseCommandLine(const std::vector& args) { cv->fromLiteralToType(cvarValue); } cv->m_wasDeserialized = true; - athena::utility::tolower(cvarName); + cv->forceClearModified(); + CStringExtras::ToLower(cvarName); if (developerName == cvarName) /* Make sure we're not overriding developer mode when we restore */ oldDeveloper = com_developer->toBoolean(); } else { /* Unable to find an existing CVar, let's defer for the time being 8 */ - athena::utility::tolower(cvarName); - m_deferedCVars.insert_or_assign(std::move(cvarName), std::move(cvarValue)); + CStringExtras::ToLower(cvarName); + if (cvarValue.empty()) { + cvarValue = "true"; + } + m_deferedCVars.insert(std::make_pair(std::move(cvarName), std::move(cvarValue))); } } @@ -351,12 +326,14 @@ void CVarManager::restoreDeveloper(bool oldDeveloper) { } void CVarManager::proc() { for (const auto& [name, cvar] : m_cvars) { - if (cvar->isModified() && !cvar->modificationRequiresRestart()) { + if (cvar->isModified()) { cvar->dispatch(); + } + if (cvar->isModified() && !cvar->modificationRequiresRestart()) { // Clear the modified flag now that we've informed everyone we've changed cvar->clearModified(); } } } -} // namespace hecl +} // namespace metaforce diff --git a/hecl/include/hecl/CVarManager.hpp b/Runtime/ConsoleVariables/CVarManager.hpp similarity index 71% rename from hecl/include/hecl/CVarManager.hpp rename to Runtime/ConsoleVariables/CVarManager.hpp index 1576ce327..f13dad26c 100644 --- a/hecl/include/hecl/CVarManager.hpp +++ b/Runtime/ConsoleVariables/CVarManager.hpp @@ -3,20 +3,19 @@ #include #include #include +#include #include -#include "hecl/CVar.hpp" +#include "Runtime/ConsoleVariables/CVar.hpp" -namespace hecl { -namespace Runtime { +namespace metaforce { class FileStoreManager; -} extern CVar* com_developer; extern CVar* com_configfile; extern CVar* com_enableCheats; extern CVar* com_cubemaps; class CVarManager final { - using CVarContainer = DNACVAR::CVarContainer; + using CVarContainer = StoreCVar::CVarContainer; template CVar* _newCVar(std::string_view name, std::string_view help, const T& value, CVar::EFlags flags) { if (CVar* ret = registerCVar(std::make_unique(name, value, help, flags))) { @@ -26,7 +25,7 @@ class CVarManager final { return nullptr; } - hecl::Runtime::FileStoreManager& m_store; + FileStoreManager& m_store; bool m_useBinary; static CVarManager* m_instance; @@ -35,26 +34,30 @@ public: CVarManager(const CVarManager&) = delete; CVarManager& operator=(const CVarManager&) = delete; CVarManager& operator=(const CVarManager&&) = delete; - CVarManager(hecl::Runtime::FileStoreManager& store, bool useBinary = false); + CVarManager(FileStoreManager& store, bool useBinary = false); ~CVarManager(); - CVar* newCVar(std::string_view name, std::string_view help, const atVec2f& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); + CVar* newCVar(std::string_view name, std::string_view help, const zeus::CVector2i& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); } - CVar* newCVar(std::string_view name, std::string_view help, const atVec2d& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); + + CVar* newCVar(std::string_view name, std::string_view help, const zeus::CVector2f& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); } - CVar* newCVar(std::string_view name, std::string_view help, const atVec3f& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); + CVar* newCVar(std::string_view name, std::string_view help, const zeus::CVector2d& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); } - CVar* newCVar(std::string_view name, std::string_view help, const atVec3d& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); + CVar* newCVar(std::string_view name, std::string_view help, const zeus::CVector3f& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); } - CVar* newCVar(std::string_view name, std::string_view help, const atVec4f& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); + CVar* newCVar(std::string_view name, std::string_view help, const zeus::CVector3d& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); } - CVar* newCVar(std::string_view name, std::string_view help, const atVec4d& value, CVar::EFlags flags) { - return _newCVar(name, help, value, flags); + CVar* newCVar(std::string_view name, std::string_view help, const zeus::CVector4f& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); + } + CVar* newCVar(std::string_view name, std::string_view help, const zeus::CVector4d& value, CVar::EFlags flags) { + return _newCVar(name, help, value, flags); } CVar* newCVar(std::string_view name, std::string_view help, std::string_view value, CVar::EFlags flags) { return _newCVar(name, help, value, flags); @@ -98,22 +101,21 @@ public: void proc(); - void list(class Console* con, const std::vector& args); - void setCVar(class Console* con, const std::vector& args); - void getCVar(class Console* con, const std::vector& args); - void setDeveloperMode(bool v, bool setDeserialized = false); void setCheatsEnabled(bool v, bool setDeserialized = false); bool restartRequired() const; void parseCommandLine(const std::vector& args); + FileStoreManager& fileStoreManager() { return m_store; } + private: bool suppressDeveloper(); void restoreDeveloper(bool oldDeveloper); std::unordered_map> m_cvars; - std::unordered_map m_deferedCVars; + std::map m_deferedCVars; + std::vector loadCVars(const std::string& filename) const; }; } // namespace hecl diff --git a/Runtime/ConsoleVariables/FileStoreManager.cpp b/Runtime/ConsoleVariables/FileStoreManager.cpp new file mode 100644 index 000000000..722f0d0a5 --- /dev/null +++ b/Runtime/ConsoleVariables/FileStoreManager.cpp @@ -0,0 +1,86 @@ +#include "Runtime/ConsoleVariables/FileStoreManager.hpp" + +#include "Runtime/CBasics.hpp" + +#include +#include +#if _WIN32 +#include +#endif + +#if _WIN32 +#include +#endif + +#if WINDOWS_STORE +using namespace Windows::Storage; +#endif + +namespace metaforce { +namespace { +static logvisor::Module Log("FileStoreManager"); +FileStoreManager* g_instance = nullptr; +} + +FileStoreManager::FileStoreManager(std::string_view org, std::string_view domain) : m_org(org), m_domain(domain) { + if (g_instance != nullptr) { + Log.report(logvisor::Fatal, FMT_STRING("Attempting to build another FileStoreManager!!")); + return; + } + + auto prefPath = SDL_GetPrefPath(org.data(), domain.data()); + if (prefPath == nullptr) { +#if _WIN32 +#if !WINDOWS_STORE + WCHAR home[MAX_PATH]; + if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, home))) + Log.report(logvisor::Fatal, FMT_STRING("unable to locate profile for file store")); + + std::string path = nowide::narrow(home); +#else + StorageFolder ^ cacheFolder = ApplicationData::Current->LocalCacheFolder; + std::string path(cacheFolder->Path->Data()); +#endif + path += "/." + m_org; + + CBasics::MakeDir(path.c_str()); + path += '/'; + path += domain.data(); + + CBasics::MakeDir(path.c_str()); + m_storeRoot = path; +#else + const char* xdg_data_home = getenv("XDG_DATA_HOME"); + std::string path; + if (xdg_data_home) { + if (xdg_data_home[0] != '/') + Log.report(logvisor::Fatal, FMT_STRING("invalid $XDG_DATA_HOME for file store (must be absolute)")); + path = xdg_data_home; + } else { + const char* home = getenv("HOME"); + if (!home) + Log.report(logvisor::Fatal, FMT_STRING("unable to locate $HOME for file store")); + path = home; + path += "/.local/share"; + } + path += "/" + m_org + "/" + domain.data(); + if (CBasics::RecursiveMakeDir(path.c_str()) != 0) { + Log.report(logvisor::Fatal, FMT_STRING("unable to mkdir at {}"), path); + } + m_storeRoot = path; +#endif + } else { + m_storeRoot = std::string(prefPath); + SDL_free(prefPath); + } + g_instance = this; +} + +FileStoreManager* FileStoreManager::instance() { + if (g_instance == nullptr) { + Log.report(logvisor::Fatal, FMT_STRING("Requested FileStoreManager instance before it's built!")); + return nullptr; + } + return g_instance; +} +} // namespace hecl::Runtime diff --git a/Runtime/ConsoleVariables/FileStoreManager.hpp b/Runtime/ConsoleVariables/FileStoreManager.hpp new file mode 100644 index 000000000..143138cbf --- /dev/null +++ b/Runtime/ConsoleVariables/FileStoreManager.hpp @@ -0,0 +1,29 @@ +#pragma once +#include +#include + +namespace metaforce { +/** + * @brief Per-platform file store resolution + */ +class FileStoreManager { + std::string m_org; + std::string m_domain; + std::string m_storeRoot; + +public: + FileStoreManager(FileStoreManager&) = delete; + FileStoreManager(FileStoreManager&&) = delete; + void operator=(FileStoreManager&) = delete; + void operator=(FileStoreManager&&) = delete; + FileStoreManager(std::string_view org, std::string_view domain); + std::string_view getOrg() const { return m_org; } + std::string_view getDomain() const { return m_domain; } + /** + * @brief Returns the full path to the file store, including domain + * @return Full path to store e.g /home/foo/.hecl/bar + */ + std::string_view getStoreRoot() const { return m_storeRoot; } + static FileStoreManager* instance(); +}; +} \ No newline at end of file diff --git a/Runtime/Flags.hpp b/Runtime/Flags.hpp new file mode 100644 index 000000000..622f932cd --- /dev/null +++ b/Runtime/Flags.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include + +namespace metaforce { +template +class Flags { +public: + using MaskType = std::underlying_type_t; + + // constructors + constexpr Flags() noexcept : m_mask(0) {} + + constexpr Flags(BitType bit) noexcept : m_mask(static_cast(bit)) {} + + constexpr Flags(Flags const& rhs) noexcept : m_mask(rhs.m_mask) {} + + constexpr explicit Flags(MaskType flags) noexcept : m_mask(flags) {} + + [[nodiscard]] constexpr bool IsSet(Flags const bit) const noexcept { return bool(*this & bit); } + + // relational operators + bool operator==(Flags const& rhs) const noexcept { return m_mask == rhs.m_mask; } + + // logical operator + constexpr bool operator!() const noexcept { return !m_mask; } + + // bitwise operators + constexpr Flags operator&(Flags const& rhs) const noexcept { + return Flags(m_mask & rhs.m_mask); + } + + constexpr Flags operator|(Flags const& rhs) const noexcept { + return Flags(m_mask | rhs.m_mask); + } + + constexpr Flags operator^(Flags const& rhs) const noexcept { + return Flags(m_mask ^ rhs.m_mask); + } + + // assignment operators + constexpr Flags& operator=(Flags const& rhs) noexcept { + m_mask = rhs.m_mask; + return *this; + } + + constexpr Flags& operator|=(Flags const& rhs) noexcept { + m_mask |= rhs.m_mask; + return *this; + } + + constexpr Flags& operator&=(Flags const& rhs) noexcept { + m_mask &= rhs.m_mask; + return *this; + } + + constexpr Flags& operator^=(Flags const& rhs) noexcept { + m_mask ^= rhs.m_mask; + return *this; + } + + // cast operators + explicit constexpr operator bool() const noexcept { return m_mask != 0; } + + explicit constexpr operator MaskType() const noexcept { return m_mask; } + +private: + MaskType m_mask; +}; +} // namespace metaforce diff --git a/Runtime/GCNTypes.hpp b/Runtime/GCNTypes.hpp index 42233d831..b5cd945a9 100644 --- a/Runtime/GCNTypes.hpp +++ b/Runtime/GCNTypes.hpp @@ -11,3 +11,56 @@ using s32 = int32_t; using u32 = uint32_t; using s64 = int64_t; using u64 = uint64_t; + +#ifndef ROUND_UP_256 +#define ROUND_UP_256(val) (((val) + 255) & ~255) +#endif +#ifndef ROUND_UP_64 +#define ROUND_UP_64(val) (((val) + 63) & ~63) +#endif +#ifndef ROUND_UP_32 +#define ROUND_UP_32(val) (((val) + 31) & ~31) +#endif +#ifndef ROUND_UP_16 +#define ROUND_UP_16(val) (((val) + 15) & ~15) +#endif +#ifndef ROUND_UP_8 +#define ROUND_UP_8(val) (((val) + 7) & ~7) +#endif +#ifndef ROUND_UP_4 +#define ROUND_UP_4(val) (((val) + 3) & ~3) +#endif + +#ifndef ENABLE_BITWISE_ENUM +#define ENABLE_BITWISE_ENUM(type) \ + constexpr type operator|(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return type(static_cast(a) | static_cast(b)); \ + } \ + constexpr type operator&(type a, type b) noexcept { \ + using T = std::underlying_type_t; \ + return type(static_cast(a) & static_cast(b)); \ + } \ + constexpr type& operator|=(type& a, type b) noexcept { \ + using T = std::underlying_type_t; \ + a = type(static_cast(a) | static_cast(b)); \ + return a; \ + } \ + constexpr type& operator&=(type& a, type b) noexcept { \ + using T = std::underlying_type_t; \ + a = type(static_cast(a) & static_cast(b)); \ + return a; \ + } \ + constexpr type operator~(type key) noexcept { \ + using T = std::underlying_type_t; \ + return type(~static_cast(key)); \ + } \ + constexpr bool True(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(key) != 0; \ + } \ + constexpr bool False(type key) noexcept { \ + using T = std::underlying_type_t; \ + return static_cast(key) == 0; \ + } +#endif \ No newline at end of file diff --git a/Runtime/GameGlobalObjects.cpp b/Runtime/GameGlobalObjects.cpp index e0d532eb5..597b23a91 100644 --- a/Runtime/GameGlobalObjects.cpp +++ b/Runtime/GameGlobalObjects.cpp @@ -13,10 +13,11 @@ class CCharacterFactoryBuilder* g_CharFactoryBuilder = nullptr; class CAiFuncMap* g_AiFuncMap = nullptr; class CGameState* g_GameState = nullptr; class CInGameTweakManagerBase* g_TweakManager = nullptr; -class CBooRenderer* g_Renderer = nullptr; +class CCubeRenderer* g_Renderer = nullptr; class CStringTable* g_MainStringTable = nullptr; class CTextureCache* g_TextureCache = nullptr; class CInputGenerator* g_InputGenerator = nullptr; +class IController* g_Controller = nullptr; class CStateManager* g_StateManager = nullptr; ITweakGame* g_tweakGame = nullptr; diff --git a/Runtime/GameGlobalObjects.hpp b/Runtime/GameGlobalObjects.hpp index 7902647aa..a861c8abc 100644 --- a/Runtime/GameGlobalObjects.hpp +++ b/Runtime/GameGlobalObjects.hpp @@ -3,35 +3,37 @@ #define USE_DOWNCAST_TWEAKS 1 #if USE_DOWNCAST_TWEAKS -#include "../DataSpec/DNAMP1/Tweaks/CTweakGame.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakPlayerControl.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakPlayerGun.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakGunRes.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakPlayerRes.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakGui.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakSlideShow.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakGui.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakTargeting.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakParticle.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakBall.hpp" -#include "../DataSpec/DNAMP1/Tweaks/CTweakGuiColors.hpp" +#include "Runtime/MP1/Tweaks/CTweakAutoMapper.hpp" +#include "Runtime/MP1/Tweaks/CTweakBall.hpp" +#include "Runtime/MP1/Tweaks/CTweakGame.hpp" +#include "Runtime/MP1/Tweaks/CTweakGui.hpp" +#include "Runtime/MP1/Tweaks/CTweakGui.hpp" +#include "Runtime/MP1/Tweaks/CTweakGuiColors.hpp" +#include "Runtime/MP1/Tweaks/CTweakGunRes.hpp" +#include "Runtime/MP1/Tweaks/CTweakParticle.hpp" +#include "Runtime/MP1/Tweaks/CTweakPlayer.hpp" +#include "Runtime/MP1/Tweaks/CTweakPlayerControl.hpp" +#include "Runtime/MP1/Tweaks/CTweakPlayerGun.hpp" +#include "Runtime/MP1/Tweaks/CTweakPlayerRes.hpp" +#include "Runtime/MP1/Tweaks/CTweakSlideShow.hpp" +#include "Runtime/MP1/Tweaks/CTweakTargeting.hpp" +#include "Runtime/MP1/Tweaks/CTweakGuiColors.hpp" +#include "Runtime/MP1/Tweaks/CTweakTargeting.hpp" #else -#include "../DataSpec/DNACommon/Tweaks/ITweakGame.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakPlayer.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakPlayerControl.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakPlayerGun.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakGunRes.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakPlayerRes.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakGui.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakSlideShow.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakGui.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakTargeting.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakParticle.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakBall.hpp" -#include "../DataSpec/DNACommon/Tweaks/ITweakGuiColors.hpp" +#include "Runtime/Tweaks/ITweakAutoMapper.hpp" +#include "Runtime/Tweaks/ITweakBall.hpp" +#include "Runtime/Tweaks/ITweakGame.hpp" +#include "Runtime/Tweaks/ITweakGui.hpp" +#include "Runtime/Tweaks/ITweakGui.hpp" +#include "Runtime/Tweaks/ITweakGuiColors.hpp" +#include "Runtime/Tweaks/ITweakGunRes.hpp" +#include "Runtime/Tweaks/ITweakParticle.hpp" +#include "Runtime/Tweaks/ITweakPlayer.hpp" +#include "Runtime/Tweaks/ITweakPlayerControl.hpp" +#include "Runtime/Tweaks/ITweakPlayerGun.hpp" +#include "Runtime/Tweaks/ITweakPlayerRes.hpp" +#include "Runtime/Tweaks/ITweakSlideShow.hpp" +#include "Runtime/Tweaks/ITweakTargeting.hpp" #endif #include "Runtime/CTextureCache.hpp" @@ -48,39 +50,42 @@ extern class CCharacterFactoryBuilder* g_CharFactoryBuilder; extern class CAiFuncMap* g_AiFuncMap; extern class CGameState* g_GameState; extern class CInGameTweakManagerBase* g_TweakManager; -extern class CBooRenderer* g_Renderer; +extern class CCubeRenderer* g_Renderer; extern class CStringTable* g_MainStringTable; extern class CTextureCache* g_TextureCache; extern class CInputGenerator* g_InputGenerator; +extern class IController* g_Controller; extern class CStateManager* g_StateManager; #if USE_DOWNCAST_TWEAKS -using ITweakGame = DataSpec::DNAMP1::CTweakGame; -using ITweakPlayer = DataSpec::DNAMP1::CTweakPlayer; -using ITweakPlayerControl = DataSpec::DNAMP1::CTweakPlayerControl; -using ITweakPlayerGun = DataSpec::DNAMP1::CTweakPlayerGun; -using ITweakGunRes = DataSpec::DNAMP1::CTweakGunRes; -using ITweakAutoMapper = DataSpec::DNAMP1::CTweakAutoMapper; -using ITweakGui = DataSpec::DNAMP1::CTweakGui; -using ITweakSlideShow = DataSpec::DNAMP1::CTweakSlideShow; -using ITweakParticle = DataSpec::DNAMP1::CTweakParticle; -using ITweakBall = DataSpec::DNAMP1::CTweakBall; -using ITweakGuiColors = DataSpec::DNAMP1::CTweakGuiColors; +using ITweakGame = metaforce::MP1::CTweakGame; +using ITweakPlayer = metaforce::MP1::CTweakPlayer; +using ITweakPlayerControl = metaforce::MP1::CTweakPlayerControl; +using ITweakPlayerGun = metaforce::MP1::CTweakPlayerGun; +using ITweakGunRes = metaforce::MP1::CTweakGunRes; +using ITweakAutoMapper = metaforce::MP1::CTweakAutoMapper; +using ITweakGui = metaforce::MP1::CTweakGui; +using ITweakSlideShow = metaforce::MP1::CTweakSlideShow; +using ITweakParticle = metaforce::MP1::CTweakParticle; +using ITweakBall = metaforce::MP1::CTweakBall; +using ITweakGuiColors = metaforce::MP1::CTweakGuiColors; +using ITweakPlayerRes = metaforce::MP1::CTweakPlayerRes; +using ITweakTargeting = metaforce::MP1::CTweakTargeting; #else -using ITweakGame = DataSpec::ITweakGame; -using ITweakPlayer = DataSpec::ITweakPlayer; -using ITweakPlayerControl = DataSpec::ITweakPlayerControl; -using ITweakPlayerGun = DataSpec::ITweakPlayerGun; -using ITweakGunRes = DataSpec::ITweakGunRes; -using ITweakAutoMapper = DataSpec::ITweakAutoMapper; -using ITweakGui = DataSpec::ITweakGui; -using ITweakSlideShow = DataSpec::ITweakSlideShow; -using ITweakParticle = DataSpec::ITweakParticle; -using ITweakBall = DataSpec::ITweakBall; -using ITweakGuiColors = DataSpec::ITweakGuiColors; +using ITweakGame = metaforce::Tweaks::ITweakGame; +using ITweakPlayer = metaforce::Tweaks::ITweakPlayer; +using ITweakPlayerControl = metaforce::Tweaks::ITweakPlayerControl; +using ITweakPlayerGun = metaforce::Tweaks::ITweakPlayerGun; +using ITweakGunRes = metaforce::Tweaks::ITweakGunRes; +using ITweakAutoMapper = metaforce::Tweaks::ITweakAutoMapper; +using ITweakGui = metaforce::Tweaks::ITweakGui; +using ITweakSlideShow = metaforce::Tweaks::ITweakSlideShow; +using ITweakParticle = metaforce::Tweaks::ITweakParticle; +using ITweakBall = metaforce::Tweaks::ITweakBall; +using ITweakGuiColors = metaforce::Tweaks::ITweakGuiColors; +using ITweakPlayerRes = metaforce::Tweaks::ITweakPlayerRes; +using ITweakTargeting = metaforce::Tweaks::ITweakTargeting; #endif -using ITweakPlayerRes = DataSpec::ITweakPlayerRes; -using ITweakTargeting = DataSpec::ITweakTargeting; extern ITweakGame* g_tweakGame; extern ITweakPlayer* g_tweakPlayer; diff --git a/Runtime/GameObjectLists.cpp b/Runtime/GameObjectLists.cpp index 80b56f0e5..0fdd515c0 100644 --- a/Runtime/GameObjectLists.cpp +++ b/Runtime/GameObjectLists.cpp @@ -27,7 +27,7 @@ bool CGameCameraList::IsQualified(const CEntity& ent) const { return TCastToCons CListeningAiList::CListeningAiList() : CObjectList(EGameObjectList::ListeningAi) {} bool CListeningAiList::IsQualified(const CEntity& ent) const { - const TCastToConstPtr ai(ent); + const TCastToConstPtr ai(ent); return ai && ai->IsListening(); } diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRender.hpp.old similarity index 81% rename from Runtime/Graphics/CBooRenderer.hpp rename to Runtime/Graphics/CBooRender.hpp.old index 1f8bab6ee..89c73ef0e 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRender.hpp.old @@ -21,6 +21,7 @@ #include "Runtime/Graphics/Shaders/CThermalColdFilter.hpp" #include "Runtime/Graphics/Shaders/CThermalHotFilter.hpp" #include "Runtime/World/CGameArea.hpp" +#include "CMetroidModelInstance.hpp" #include #include @@ -101,31 +102,31 @@ class CBooRenderer final : public IRenderer { // boo::ITextureS* xe4_blackTex = nullptr; bool xee_24_ : 1 = true; - boo::ObjToken m_clearTexture; - boo::ObjToken m_blackTexture; - boo::ObjToken m_whiteTexture; - std::unordered_map> m_colorTextures; + aurora::gfx::TextureHandle m_clearTexture; + aurora::gfx::TextureHandle m_blackTexture; + aurora::gfx::TextureHandle m_whiteTexture; + std::unordered_map m_colorTextures; - boo::ObjToken x14c_reflectionTex; + aurora::gfx::TextureHandle x14c_reflectionTex; // boo::ITextureS* x150_mirrorRamp = nullptr; - boo::ObjToken x1b8_fogVolumeRamp; - boo::ObjToken x220_sphereRamp; - TLockedToken m_thermoPaletteTex; - boo::ObjToken x288_thermoPalette; - TLockedToken m_ballFadeTex; - boo::ObjToken m_ballFade; - boo::ObjToken m_ballShadowId; - boo::ObjToken m_scanLinesEvenVBO; - boo::ObjToken m_scanLinesOddVBO; +// aurora::gfx::TextureHandle x1b8_fogVolumeRamp; + aurora::gfx::TextureHandle x220_sphereRamp; +// TLockedToken m_thermoPaletteTex; +// aurora::gfx::TextureHandle x288_thermoPalette; +// TLockedToken m_ballFadeTex; + aurora::gfx::TextureHandle m_ballFade; + aurora::gfx::TextureHandle m_ballShadowId; +// boo::ObjToken m_scanLinesEvenVBO; +// boo::ObjToken m_scanLinesOddVBO; int m_ballShadowIdW = 64; int m_ballShadowIdH = 64; CRandom16 x2a8_thermalRand; std::list x2ac_fogVolumes; - std::list m_fogVolumePlaneShaders; - std::list::iterator m_nextFogVolumePlaneShader; - std::list m_fogVolumeFilters; - std::list::iterator m_nextFogVolumeFilter; +// std::list m_fogVolumePlaneShaders; +// std::list::iterator m_nextFogVolumePlaneShader; +// std::list m_fogVolumeFilters; +// std::list::iterator m_nextFogVolumeFilter; std::list> x2c4_spaceWarps; u32 x2dc_reflectionAge = 2; zeus::CColor x2e0_ = zeus::skWhite; @@ -156,11 +157,11 @@ class CBooRenderer final : public IRenderer { bool x318_31_persistRGBA6 : 1 = false; bool m_thermalHotPass : 1 = false; - void GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx); - void GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx); - void GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx); - void LoadThermoPalette(); - void LoadBallFade(); +// void GenerateFogVolumeRampTex(); +// void GenerateSphereRampTex(); +// void GenerateScanLinesVBO(); +// void LoadThermoPalette(); +// void LoadBallFade(); void ActivateLightsForModel(CAreaListItem* item, CBooModel& model); void RenderBucketItems(CAreaListItem* item); @@ -170,8 +171,7 @@ class CBooRenderer final : public IRenderer { static void DrawFogSlices(const zeus::CPlane* planes, size_t numPlanes, size_t iteration, const zeus::CVector3f& center, float delta, CFogVolumePlaneShader& fogVol); static void RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx, - const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass, - CFogVolumePlaneShader* fvs); + const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass); void SetupRendererStates() const; void ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, /*const CTexture& maskTex,*/ @@ -264,27 +264,31 @@ public: void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const CModel* model, const CSkinnedModel* sModel); - const boo::ObjToken& GetThermoPalette() const { return x288_thermoPalette; } - const boo::ObjToken& GetFogRampTex() const { return x1b8_fogVolumeRamp; } - const boo::ObjToken& GetRandomStaticEntropyTex() const { return m_staticEntropy->GetBooTexture(); } - const boo::ObjToken& GetScanLinesEvenVBO() const { return m_scanLinesEvenVBO; } - const boo::ObjToken& GetScanLinesOddVBO() const { return m_scanLinesOddVBO; } +// const boo::ObjToken& GetThermoPalette() const { return x288_thermoPalette; } +// const boo::ObjToken& GetFogRampTex() const { return x1b8_fogVolumeRamp; } +// const boo::ObjToken& GetRandomStaticEntropyTex() const { return m_staticEntropy->GetBooTexture(); } +// const boo::ObjToken& GetScanLinesEvenVBO() const { return m_scanLinesEvenVBO; } +// const boo::ObjToken& GetScanLinesOddVBO() const { return m_scanLinesOddVBO; } - const boo::ObjToken& GetClearTexture() const { return m_clearTexture; } - const boo::ObjToken& GetBlackTexture() const { return m_blackTexture; } - const boo::ObjToken& GetWhiteTexture() const { return m_whiteTexture; } + const aurora::gfx::TextureHandle& GetClearTexture() const { return m_clearTexture; } + const aurora::gfx::TextureHandle& GetBlackTexture() const { return m_blackTexture; } + const aurora::gfx::TextureHandle& GetWhiteTexture() const { return m_whiteTexture; } - boo::ObjToken GetColorTexture(const zeus::CColor& color); + aurora::gfx::TextureHandle GetColorTexture(const zeus::CColor& color); - static void BindMainDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture); } - void BindReflectionDrawTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex); } + static void BindMainDrawTarget() { +// CGraphics::g_BooMainCommandQueue->setRenderTarget(CGraphics::g_SpareTexture); + } + void BindReflectionDrawTarget() { +// CGraphics::g_BooMainCommandQueue->setRenderTarget(x14c_reflectionTex); + } void BindBallShadowIdTarget() { - CGraphics::g_BooMainCommandQueue->setRenderTarget(m_ballShadowId); +// CGraphics::g_BooMainCommandQueue->setRenderTarget(m_ballShadowId); SetViewport(0, 0, m_ballShadowIdW, m_ballShadowIdH); } void ResolveBallShadowIdTarget() { - CGraphics::g_BooMainCommandQueue->resolveBindTexture( - m_ballShadowId, boo::SWindowRect(0, 0, m_ballShadowIdW, m_ballShadowIdH), false, 0, true, false); +// CGraphics::g_BooMainCommandQueue->resolveBindTexture( +// m_ballShadowId, boo::SWindowRect(0, 0, m_ballShadowIdW, m_ballShadowIdH), false, 0, true, false); } void FindOverlappingWorldModels(std::vector& modelBits, const zeus::CAABox& aabb) const; diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index a45ce32fe..f5a41d77d 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -410,8 +409,7 @@ void CBooRenderer::DrawFogSlices(const zeus::CPlane* planes, size_t numPlanes, s } void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* model, const zeus::CTransform& modelMtx, - const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass, - CFogVolumePlaneShader* fvs) { + const zeus::CTransform& viewMtx, const CSkinnedModel* sModel, int pass) { if (!model && !sModel) { if (pass == 0) { zeus::CAABox xfAABB = aabb.getTransformedAABox(modelMtx); @@ -432,13 +430,14 @@ void CBooRenderer::RenderFogVolumeModel(const zeus::CAABox& aabb, const CModel* xfAABB.max.z() - xfAABB.min.z()) * 2.f; - fvs->reset(7 * 6); + CFogVolumePlaneShader fvs; + fvs.reset(7 * 6); for (size_t i = 0; i < planes.size(); ++i) { - DrawFogSlices(planes.data(), planes.size(), i, xfAABB.center(), longestAxis, *fvs); + DrawFogSlices(planes.data(), planes.size(), i, xfAABB.center(), longestAxis, fvs); } - fvs->draw(0); + aurora::gfx::queue_fog_volume_plane(fvs.m_verts, 0); } else { - fvs->draw(pass); + aurora::gfx::queue_fog_volume_plane({}, pass); } } else { CModelFlags flags; @@ -547,140 +546,131 @@ void CBooRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus:: zeus::CAABox marginAABB((CGraphics::g_GXModelView * aabb.min) - 1.f, (CGraphics::g_GXModelView * aabb.max) + 1.f); bool camInModel = marginAABB.pointInside(CGraphics::g_ViewMatrix.origin) && (model || sModel); - CFogVolumePlaneShader* fvs; - if (!model && !sModel) { - fvs = &*((m_nextFogVolumePlaneShader == m_fogVolumePlaneShaders.end()) - ? m_fogVolumePlaneShaders.insert(m_fogVolumePlaneShaders.end(), CFogVolumePlaneShader()) - : m_nextFogVolumePlaneShader++); - } else { - fvs = nullptr; - } +// CFogVolumePlaneShader* fvs; +// if (!model && !sModel) { +// fvs = &*((m_nextFogVolumePlaneShader == m_fogVolumePlaneShaders.end()) +// ? m_fogVolumePlaneShaders.insert(m_fogVolumePlaneShaders.end(), CFogVolumePlaneShader()) +// : m_nextFogVolumePlaneShader++); +// } else { +// fvs = nullptr; +// } - RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 0, fvs); + RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 0); if (camInModel) - RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 1, fvs); + RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 1); CGraphics::ResolveSpareDepth(rect, 0); - RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 2, fvs); + RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 2); if (camInModel) - RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 3, fvs); + RenderFogVolumeModel(aabb, model, CGraphics::g_GXModelMatrix, CGraphics::g_ViewMatrix, sModel, 3); CGraphics::ResolveSpareDepth(rect, 1); - auto fvf = (m_nextFogVolumeFilter == m_fogVolumeFilters.end()) - ? m_fogVolumeFilters.insert(m_fogVolumeFilters.end(), CFogVolumeFilter()) - : m_nextFogVolumeFilter++; - fvf->draw2WayPass(color); + aurora::gfx::queue_fog_volume_filter(color, true); if (camInModel) - fvf->draw1WayPass(color); + aurora::gfx::queue_fog_volume_filter(color, false); // CGraphics::SetScissor(g_Viewport.x0_left, g_Viewport.x4_top, g_Viewport.x8_width, g_Viewport.xc_height); } -void CBooRenderer::GenerateFogVolumeRampTex(boo::IGraphicsDataFactory::Context& ctx) { - std::array, FOGVOL_RAMP_RES> data{}; - for (size_t y = 0; y < data.size(); ++y) { - for (size_t x = 0; x < data[y].size(); ++x) { - const int tmp = int(y << 16 | x << 8 | 0x7f); - const double a = - zeus::clamp(0.0, - (-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) * - 3.0 / (FOGVOL_FAR - FOGVOL_NEAR), - 1.0); - data[y][x] = u16((a * a + a) / 2.0 * 65535); - } - } - x1b8_fogVolumeRamp = - ctx.newStaticTexture(FOGVOL_RAMP_RES, FOGVOL_RAMP_RES, 1, boo::TextureFormat::I16, boo::TextureClampMode::Repeat, - data[0].data(), FOGVOL_RAMP_RES * FOGVOL_RAMP_RES * 2); -} +//void CBooRenderer::GenerateFogVolumeRampTex() { +// std::array, FOGVOL_RAMP_RES> data{}; +// for (size_t y = 0; y < data.size(); ++y) { +// for (size_t x = 0; x < data[y].size(); ++x) { +// const int tmp = int(y << 16 | x << 8 | 0x7f); +// const double a = +// zeus::clamp(0.0, +// (-150.0 / (tmp / double(0xffffff) * (FOGVOL_FAR - FOGVOL_NEAR) - FOGVOL_FAR) - FOGVOL_NEAR) * +// 3.0 / (FOGVOL_FAR - FOGVOL_NEAR), +// 1.0); +// data[y][x] = (a * a + a) / 2.0; +// } +// } +// x1b8_fogVolumeRamp = +// aurora::new_static_texture_2d(FOGVOL_RAMP_RES, FOGVOL_RAMP_RES, 1, aurora::gfx::TextureFormat::R32Float, +// {data[0].data(), FOGVOL_RAMP_RES * FOGVOL_RAMP_RES * 2}); +//} +// +//void CBooRenderer::GenerateSphereRampTex() { +// std::array, SPHERE_RAMP_RES> data{}; +// constexpr float halfRes = SPHERE_RAMP_RES / 2.f; +// for (size_t y = 0; y < data.size(); ++y) { +// for (size_t x = 0; x < data[y].size(); ++x) { +// const zeus::CVector2f vec((float(x) - halfRes) / halfRes, (float(y) - halfRes) / halfRes); +// data[y][x] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255; +// } +// } +// x220_sphereRamp = +// aurora::new_static_texture_2d(SPHERE_RAMP_RES, SPHERE_RAMP_RES, 1, aurora::gfx::TextureFormat::R8, +// {data[0].data(), SPHERE_RAMP_RES * SPHERE_RAMP_RES}); +//} +// +//void CBooRenderer::GenerateScanLinesVBO() { +// std::vector verts; +// verts.reserve(670); +// +// for (int i = 0; i < 112; ++i) { +// verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); +// if (i != 0) { +// verts.emplace_back(verts.back()); +// } +// verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) - (1.f / 448.f)) * 2.f - 1.f, 0.f); +// verts.emplace_back(1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); +// verts.emplace_back(1.f, (float(i) * (4.f / 448.f) - (1.f / 448.f)) * 2.f - 1.f, 0.f); +// if (i != 111) { +// verts.emplace_back(verts.back()); +// } +// } +// +// m_scanLinesEvenVBO = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(zeus::CVector3f), verts.size()); +// +// verts.clear(); +// +// for (int i = 0; i < 112; ++i) { +// verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) + (3.f / 448.f)) * 2.f - 1.f, 0.f); +// if (i != 0) { +// verts.emplace_back(verts.back()); +// } +// verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); +// verts.emplace_back(1.f, (float(i) * (4.f / 448.f) + (3.f / 448.f)) * 2.f - 1.f, 0.f); +// verts.emplace_back(1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); +// if (i != 111) { +// verts.emplace_back(verts.back()); +// } +// } +// +// m_scanLinesOddVBO = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(zeus::CVector3f), verts.size()); +//} -void CBooRenderer::GenerateSphereRampTex(boo::IGraphicsDataFactory::Context& ctx) { - std::array, SPHERE_RAMP_RES> data{}; - constexpr float halfRes = SPHERE_RAMP_RES / 2.f; - for (size_t y = 0; y < data.size(); ++y) { - for (size_t x = 0; x < data[y].size(); ++x) { - const zeus::CVector2f vec((float(x) - halfRes) / halfRes, (float(y) - halfRes) / halfRes); - data[y][x] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255; - } - } - x220_sphereRamp = - ctx.newStaticTexture(SPHERE_RAMP_RES, SPHERE_RAMP_RES, 1, boo::TextureFormat::I8, - boo::TextureClampMode::ClampToEdge, data[0].data(), SPHERE_RAMP_RES * SPHERE_RAMP_RES); -} - -void CBooRenderer::GenerateScanLinesVBO(boo::IGraphicsDataFactory::Context& ctx) { - std::vector verts; - verts.reserve(670); - - for (int i = 0; i < 112; ++i) { - verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); - if (i != 0) { - verts.emplace_back(verts.back()); - } - verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) - (1.f / 448.f)) * 2.f - 1.f, 0.f); - verts.emplace_back(1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); - verts.emplace_back(1.f, (float(i) * (4.f / 448.f) - (1.f / 448.f)) * 2.f - 1.f, 0.f); - if (i != 111) { - verts.emplace_back(verts.back()); - } - } - - m_scanLinesEvenVBO = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(zeus::CVector3f), verts.size()); - - verts.clear(); - - for (int i = 0; i < 112; ++i) { - verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) + (3.f / 448.f)) * 2.f - 1.f, 0.f); - if (i != 0) { - verts.emplace_back(verts.back()); - } - verts.emplace_back(-1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); - verts.emplace_back(1.f, (float(i) * (4.f / 448.f) + (3.f / 448.f)) * 2.f - 1.f, 0.f); - verts.emplace_back(1.f, (float(i) * (4.f / 448.f) + (1.f / 448.f)) * 2.f - 1.f, 0.f); - if (i != 111) { - verts.emplace_back(verts.back()); - } - } - - m_scanLinesOddVBO = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(zeus::CVector3f), verts.size()); -} - -boo::ObjToken CBooRenderer::GetColorTexture(const zeus::CColor& color) { +aurora::gfx::TextureHandle CBooRenderer::GetColorTexture(const zeus::CColor& color) { const auto search = m_colorTextures.find(color); if (search != m_colorTextures.end()) { return search->second; } - std::array pixel; + std::array pixel{}; color.toRGBA8(pixel[0], pixel[1], pixel[2], pixel[3]); - boo::ObjToken tex; - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - tex = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, pixel.data(), - pixel.size()) - .get(); - return true; - } BooTrace); + auto tex = aurora::gfx::new_static_texture_2d(1, 1, 1, aurora::gfx::TextureFormat::RGBA8, pixel, "Color Texture"); m_colorTextures.emplace(color, tex); return tex; } -void CBooRenderer::LoadThermoPalette() { - m_thermoPaletteTex = xc_store.GetObj("TXTR_ThermoPalette"); - CTexture* thermoTexObj = m_thermoPaletteTex.GetObj(); - if (thermoTexObj) - x288_thermoPalette = thermoTexObj->GetPaletteTexture(); -} - -void CBooRenderer::LoadBallFade() { - m_ballFadeTex = xc_store.GetObj("TXTR_BallFade"); - CTexture* ballFadeTexObj = m_ballFadeTex.GetObj(); - if (ballFadeTexObj) { - m_ballFade = ballFadeTexObj->GetBooTexture(); - m_ballFade->setClampMode(boo::TextureClampMode::ClampToEdge); - } -} +//void CBooRenderer::LoadThermoPalette() { +// m_thermoPaletteTex = xc_store.GetObj("TXTR_ThermoPalette"); +// CTexture* thermoTexObj = m_thermoPaletteTex.GetObj(); +// if (thermoTexObj) +// x288_thermoPalette = thermoTexObj->GetPaletteTexture(); +//} +// +//void CBooRenderer::LoadBallFade() { +// m_ballFadeTex = xc_store.GetObj("TXTR_BallFade"); +// CTexture* ballFadeTexObj = m_ballFadeTex.GetObj(); +// if (ballFadeTexObj) { +// m_ballFade = ballFadeTexObj->GetBooTexture(); +// m_ballFade->setClampMode(boo::TextureClampMode::ClampToEdge); +// } +//} CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) : x8_factory(resFac), xc_store(store), x2a8_thermalRand(20) { @@ -688,36 +678,32 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) m_staticEntropy = store.GetObj("RandomStaticEntropy"); - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - constexpr std::array clearPixel{0, 0, 0, 0}; - m_clearTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - clearPixel.data(), clearPixel.size()) - .get(); - constexpr std::array blackPixel{0, 0, 0, 255}; - m_blackTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - blackPixel.data(), blackPixel.size()) - .get(); - constexpr std::array whitePixel{255, 255, 255, 255}; - m_whiteTexture = ctx.newStaticTexture(1, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - whitePixel.data(), whitePixel.size()) - .get(); + constexpr std::array clearPixel{0, 0, 0, 0}; + m_clearTexture = + aurora::gfx::new_static_texture_2d(1, 1, 1, aurora::gfx::TextureFormat::RGBA8, clearPixel, "Clear Texture"); + constexpr std::array blackPixel{0, 0, 0, 255}; + m_blackTexture = + aurora::gfx::new_static_texture_2d(1, 1, 1, aurora::gfx::TextureFormat::RGBA8, blackPixel, "Black Texture"); + constexpr std::array whitePixel{255, 255, 255, 255}; + m_whiteTexture = + aurora::gfx::new_static_texture_2d(1, 1, 1, aurora::gfx::TextureFormat::RGBA8, whitePixel, "White Texture"); - GenerateFogVolumeRampTex(ctx); - GenerateSphereRampTex(ctx); - m_ballShadowId = ctx.newRenderTexture(m_ballShadowIdW, m_ballShadowIdH, boo::TextureClampMode::Repeat, 1, 0); - x14c_reflectionTex = ctx.newRenderTexture(256, 256, boo::TextureClampMode::ClampToBlack, 1, 0); - GenerateScanLinesVBO(ctx); - return true; - } BooTrace); - LoadThermoPalette(); - LoadBallFade(); + // GenerateFogVolumeRampTex(); +// GenerateSphereRampTex(); + m_ballShadowId = aurora::gfx::new_render_texture(m_ballShadowIdW, m_ballShadowIdH, 1, 0, "Ball Shadow"); +// m_ballShadowId = ctx.newRenderTexture(m_ballShadowIdW, m_ballShadowIdH, boo::TextureClampMode::Repeat, 1, 0); + x14c_reflectionTex = aurora::gfx::new_render_texture(256, 256, 1, 0, "Reflection"); +// x14c_reflectionTex = ctx.newRenderTexture(256, 256, boo::TextureClampMode::ClampToBlack, 1, 0); +// GenerateScanLinesVBO(); +// LoadThermoPalette(); +// LoadBallFade(); m_thermColdFilter.emplace(); m_thermHotFilter.emplace(); Buckets::Init(); - m_nextFogVolumePlaneShader = m_fogVolumePlaneShaders.end(); - m_nextFogVolumeFilter = m_fogVolumeFilters.end(); +// m_nextFogVolumePlaneShader = m_fogVolumePlaneShaders.end(); +// m_nextFogVolumeFilter = m_fogVolumeFilters.end(); } CBooRenderer::~CBooRenderer() { g_Renderer = nullptr; } @@ -725,11 +711,11 @@ CBooRenderer::~CBooRenderer() { g_Renderer = nullptr; } void CBooRenderer::AddWorldSurfaces(CBooModel& model) { CBooSurface* surf = model.x3c_firstSortedSurface; while (surf) { - const MaterialSet::Material& mat = model.GetMaterialByIndex(surf->m_data.matIdx); +// const MaterialSet::Material& mat = model.GetMaterialByIndex(surf->m_data.matIdx); zeus::CAABox aabb = surf->GetBounds(); zeus::CVector3f pt = aabb.closestPointAlongVector(xb0_viewPlane.normal()); Buckets::Insert(pt, aabb, EDrawableType::WorldSurface, surf, xb0_viewPlane, - mat.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Alpha); + /*mat.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Alpha*/ false); surf = surf->m_next; } } @@ -792,23 +778,20 @@ void CBooRenderer::UpdateAreaUniforms(int areaIdx, EWorldShadowMode shadowMode, if (areaIdx != -1 && item.x18_areaIdx != areaIdx) continue; - item.m_shaderSet->m_geomLayout->Update(flags, nullptr, nullptr, &item.m_shaderSet->m_matSet, - item.m_shaderSet->m_geomLayout->GetSharedBuffer(bufIdx), nullptr); +// item.m_shaderSet->m_geomLayout->Update(flags, nullptr, nullptr, &item.m_shaderSet->m_matSet, +// item.m_shaderSet->m_geomLayout->GetSharedBuffer(bufIdx), nullptr); if (shadowMode == EWorldShadowMode::BallOnWorldShadow || shadowMode == EWorldShadowMode::BallOnWorldIds) continue; - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - for (auto it = item.x10_models.begin(); it != item.x10_models.end(); ++it) { - CBooModel* model = *it; - if (model->TryLockTextures()) { - if (activateLights) - ActivateLightsForModel(&item, *model); - model->UpdateUniformData(flags, nullptr, nullptr, bufIdx, &ctx); - } + for (auto it = item.x10_models.begin(); it != item.x10_models.end(); ++it) { + CBooModel* model = *it; + if (model->TryLockTextures()) { + if (activateLights) + ActivateLightsForModel(&item, *model); +// model->UpdateUniformData(flags, nullptr, nullptr, bufIdx); } - return true; - } BooTrace); + } } } @@ -1084,8 +1067,8 @@ void CBooRenderer::BeginScene() { x318_26_requestRGBA6 = false; // GXSetPixelFmt(x318_27_currentRGBA6); CGraphics::BeginScene(); - m_nextFogVolumePlaneShader = m_fogVolumePlaneShaders.begin(); - m_nextFogVolumeFilter = m_fogVolumeFilters.begin(); +// m_nextFogVolumePlaneShader = m_fogVolumePlaneShaders.begin(); +// m_nextFogVolumeFilter = m_fogVolumeFilters.begin(); } void CBooRenderer::EndScene() { @@ -1111,15 +1094,16 @@ void CBooRenderer::CacheReflection(TReflectionCallback cb, void* ctx, bool clear x318_24_refectionDirty = false; x2dc_reflectionAge = 0; - BindReflectionDrawTarget(); - SViewport backupVp = g_Viewport; - SetViewport(0, 0, 256, 256); - CGraphics::g_BooMainCommandQueue->clearTarget(); - cb(ctx, CBooModel::g_ReflectViewPos); - boo::SWindowRect rect(0, 0, 256, 256); - CGraphics::g_BooMainCommandQueue->resolveBindTexture(x14c_reflectionTex, rect, false, 0, true, false); - BindMainDrawTarget(); - SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height); + // TODO + // BindReflectionDrawTarget(); + // SViewport backupVp = g_Viewport; + // SetViewport(0, 0, 256, 256); + // CGraphics::g_BooMainCommandQueue->clearTarget(); + // cb(ctx, CBooModel::g_ReflectViewPos); + // boo::SWindowRect rect(0, 0, 256, 256); + // CGraphics::g_BooMainCommandQueue->resolveBindTexture(x14c_reflectionTex, rect, false, 0, true, false); + // BindMainDrawTarget(); + // SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height); } void CBooRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength) { @@ -1152,7 +1136,7 @@ void CBooRenderer::DrawXRayOutline(const zeus::CAABox& aabb) { for (u32 b = 0; b < 32; ++b) { if ((bitmap[c] & (1U << b)) != 0) { CBooModel* model = item.x10_models[c * 32 + b]; - model->UpdateUniformData(flags, nullptr, nullptr); +// model->UpdateUniformData(flags, nullptr, nullptr); const CBooSurface* surf = model->x38_firstUnsortedSurface; while (surf) { if (surf->GetBounds().intersects(aabb)) @@ -1362,7 +1346,7 @@ int CBooRenderer::DrawOverlappingWorldModelIDs(int alphaVal, const std::vector(alphaVal) / 255.f; CBooModel& model = *item.x10_models[wordModel + j]; - model.UpdateUniformData(flags, nullptr, nullptr, 3); +// model.UpdateUniformData(flags, nullptr, nullptr, 3); model.VerifyCurrentShader(0); for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) { if (surf->GetBounds().intersects(aabb)) { @@ -1409,7 +1393,7 @@ void CBooRenderer::DrawOverlappingWorldModelShadows(int alphaVal, const std::vec flags.x4_color.r() = static_cast(alphaVal) / 255.f; CBooModel& model = *item.x10_models[wordModel + j]; - model.UpdateUniformData(flags, nullptr, nullptr, 2); +// model.UpdateUniformData(flags, nullptr, nullptr, 2); model.VerifyCurrentShader(0); for (const CBooSurface* surf = model.x38_firstUnsortedSurface; surf; surf = surf->m_next) if (surf->GetBounds().intersects(aabb)) diff --git a/Runtime/Graphics/CCubeMaterial.cpp b/Runtime/Graphics/CCubeMaterial.cpp new file mode 100644 index 000000000..f7c23dedd --- /dev/null +++ b/Runtime/Graphics/CCubeMaterial.cpp @@ -0,0 +1,584 @@ +#include "Graphics/CCubeMaterial.hpp" + +#include "GameGlobalObjects.hpp" +#include "Graphics/CCubeModel.hpp" +#include "Graphics/CCubeRenderer.hpp" +#include "Graphics/CCubeSurface.hpp" +#include "Graphics/CGX.hpp" +#include "Graphics/CModel.hpp" + +namespace metaforce { +static u32 sReflectionType = 0; +static u32 sLastMaterialUnique = UINT32_MAX; +static const u8* sLastMaterialCached = nullptr; +static const CCubeModel* sLastModelCached = nullptr; +static const CCubeModel* sRenderingModel = nullptr; +static float sReflectionAlpha = 0.f; + +void CCubeMaterial::SetCurrent(const CModelFlags& flags, const CCubeSurface& surface, CCubeModel& model) { + if (sLastMaterialCached == x0_data) { + if (sReflectionType == 1) { + if (sLastModelCached == sRenderingModel) { + return; + } + } else if (sReflectionType != 2) { + return; + } + } + + if (CCubeModel::sRenderModelBlack) { + SetCurrentBlack(); + return; + } + + sRenderingModel = &model; + sLastMaterialCached = x0_data; + + u32 numIndStages = 0; + const auto matFlags = GetFlags(); + const u8* materialDataCur = x0_data; + + const bool reflection = bool( + matFlags & (Flags(CCubeMaterialFlagBits::fSamusReflection) | CCubeMaterialFlagBits::fSamusReflectionSurfaceEye)); + if (reflection) { + if (!(matFlags & CCubeMaterialFlagBits::fSamusReflectionSurfaceEye)) { + EnsureViewDepStateCached(nullptr); + } else { + EnsureViewDepStateCached(&surface); + } + } + + u32 texCount = SBig(*reinterpret_cast(materialDataCur + 4)); + if (flags.x2_flags & CModelFlagBits::NoTextureLock) { + materialDataCur += (2 + texCount) * 4; + } else { + materialDataCur += 8; + for (u32 i = 0; i < texCount; ++i) { + u32 texIdx = SBig(*reinterpret_cast(materialDataCur)); + model.GetTexture(texIdx)->Load(static_cast(i), EClampMode::Repeat); + materialDataCur += 4; + } + } + + auto groupIdx = SBig(*reinterpret_cast(materialDataCur + 4)); + if (sLastMaterialUnique != UINT32_MAX && sLastMaterialUnique == groupIdx && sReflectionType == 0) { + return; + } + sLastMaterialUnique = groupIdx; + + u32 vatFlags = SBig(*reinterpret_cast(materialDataCur)); + CGX::SetVtxDescv_Compressed(vatFlags); + materialDataCur += 8; + + bool packedLightMaps = matFlags.IsSet(CCubeMaterialFlagBits::fLightmapUvArray); + if (packedLightMaps != CCubeModel::sUsingPackedLightmaps) { + model.SetUsingPackedLightmaps(packedLightMaps); + } + + u32 finalKColorCount = 0; + if (matFlags & CCubeMaterialFlagBits::fKonstValues) { + u32 konstCount = SBig(*reinterpret_cast(materialDataCur)); + finalKColorCount = konstCount; + materialDataCur += 4; + for (u32 i = 0; i < konstCount; ++i) { + u32 kColor = SBig(*reinterpret_cast(materialDataCur)); + materialDataCur += 4; + CGX::SetTevKColor(static_cast(i), kColor); + } + } + + u32 blendFactors = SBig(*reinterpret_cast(materialDataCur)); + materialDataCur += 4; + if (g_Renderer->IsInAreaDraw()) { + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + } else { + SetupBlendMode(blendFactors, flags, matFlags.IsSet(CCubeMaterialFlagBits::fAlphaTest)); + } + + bool indTex = matFlags.IsSet(CCubeMaterialFlagBits::fSamusReflectionIndirectTexture); + u32 indTexSlot = 0; + if (indTex) { + indTexSlot = SBig(*reinterpret_cast(materialDataCur)); + materialDataCur += 4; + } + + HandleDepth(flags.x2_flags, matFlags); + + u32 chanCount = SBig(*reinterpret_cast(materialDataCur)); + materialDataCur += 4; + u32 firstChan = SBig(*reinterpret_cast(materialDataCur)); + materialDataCur += 4 * chanCount; + u32 finalNumColorChans = HandleColorChannels(chanCount, firstChan); + + u32 firstTev = 0; + if (CCubeModel::sRenderModelShadow) + firstTev = 2; + + u32 matTevCount = SBig(*reinterpret_cast(materialDataCur)); + materialDataCur += 4; + u32 finalTevCount = matTevCount; + + const u32* texMapTexCoordFlags = reinterpret_cast(materialDataCur + matTevCount * 20); + const u32* tcgs = reinterpret_cast(texMapTexCoordFlags + matTevCount); + bool usesTevReg2 = false; + + u32 finalCCFlags = 0; + u32 finalACFlags = 0; + + if (g_Renderer->IsThermalVisorActive()) { + finalTevCount = firstTev + 1; + u32 ccFlags = SBig(*reinterpret_cast(materialDataCur + 8)); + finalCCFlags = ccFlags; + auto outputReg = static_cast(ccFlags >> 9 & 0x3); + if (outputReg == GX_TEVREG0) { + materialDataCur += 20; + texMapTexCoordFlags += 1; + finalCCFlags = SBig(*reinterpret_cast(materialDataCur + 8)); + GXSetTevColor(GX_TEVREG0, GXColor{0xc0, 0xc0, 0xc0, 0xc0}); + } + finalACFlags = SBig(*reinterpret_cast(materialDataCur + 12)); + HandleTev(firstTev, reinterpret_cast(materialDataCur), texMapTexCoordFlags, + CCubeModel::sRenderModelShadow); + usesTevReg2 = false; + } else { + finalTevCount = firstTev + matTevCount; + for (u32 i = firstTev; i < finalTevCount; ++i) { + HandleTev(i, reinterpret_cast(materialDataCur), texMapTexCoordFlags, + CCubeModel::sRenderModelShadow && i == firstTev); + u32 ccFlags = SBig(*reinterpret_cast(materialDataCur + 8)); + finalCCFlags = ccFlags; + finalACFlags = SBig(*reinterpret_cast(materialDataCur + 12)); + auto outputReg = static_cast(ccFlags >> 9 & 0x3); + if (outputReg == GX_TEVREG2) { + usesTevReg2 = true; + } + materialDataCur += 20; + texMapTexCoordFlags += 1; + } + } + + u32 tcgCount = 0; + if (g_Renderer->IsThermalVisorActive()) { + u32 fullTcgCount = SBig(*tcgs); + tcgCount = std::min(fullTcgCount, 2u); + for (u32 i = 0; i < tcgCount; ++i) { + CGX::SetTexCoordGen(GXTexCoordID(i), SBig(tcgs[i + 1])); + } + tcgs += fullTcgCount + 1; + } else { + tcgCount = SBig(*tcgs); + for (u32 i = 0; i < tcgCount; ++i) { + CGX::SetTexCoordGen(GXTexCoordID(i), SBig(tcgs[i + 1])); + } + tcgs += tcgCount + 1; + } + + const u32* uvAnim = tcgs; + u32 animCount = SBig(uvAnim[1]); + uvAnim += 2; + u32 texMtx = GX_TEXMTX0; + u32 pttTexMtx = GX_PTTEXMTX0; + for (u32 i = 0; i < animCount; ++i) { + u32 size = HandleAnimatedUV(uvAnim, static_cast(texMtx), static_cast(pttTexMtx)); + if (size == 0) + break; + uvAnim += size; + texMtx += 3; + pttTexMtx += 3; + } + + if (flags.x0_blendMode != 0) { + HandleTransparency(finalTevCount, finalKColorCount, flags, blendFactors, finalCCFlags, finalACFlags); + } + + if (reflection) { + if (sReflectionAlpha > 0.f) { + u32 additionalTevs = 0; + if (indTex) { + additionalTevs = HandleReflection(usesTevReg2, indTexSlot, 0, finalTevCount, texCount, tcgCount, + finalKColorCount, finalCCFlags, finalACFlags); + numIndStages = 1; + tcgCount += 2; + } else { + additionalTevs = HandleReflection(usesTevReg2, 255, 0, finalTevCount, texCount, tcgCount, finalKColorCount, + finalCCFlags, finalACFlags); + tcgCount += 1; + } + texCount += 1; + finalTevCount += additionalTevs; + finalKColorCount += 1; + } else if (((finalCCFlags >> 9) & 0x3) != 0) { + DoPassthru(finalTevCount); + finalTevCount += 1; + } + } + + if (CCubeModel::sRenderModelShadow) { + DoModelShadow(texCount, tcgCount); + tcgCount += 1; + } + + CGX::SetNumIndStages(numIndStages); + CGX::SetNumTevStages(finalTevCount); + CGX::SetNumTexGens(tcgCount); + CGX::SetNumChans(finalNumColorChans); +} + +void CCubeMaterial::SetCurrentBlack() { + const auto flags = GetFlags(); + const auto vatFlags = GetVatFlags(); + if (flags.IsSet(CCubeMaterialFlagBits::fDepthSorting) || flags.IsSet(CCubeMaterialFlagBits::fAlphaTest)) { + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_ZERO, GX_BL_ONE, GX_LO_CLEAR); + } else { + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + } + CGX::SetVtxDescv_Compressed(vatFlags); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO /* ? CC_ONE */); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO /* ? CA_KONST */); + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_1); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_POS, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetNumTevStages(1); + CGX::SetNumChans(0); + CGX::SetNumTexGens(1); + CGX::SetNumIndStages(0); +} + +void CCubeMaterial::SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest) { + auto newSrcFactor = static_cast(blendFactors & 0xffff); + auto newDstFactor = static_cast(blendFactors >> 16 & 0xffff); + if (alphaTest) { + // discard fragments with alpha < 0.25 + CGX::SetAlphaCompare(GX_GEQUAL, 64, GX_AOP_OR, GX_NEVER, 0); + newSrcFactor = GX_BL_ONE; + newDstFactor = GX_BL_ZERO; + } else { + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + } + + if (flags.x0_blendMode > 4 && newSrcFactor == GX_BL_ONE) { + newSrcFactor = GX_BL_SRCALPHA; + if (newDstFactor == GX_BL_ZERO) { + newDstFactor = flags.x0_blendMode > 6 ? GX_BL_ONE : GX_BL_INVSRCALPHA; + } + } + + CGX::SetBlendMode(GX_BM_BLEND, newSrcFactor, newDstFactor, GX_LO_CLEAR); +} + +void CCubeMaterial::HandleDepth(CModelFlagsFlags modelFlags, CCubeMaterialFlags matFlags) { + GXCompare func = GX_NEVER; + if (!(modelFlags & CModelFlagBits::DepthTest)) { + func = GX_ALWAYS; + } else if (modelFlags & CModelFlagBits::DepthGreater) { + func = modelFlags & CModelFlagBits::DepthNonInclusive ? GX_GREATER : GX_GEQUAL; + } else { + func = modelFlags & CModelFlagBits::DepthNonInclusive ? GX_LESS : GX_LEQUAL; + } + bool depthWrite = modelFlags & CModelFlagBits::DepthUpdate && matFlags & CCubeMaterialFlagBits::fDepthWrite; + CGX::SetZMode(true, func, depthWrite); +} + +void CCubeMaterial::ResetCachedMaterials() { + KillCachedViewDepState(); + sLastMaterialUnique = UINT32_MAX; + sRenderingModel = nullptr; + sLastMaterialCached = nullptr; +} + +void CCubeMaterial::KillCachedViewDepState() { sLastModelCached = nullptr; } + +void CCubeMaterial::EnsureViewDepStateCached(const CCubeSurface* surface) { + // TODO + if ((surface != nullptr || sLastModelCached != sRenderingModel) && sRenderingModel != nullptr) { + sLastModelCached = sRenderingModel; + if (surface == nullptr) { + sReflectionType = 1; + } else { + sReflectionType = 2; + } + if (g_Renderer->IsReflectionDirty()) { + + } else { + g_Renderer->SetReflectionDirty(true); + } + } +} + +u32 CCubeMaterial::HandleColorChannels(u32 chanCount, u32 firstChan) { + if (CCubeModel::sRenderModelShadow) { + if (chanCount != 0) { + CGX::SetChanAmbColor(CGX::EChannelId::Channel1, GX_BLACK); + CGX::SetChanMatColor(CGX::EChannelId::Channel1, GX_WHITE); + + auto chan0Lights = CGraphics::g_LightActive & ~CCubeModel::sChannel0DisableLightMask; + CGX::SetChanCtrl(CGX::EChannelId::Channel0, firstChan, chan0Lights); + CGX::SetChanCtrl(CGX::EChannelId::Channel1, CCubeModel::sChannel1EnableLightMask); + if (chan0Lights.any()) { + CGX::SetChanMatColor(CGX::EChannelId::Channel0, GX_WHITE); + } else { + CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0)); + } + } + return 2; + } + + if (chanCount == 2) { + CGX::SetChanAmbColor(CGX::EChannelId::Channel1, GX_BLACK); + CGX::SetChanMatColor(CGX::EChannelId::Channel1, GX_WHITE); + } else { + CGX::SetChanCtrl(CGX::EChannelId::Channel1, {}); + } + + if (chanCount == 0) { + CGX::SetChanCtrl(CGX::EChannelId::Channel0, {}); + } else { + CGX::SetChanCtrl(CGX::EChannelId::Channel0, firstChan, CGraphics::g_LightActive); + if (CGraphics::g_LightActive.any()) { + CGX::SetChanMatColor(CGX::EChannelId::Channel0, GX_WHITE); + } else { + CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0)); + } + } + + return chanCount; +} + +void CCubeMaterial::HandleTev(u32 tevCur, const u32* materialDataCur, const u32* texMapTexCoordFlags, + bool shadowMapsEnabled) { + const u32 colorArgs = shadowMapsEnabled ? 0x7a04f : SBig(materialDataCur[0]); + const u32 alphaArgs = SBig(materialDataCur[1]); + const u32 colorOps = SBig(materialDataCur[2]); + const u32 alphaOps = SBig(materialDataCur[3]); + + const auto stage = static_cast(tevCur); + CGX::SetStandardDirectTev_Compressed(stage, colorArgs, alphaArgs, colorOps, alphaOps); + + u32 tmtcFlags = SBig(*texMapTexCoordFlags); + u32 matFlags = SBig(materialDataCur[4]); + CGX::SetTevOrder(stage, static_cast(tmtcFlags & 0xFF), static_cast(tmtcFlags >> 8 & 0xFF), + static_cast(matFlags & 0xFF)); + CGX::SetTevKColorSel(stage, static_cast(matFlags >> 0x8 & 0xFF)); + CGX::SetTevKAlphaSel(stage, static_cast(matFlags >> 0x10 & 0xFF)); +} + +constexpr zeus::CTransform MvPostXf{ + {zeus::CVector3f{0.5f, 0.f, 0.f}, {0.f, 0.f, 0.f}, {0.f, 0.5f, 0.f}}, + {0.5f, 0.5f, 1.f}, +}; + +u32 CCubeMaterial::HandleAnimatedUV(const u32* uvAnim, GXTexMtx texMtx, GXPTTexMtx pttTexMtx) { + u32 type = SBig(*uvAnim); + const float* params = reinterpret_cast(uvAnim + 1); + switch (type) { + case 0: { + auto xf = CGraphics::g_ViewMatrix.inverse().multiplyIgnoreTranslation(CGraphics::g_GXModelMatrix); + xf.origin.zeroOut(); + GXLoadTexMtxImm(&xf, texMtx, GX_MTX3x4); + GXLoadTexMtxImm(&MvPostXf, pttTexMtx, GX_MTX3x4); + return 1; + } + case 1: { + auto xf = CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix; + GXLoadTexMtxImm(&xf, texMtx, GX_MTX3x4); + GXLoadTexMtxImm(&MvPostXf, pttTexMtx, GX_MTX3x4); + return 1; + } + case 2: { + const float f1 = SBig(params[0]); + const float f2 = SBig(params[1]); + const float f3 = SBig(params[2]); + const float f4 = SBig(params[3]); + const float seconds = CGraphics::GetSecondsMod900(); + const auto xf = zeus::CTransform::Translate(seconds * f3 + f1, seconds * f4 + f2, 0.f); + GXLoadTexMtxImm(&xf, texMtx, GX_MTX3x4); + return 5; + } + case 3: { + const float angle = CGraphics::GetSecondsMod900() * SBig(params[1]) + SBig(params[0]); + const float acos = std::cos(angle); + const float asin = std::sin(angle); + zeus::CTransform xf; + xf.basis[0][0] = acos; + xf.basis[0][1] = asin; + xf.basis[1][0] = -asin; + xf.basis[1][1] = acos; + xf.origin[0] = (1.f - (acos - asin)) * 0.5f; + xf.origin[1] = (1.f - (asin + acos)) * 0.5f; + GXLoadTexMtxImm(&xf, texMtx, GX_MTX3x4); + return 3; + } + case 4: + case 5: { + zeus::CTransform xf; + const float value = SBig(params[0]) * SBig(params[2]) * (SBig(params[3]) + CGraphics::GetSecondsMod900()); + if (type == 4) { + xf.origin.x() = std::trunc(SBig(params[1]) * std::fmod(value, 1.f)) * SBig(params[2]); + xf.origin.y() = 0.f; + } else { + xf.origin.x() = 0.f; + xf.origin.y() = std::trunc(SBig(params[1]) * std::fmod(value, 1.f)) * SBig(params[2]); + } + GXLoadTexMtxImm(&xf, texMtx, GX_MTX3x4); + return 5; + } + case 6: { + const zeus::CTransform mtx{CGraphics::g_GXModelMatrix.basis}; + const zeus::CTransform postMtx{ + { + zeus::CVector3f{0.5f, 0.f, 0.f}, + zeus::CVector3f{0.f, 0.f, 0.f}, + zeus::CVector3f{0.f, 0.5f, 0.f}, + }, + zeus::CVector3f{ + CGraphics::g_GXModelMatrix.origin.x() * 0.05f, + CGraphics::g_GXModelMatrix.origin.y() * 0.05f, + 1.f, + }, + }; + GXLoadTexMtxImm(&mtx, texMtx, GX_MTX3x4); + GXLoadTexMtxImm(&postMtx, pttTexMtx, GX_MTX3x4); + return 1; + } + case 7: { + zeus::CTransform mtx = CGraphics::g_ViewMatrix.inverse().multiplyIgnoreTranslation(CGraphics::g_GXModelMatrix); + mtx.origin.zeroOut(); + float xy = SBig(params[1]) * (CGraphics::g_ViewMatrix.origin.x() + CGraphics::g_ViewMatrix.origin.y()) * 0.025f; + xy = (xy - static_cast(xy)); + float z = SBig(params[1]) * CGraphics::g_ViewMatrix.origin.z() * 0.05f; + z = (z - static_cast(z)); + float halfA = SBig(params[0]) * 0.5f; + zeus::CTransform postMtx{ + { + zeus::CVector3f{halfA, 0.f, 0.f}, + zeus::CVector3f{0.f, 0.f, 0.f}, + zeus::CVector3f{0.f, halfA, 0.f}, + }, + zeus::CVector3f{xy, z, 1.f}, + }; + GXLoadTexMtxImm(&mtx, texMtx, GX_MTX3x4); + GXLoadTexMtxImm(&postMtx, pttTexMtx, GX_MTX3x4); + return 3; + } + default: + return 0; + } +} + +void CCubeMaterial::HandleTransparency(u32& finalTevCount, u32& finalKColorCount, const CModelFlags& modelFlags, + u32 blendFactors, u32& finalCCFlags, u32& finalACFlags) { + if (modelFlags.x0_blendMode == 2) { + u16 dstFactor = blendFactors >> 16 & 0xffff; + if (dstFactor == 1) { + return; + } + } + if (modelFlags.x0_blendMode == 3) { + // Stage outputting splatted KAlpha as color to reg0 + auto stage = static_cast(finalTevCount); + CGX::SetTevColorIn(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST); + CGX::SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + CGX::SetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVREG0); + CGX::SetTevKColorSel(stage, static_cast(finalKColorCount + GX_TEV_KCSEL_K0_A)); + CGX::SetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTevOrder(stage, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetTevDirect(stage); + + // Stage interpolating from splatted KAlpha using KColor + stage = static_cast(stage + 1); + CGX::SetTevColorIn(stage, GX_CC_CPREV, GX_CC_C0, GX_CC_KONST, GX_CC_ZERO); + CGX::SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + CGX::SetTevKColorSel(stage, static_cast(finalKColorCount + GX_TEV_KCSEL_K0)); + CGX::SetStandardTevColorAlphaOp(stage); + CGX::SetTevDirect(stage); + CGX::SetTevOrder(stage, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetTevKColor(static_cast(finalKColorCount), modelFlags.x4_color); + + finalKColorCount += 1; + finalTevCount += 2; + } else { + auto stage = static_cast(finalTevCount); + if (modelFlags.x0_blendMode == 8) { + CGX::SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); // Set KAlpha + } else { + CGX::SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_KONST, GX_CA_APREV, GX_CA_ZERO); // Mul KAlpha + } + if (modelFlags.x0_blendMode == 2) { + CGX::SetTevColorIn(stage, GX_CC_ZERO, GX_CC_ONE, GX_CC_CPREV, GX_CC_KONST); // Add KColor + } else { + CGX::SetTevColorIn(stage, GX_CC_ZERO, GX_CC_KONST, GX_CC_CPREV, GX_CC_ZERO); // Mul KColor + } + CGX::SetStandardTevColorAlphaOp(stage); + + finalCCFlags = 0x100; // Just clamp, output prev reg + finalACFlags = 0x100; + + CGX::SetTevDirect(stage); + CGX::SetTevOrder(stage, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetTevKColor(static_cast(finalKColorCount), modelFlags.x4_color); + CGX::SetTevKColorSel(stage, static_cast(finalKColorCount + GX_TEV_KCSEL_K0)); + CGX::SetTevKAlphaSel(stage, static_cast(finalKColorCount + GX_TEV_KASEL_K0_A)); + + finalTevCount += 1; + finalKColorCount += 1; + } +} + +u32 CCubeMaterial::HandleReflection(bool usesTevReg2, u32 indTexSlot, u32 r5, u32 finalTevCount, u32 texCount, + u32 tcgCount, u32 finalKColorCount, u32& finalCCFlags, u32& finalACFlags) { + u32 out = 0; + GXTevColorArg colorArg = GX_CC_KONST; + if (usesTevReg2) { + colorArg = GX_CC_C2; + const auto stage = static_cast(finalTevCount); + CGX::SetTevColorIn(stage, GX_CC_ZERO, GX_CC_C2, GX_CC_KONST, GX_CC_ZERO); + CGX::SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A2); + CGX::SetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVREG2); + CGX::SetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVREG2); + CGX::SetTevOrder(stage, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_ZERO); + out = 1; + } + CGX::SetTevKColor(static_cast(finalKColorCount), zeus::CColor{sReflectionAlpha, sReflectionAlpha}); + CGX::SetTevKColorSel(static_cast(finalTevCount), + static_cast(GX_TEV_KCSEL_K0 + finalKColorCount)); + + const auto stage = static_cast(finalTevCount + out); + // tex = g_Renderer->GetRealReflection + // tex.Load(texCount, 0) + + // TODO + + finalACFlags = 0; + finalCCFlags = 0; + + // aurora::gfx::set_tev_order(stage, ...) + + return out; //+ 1; +} + +void CCubeMaterial::DoPassthru(u32 finalTevCount) { + const auto stage = static_cast(finalTevCount); + CGX::SetTevColorIn(stage, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV); + CGX::SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + CGX::SetTevOrder(stage, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetTevDirect(stage); + CGX::SetStandardTevColorAlphaOp(stage); +} + +void CCubeMaterial::DoModelShadow(u32 texCount, u32 tcgCount) { + // CCubeModel::sShadowTexture->Load(texCount, EClampMode::One); + // TODO +} + +static GXTevStageID sCurrentTevStage = GX_MAX_TEVSTAGE; +void CCubeMaterial::EnsureTevsDirect() { + if (sCurrentTevStage == GX_MAX_TEVSTAGE) { + return; + } + + CGX::SetNumIndStages(0); + CGX::SetTevDirect(sCurrentTevStage); + sCurrentTevStage = GX_MAX_TEVSTAGE; +} +} // namespace metaforce diff --git a/Runtime/Graphics/CCubeMaterial.hpp b/Runtime/Graphics/CCubeMaterial.hpp new file mode 100644 index 000000000..0903ecc26 --- /dev/null +++ b/Runtime/Graphics/CCubeMaterial.hpp @@ -0,0 +1,75 @@ +#pragma once + +#include "CToken.hpp" +#include "GCNTypes.hpp" +#include "Graphics/CTexture.hpp" +#include "Graphics/CModel.hpp" +#include "IObjectStore.hpp" + +namespace metaforce { +class CCubeModel; +class CCubeSurface; + +enum class CCubeMaterialFlagBits : u32 { + fKonstValues = 0x8, + fDepthSorting = 0x10, + fAlphaTest = 0x20, + fSamusReflection = 0x40, + fDepthWrite = 0x80, + fSamusReflectionSurfaceEye = 0x100, + fShadowOccluderMesh = 0x200, + fSamusReflectionIndirectTexture = 0x400, + fLightmap = 0x800, + fLightmapUvArray = 0x2000, + fTextureSlotMask = 0xffff0000 +}; +using CCubeMaterialFlags = Flags; + +class CCubeMaterial { + const u8* x0_data; + +public: + explicit CCubeMaterial(const u8* data) : x0_data(data) {} + + void SetCurrent(const CModelFlags& flags, const CCubeSurface& surface, CCubeModel& model); + + [[nodiscard]] u32 GetCompressedBlend() { + const u32* ptr = reinterpret_cast(x0_data + (GetTextureCount() * 4) + 16); + if (GetFlags() & CCubeMaterialFlagBits::fKonstValues) { + ptr += SBig(*ptr) + 1; + } + return SBig(*ptr); + } + [[nodiscard]] CCubeMaterialFlags GetFlags() const { + return CCubeMaterialFlags(SBig(*reinterpret_cast(x0_data))); + } + [[nodiscard]] u32 GetVatFlags() const { + return SBig(*reinterpret_cast(x0_data + 8 + (GetTextureCount() * 4))); + } + [[nodiscard]] u32 GetUsedTextureSlots() const { return static_cast(GetFlags()) >> 16; } + [[nodiscard]] u32 GetTextureCount() const { return SBig(*reinterpret_cast(x0_data + 4)); } + [[nodiscard]] u32 GetVertexDesc() const { + return SBig(*reinterpret_cast(x0_data + (GetTextureCount() * 4) + 8)); + } + + static void ResetCachedMaterials(); + static void EnsureViewDepStateCached(const CCubeSurface* surface); + static void KillCachedViewDepState(); + static void EnsureTevsDirect(); + +private: + void SetCurrentBlack(); + + static void SetupBlendMode(u32 blendFactors, const CModelFlags& flags, bool alphaTest); + static void HandleDepth(CModelFlagsFlags modelFlags, CCubeMaterialFlags matFlags); + static u32 HandleColorChannels(u32 chanCount, u32 firstChan); + static void HandleTev(u32 tevCur, const u32* materialDataCur, const u32* texMapTexCoordFlags, bool shadowMapsEnabled); + static u32 HandleAnimatedUV(const u32* uvAnim, GXTexMtx texMtx, GXPTTexMtx pttTexMtx); + static void HandleTransparency(u32& finalTevCount, u32& finalKColorCount, const CModelFlags& modelFlags, + u32 blendFactors, u32& finalCCFlags, u32& finalACFlags); + static u32 HandleReflection(bool usesTevReg2, u32 indTexSlot, u32 r5, u32 finalTevCount, u32 texCount, u32 tcgCount, + u32 finalKColorCount, u32& finalCCFlags, u32& finalACFlags); + static void DoPassthru(u32 finalTevCount); + static void DoModelShadow(u32 texCount, u32 tcgCount); +}; +} // namespace metaforce diff --git a/Runtime/Graphics/CCubeModel.cpp b/Runtime/Graphics/CCubeModel.cpp new file mode 100644 index 000000000..c4b619b8c --- /dev/null +++ b/Runtime/Graphics/CCubeModel.cpp @@ -0,0 +1,322 @@ +#include "CCubeModel.hpp" + +#include "CSimplePool.hpp" +#include "Graphics/CCubeMaterial.hpp" +#include "Graphics/CCubeSurface.hpp" +#include "Graphics/CGraphics.hpp" +#include "Graphics/CModel.hpp" +#include "Graphics/CGX.hpp" + +namespace metaforce { +bool CCubeModel::sRenderModelBlack = false; +bool CCubeModel::sRenderModelShadow = false; +bool CCubeModel::sUsingPackedLightmaps = false; +const CTexture* CCubeModel::sShadowTexture = nullptr; +zeus::CTransform CCubeModel::sTextureProjectionTransform; +GX::LightMask CCubeModel::sChannel0DisableLightMask; +GX::LightMask CCubeModel::sChannel1EnableLightMask; + +static bool sDrawingOccluders = false; +static bool sDrawingWireframe = false; + +static zeus::CVector3f sPlayerPosition; + +CCubeModel::CCubeModel(std::vector* surfaces, std::vector>* textures, + u8* materialData, std::vector* positions, std::vector* colors, + std::vector* normals, std::vector>* texCoords, + std::vector>* packedTexCoords, const zeus::CAABox& aabb, u8 flags, bool b1, + u32 idx) +: x0_modelInstance(surfaces, materialData, positions, colors, normals, texCoords, packedTexCoords) +, x1c_textures(textures) +, x20_worldAABB(aabb) +, x40_24_texturesLoaded(!b1) +, x41_visorFlags(flags) +, x44_idx(idx) { + for (auto& surf : *x0_modelInstance.Surfaces()) { + surf.SetParent(this); + } + + for (u32 i = x0_modelInstance.Surfaces()->size(); i > 0; --i) { + auto& surf = (*x0_modelInstance.Surfaces())[i - 1]; + const auto matFlags = GetMaterialByIndex(surf.GetMaterialIndex()).GetFlags(); + if (!matFlags.IsSet(CCubeMaterialFlagBits::fDepthSorting)) { + surf.SetNextSurface(x38_firstUnsortedSurf); + x38_firstUnsortedSurf = &surf; + } else { + surf.SetNextSurface(x3c_firstSortedSurf); + x3c_firstSortedSurf = &surf; + } + } +} + +CCubeMaterial CCubeModel::GetMaterialByIndex(u32 idx) { + u32 materialOffset = 0; + const u8* matData = x0_modelInstance.GetMaterialPointer(); + matData += (x1c_textures->size() + 1) * 4; + if (idx != 0) { + materialOffset = SBig(*reinterpret_cast(matData + (idx * 4))); + } + + u32 materialCount = SBig(*reinterpret_cast(matData)); + return CCubeMaterial(matData + materialOffset + (materialCount * 4) + 4); +} + +bool CCubeModel::TryLockTextures() { + if (!x40_24_texturesLoaded) { + bool texturesLoading = false; + for (auto& texture : *x1c_textures) { + texture.Lock(); + bool loadTexture = true; + if (!texture.HasReference()) { + if (!texture.IsLocked() || texture.IsNull()) { + loadTexture = false; + } else { + texture.GetObj(); + } + } + if (loadTexture) { + // if (!texture->LoadToMRAM()) { + // texturesLoading = true; + // } + } + } + if (!texturesLoading) { + x40_24_texturesLoaded = true; + } + } + return x40_24_texturesLoaded; +} + +void CCubeModel::UnlockTextures() { + for (auto& token : *x1c_textures) { + token.Unlock(); + } +} + +void CCubeModel::RemapMaterialData(u8* data, std::vector>& textures) { + x0_modelInstance.SetMaterialPointer(data); + x1c_textures = &textures; + x40_24_texturesLoaded = false; +} + +void CCubeModel::MakeTexturesFromMats(const u8* ptr, std::vector>& textures, IObjectStore* store, + bool b1) { + const u32* curId = reinterpret_cast(ptr + 4); + u32 textureCount = SBig(*reinterpret_cast(ptr)); + textures.reserve(textureCount); + for (u32 i = 0; i < textureCount; ++i) { + textures.emplace_back(store->GetObj({FOURCC('TXTR'), SBig(curId[i])})); + + if (!b1 && textures.back().IsNull()) { + textures.back().GetObj(); + } + } +} + +void CCubeModel::Draw(const CModelFlags& flags) { + CCubeMaterial::KillCachedViewDepState(); + SetArraysCurrent(); + DrawSurfaces(flags); +} + +void CCubeModel::Draw(TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) { + CCubeMaterial::KillCachedViewDepState(); + SetSkinningArraysCurrent(positions, normals); + DrawSurfaces(flags); +} + +void CCubeModel::DrawAlpha(const CModelFlags& flags) { + CCubeMaterial::KillCachedViewDepState(); + SetArraysCurrent(); + DrawAlphaSurfaces(flags); +} + +void CCubeModel::DrawAlphaSurfaces(const CModelFlags& flags) { + if (sDrawingWireframe) { + const auto* surface = x3c_firstSortedSurf; + while (surface != nullptr) { + DrawSurfaceWireframe(*surface); + surface = surface->GetNextSurface(); + } + } else if (TryLockTextures()) { + const auto* surface = x3c_firstSortedSurf; + while (surface != nullptr) { + DrawSurface(*surface, flags); + surface = surface->GetNextSurface(); + } + } +} + +void CCubeModel::DrawFlat(TConstVectorRef positions, TConstVectorRef normals, ESurfaceSelection surfaces) { + if (positions == nullptr) { + SetArraysCurrent(); + } else { + SetSkinningArraysCurrent(positions, normals); + } + if (surfaces != ESurfaceSelection::Sorted) { + const auto* surface = x38_firstUnsortedSurf; + while (surface != nullptr) { + const auto mat = GetMaterialByIndex(surface->GetMaterialIndex()); + CGX::SetVtxDescv_Compressed(mat.GetVertexDesc()); + CGX::CallDisplayList(surface->GetDisplayList(), surface->GetDisplayListSize()); + surface = surface->GetNextSurface(); + } + } + if (surfaces != ESurfaceSelection::Unsorted) { + const auto* surface = x3c_firstSortedSurf; + while (surface != nullptr) { + const auto mat = GetMaterialByIndex(surface->GetMaterialIndex()); + CGX::SetVtxDescv_Compressed(mat.GetVertexDesc()); + CGX::CallDisplayList(surface->GetDisplayList(), surface->GetDisplayListSize()); + surface = surface->GetNextSurface(); + } + } +} + +void CCubeModel::DrawNormal(TConstVectorRef positions, TConstVectorRef normals, ESurfaceSelection surfaces) { + CGX::SetNumIndStages(0); + CGX::SetNumTevStages(1); + CGX::SetNumTexGens(1); + CGX::SetZMode(true, GX_LEQUAL, true); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_ZERO, GX_BL_ONE, GX_LO_CLEAR); + DrawFlat(positions, normals, surfaces); +} + +void CCubeModel::DrawNormal(const CModelFlags& flags) { + CCubeMaterial::KillCachedViewDepState(); + SetArraysCurrent(); + DrawNormalSurfaces(flags); +} + +void CCubeModel::DrawNormalSurfaces(const CModelFlags& flags) { + if (sDrawingWireframe) { + const auto* surface = x38_firstUnsortedSurf; + while (surface != nullptr) { + DrawSurfaceWireframe(*surface); + surface = surface->GetNextSurface(); + } + } else if (TryLockTextures()) { + const auto* surface = x38_firstUnsortedSurf; + while (surface != nullptr) { + DrawSurface(*surface, flags); + surface = surface->GetNextSurface(); + } + } +} + +void CCubeModel::DrawSurface(const CCubeSurface& surface, const CModelFlags& flags) { + auto mat = GetMaterialByIndex(surface.GetMaterialIndex()); + if (!mat.GetFlags().IsSet(CCubeMaterialFlagBits::fShadowOccluderMesh) || sDrawingOccluders) { + mat.SetCurrent(flags, surface, *this); + CGX::CallDisplayList(surface.GetDisplayList(), surface.GetDisplayListSize()); + } +} + +void CCubeModel::DrawSurfaces(const CModelFlags& flags) { + if (sDrawingWireframe) { + const auto* surface = x38_firstUnsortedSurf; + while (surface != nullptr) { + DrawSurfaceWireframe(*surface); + surface = surface->GetNextSurface(); + } + surface = x3c_firstSortedSurf; + while (surface != nullptr) { + DrawSurfaceWireframe(*surface); + surface = surface->GetNextSurface(); + } + } else if (TryLockTextures()) { + const auto* surface = x38_firstUnsortedSurf; + while (surface != nullptr) { + DrawSurface(*surface, flags); + surface = surface->GetNextSurface(); + } + surface = x3c_firstSortedSurf; + while (surface != nullptr) { + DrawSurface(*surface, flags); + surface = surface->GetNextSurface(); + } + } +} + +void CCubeModel::DrawSurfaceWireframe(const CCubeSurface& surface) { + auto mat = GetMaterialByIndex(surface.GetMaterialIndex()); + // TODO convert vertices to line strips and draw +} + +void CCubeModel::EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf, + GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask) { + sRenderModelShadow = true; + sShadowTexture = &shadowTex; + sTextureProjectionTransform = textureProjXf; + sChannel0DisableLightMask = chan0DisableMask; + sChannel1EnableLightMask = chan1EnableLightMask; +} + +void CCubeModel::DisableShadowMaps() { sRenderModelShadow = false; } + +void CCubeModel::SetArraysCurrent() { + CGX::SetArray(GX_VA_POS, x0_modelInstance.GetVertexPointer(), true); + CGX::SetArray(GX_VA_NRM, x0_modelInstance.GetNormalPointer(), true); + SetStaticArraysCurrent(); +} + +void CCubeModel::SetDrawingOccluders(bool v) { sDrawingOccluders = v; } + +void CCubeModel::SetModelWireframe(bool v) { sDrawingWireframe = v; } + +void CCubeModel::SetNewPlayerPositionAndTime(const zeus::CVector3f& pos, const CStopwatch& time) { + sPlayerPosition = pos; + CCubeMaterial::KillCachedViewDepState(); + // TODO time +} + +void CCubeModel::SetRenderModelBlack(bool v) { + sRenderModelBlack = v; + // TODO another value is set here, but always 0? +} + +void CCubeModel::SetSkinningArraysCurrent(TConstVectorRef positions, TConstVectorRef normals) { + CGX::SetArray(GX_VA_POS, positions, false); + CGX::SetArray(GX_VA_NRM, normals, false); + // colors unused + SetStaticArraysCurrent(); +} + +void CCubeModel::SetStaticArraysCurrent() { + // colors unused + const auto* packedTexCoords = x0_modelInstance.GetPackedTCPointer(); + const auto* texCoords = x0_modelInstance.GetTCPointer(); + if (packedTexCoords == nullptr) { + sUsingPackedLightmaps = false; + } + if (sUsingPackedLightmaps) { + CGX::SetArray(GX_VA_TEX0, packedTexCoords, true); + } else { + CGX::SetArray(GX_VA_TEX0, texCoords, true); + } + for (int i = GX_VA_TEX1; i <= GX_VA_TEX7; ++i) { + CGX::SetArray(static_cast(i), texCoords, true); + } + CCubeMaterial::KillCachedViewDepState(); +} + +void CCubeModel::SetUsingPackedLightmaps(bool v) { + sUsingPackedLightmaps = v; + if (v) { + CGX::SetArray(GX_VA_TEX0, x0_modelInstance.GetPackedTCPointer(), true); + } else { + CGX::SetArray(GX_VA_TEX0, x0_modelInstance.GetTCPointer(), true); + } +} + +template <> +aurora::Vec2 cinput_stream_helper(CInputStream& in) { + float x = in.ReadFloat(); + float y = in.ReadFloat(); + return {x, y}; +} +} // namespace metaforce diff --git a/Runtime/Graphics/CCubeModel.hpp b/Runtime/Graphics/CCubeModel.hpp new file mode 100644 index 000000000..4a91697cf --- /dev/null +++ b/Runtime/Graphics/CCubeModel.hpp @@ -0,0 +1,145 @@ +#pragma once + +#include +#include +#include + +#include "CStopwatch.hpp" +#include "CToken.hpp" +#include "GCNTypes.hpp" +#include "Graphics/CTexture.hpp" +#include "IObjectStore.hpp" + +namespace metaforce { +class CCubeSurface; +class CCubeMaterial; +struct CModelFlags; + +enum class ESurfaceSelection { + Unsorted, + Sorted, + All, +}; + +// These parameters were originally float* +using TVectorRef = std::vector*; +using TConstVectorRef = const std::vector*; + +class CCubeModel { + friend class CModel; + friend class CCubeMaterial; + +private: + class ModelInstance { + std::vector* x0_surfacePtrs; // was rstl::vector* + u8* x4_materialData; // + std::vector* x8_positions; // was void* + std::vector* xc_normals; // was void* + std::vector* x10_colors; // was void* + std::vector>* x14_texCoords; // was void* + std::vector>* x18_packedTexCoords; // was void* + + public: + ModelInstance(std::vector* surfaces, u8* material, std::vector* positions, + std::vector* colors, std::vector* normals, + std::vector>* texCoords, std::vector>* packedTexCoords) + : x0_surfacePtrs(surfaces) + , x4_materialData(material) + , x8_positions(positions) + , xc_normals(normals) + , x10_colors(colors) + , x14_texCoords(texCoords) + , x18_packedTexCoords(packedTexCoords) {} + + /* + * These functions have been slightly modified from their original to return the actual vector instead of a raw + * pointer + */ + [[nodiscard]] std::vector* Surfaces() const { return x0_surfacePtrs; } + [[nodiscard]] u8* GetMaterialPointer() const { return x4_materialData; } + void SetMaterialPointer(u8* mat) { x4_materialData = mat; } + [[nodiscard]] TVectorRef GetVertexPointer() { return x8_positions; } + [[nodiscard]] TConstVectorRef GetVertexPointer() const { return x8_positions; } + [[nodiscard]] TVectorRef GetNormalPointer() { return xc_normals; } + [[nodiscard]] TConstVectorRef GetNormalPointer() const { return xc_normals; } + [[nodiscard]] std::vector* GetColorPointer() const { return x10_colors; } + [[nodiscard]] std::vector>* GetTCPointer() const { return x14_texCoords; } + [[nodiscard]] std::vector>* GetPackedTCPointer() const { return x18_packedTexCoords; } + }; + + ModelInstance x0_modelInstance; + std::vector>* x1c_textures; + zeus::CAABox x20_worldAABB; + CCubeSurface* x38_firstUnsortedSurf = nullptr; + CCubeSurface* x3c_firstSortedSurf = nullptr; + bool x40_24_texturesLoaded : 1 = false; + bool x40_25_modelVisible : 1 = false; + u8 x41_visorFlags; + u32 x44_idx; + +public: + CCubeModel(std::vector* surfaces, std::vector>* textures, u8* materialData, + std::vector* positions, std::vector* colors, + std::vector* normals, std::vector>* texCoords, + std::vector>* packedTexCoords, const zeus::CAABox& aabb, u8 flags, bool b1, u32 idx); + + CCubeMaterial GetMaterialByIndex(u32 idx); + bool TryLockTextures(); + void UnlockTextures(); + void RemapMaterialData(u8* data, std::vector>& textures); + void Draw(const CModelFlags& flags); + void DrawAlpha(const CModelFlags& flags); + void DrawFlat(TConstVectorRef positions, TConstVectorRef normals, ESurfaceSelection surfaces); + void DrawNormal(TConstVectorRef positions, TConstVectorRef normals, ESurfaceSelection surfaces); + void DrawNormal(const CModelFlags& flags); + void DrawSurface(const CCubeSurface& surface, const CModelFlags& flags); + void DrawSurfaceWireframe(const CCubeSurface& surface); + void SetArraysCurrent(); + void SetUsingPackedLightmaps(bool v); + zeus::CAABox GetBounds() const { return x20_worldAABB; } + u8 GetFlags() const { return x41_visorFlags; } + bool AreTexturesLoaded() const { return x40_24_texturesLoaded; } + void SetVisible(bool v) { x40_25_modelVisible = v; } + bool IsVisible() const { return x40_25_modelVisible; } + [[nodiscard]] u32 GetIndex() const { return x44_idx; } + [[nodiscard]] CCubeSurface* GetFirstUnsortedSurface() { return x38_firstUnsortedSurf; } + [[nodiscard]] const CCubeSurface* GetFirstUnsortedSurface() const { return x38_firstUnsortedSurf; } + [[nodiscard]] CCubeSurface* GetFirstSortedSurface() { return x3c_firstSortedSurf; } + [[nodiscard]] const CCubeSurface* GetFirstSortedSurface() const { return x3c_firstSortedSurf; } + + [[nodiscard]] TVectorRef GetPositions() { return x0_modelInstance.GetVertexPointer(); } + [[nodiscard]] TConstVectorRef GetPositions() const { return x0_modelInstance.GetVertexPointer(); } + [[nodiscard]] TVectorRef GetNormals() { return x0_modelInstance.GetNormalPointer(); } + [[nodiscard]] TConstVectorRef GetNormals() const { return x0_modelInstance.GetNormalPointer(); } + [[nodiscard]] TCachedToken& GetTexture(u32 idx) const { return x1c_textures->at(idx); } + + static void EnableShadowMaps(const CTexture& shadowTex, const zeus::CTransform& textureProjXf, + GX::LightMask chan0DisableMask, GX::LightMask chan1EnableLightMask); + static void DisableShadowMaps(); + static void MakeTexturesFromMats(const u8* ptr, std::vector>& texture, IObjectStore* store, + bool b1); + static void SetDrawingOccluders(bool v); + static void SetModelWireframe(bool v); + static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos, const CStopwatch& time); + static void SetRenderModelBlack(bool v); + +private: + void Draw(TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags); + void DrawAlphaSurfaces(const CModelFlags& flags); + void DrawNormalSurfaces(const CModelFlags& flags); + void DrawSurfaces(const CModelFlags& flags); + void SetSkinningArraysCurrent(TConstVectorRef positions, TConstVectorRef normals); + void SetStaticArraysCurrent(); + + static bool sRenderModelBlack; + static bool sUsingPackedLightmaps; + static bool sRenderModelShadow; + static const CTexture* sShadowTexture; + static zeus::CTransform sTextureProjectionTransform; + static GX::LightMask sChannel0DisableLightMask; + static GX::LightMask sChannel1EnableLightMask; +}; + +template <> +aurora::Vec2 cinput_stream_helper(CInputStream& in); +} // namespace metaforce diff --git a/Runtime/Graphics/CCubeRenderer.cpp b/Runtime/Graphics/CCubeRenderer.cpp new file mode 100644 index 000000000..c966df2f2 --- /dev/null +++ b/Runtime/Graphics/CCubeRenderer.cpp @@ -0,0 +1,1477 @@ +#include "Runtime/Graphics/CCubeRenderer.hpp" + +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CCubeMaterial.hpp" +#include "Runtime/Graphics/CCubeModel.hpp" +#include "Runtime/Graphics/CCubeSurface.hpp" +#include "Runtime/Graphics/CDrawable.hpp" +#include "Runtime/Graphics/CDrawablePlaneObject.hpp" +#include "Runtime/Graphics/CGX.hpp" +#include "Runtime/Graphics/CLight.hpp" +#include "Runtime/Graphics/CMetroidModelInstance.hpp" +#include "Runtime/Graphics/CModel.hpp" +#include "Runtime/World/CGameArea.hpp" +#include "Runtime/Particle/CParticleGen.hpp" +#include "Runtime/Particle/CDecal.hpp" +#include "Runtime/Particle/CElementGen.hpp" +#include "Runtime/CDvdFile.hpp" + +#include + +namespace metaforce { +static logvisor::Module Log("CCubeRenderer"); + +/* TODO: This is to fix some areas exceeding the max drawable count, the proper number is 128 drawables per bucket */ +// using BucketHolderType = rstl::reserved_vector; +using BucketHolderType = rstl::reserved_vector; +static rstl::reserved_vector sDataHolder; +static rstl::reserved_vector sBucketsHolder; +static rstl::reserved_vector sPlaneObjectDataHolder; +static rstl::reserved_vector sPlaneObjectBucketHolder; + +class Buckets { + friend class CCubeRenderer; + + static inline rstl::reserved_vector sBucketIndex; + static inline rstl::reserved_vector* sData = nullptr; + static inline rstl::reserved_vector* sBuckets = nullptr; + static inline rstl::reserved_vector* sPlaneObjectData = nullptr; + static inline rstl::reserved_vector* sPlaneObjectBucket = nullptr; + static constexpr std::array skWorstMinMaxDistance{99999.0f, -99999.0f}; + static inline std::array sMinMaxDistance{99999.0f, -99999.0f}; + +public: + static void Clear(); + static void Sort(); + static void InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest, + const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, void* data); + static void Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, void* data, + const zeus::CPlane& plane, u16 extraSort); + static void Shutdown(); + static void Init(); +}; + +void Buckets::Clear() { + sData->clear(); + sBucketIndex.clear(); + sPlaneObjectData->clear(); + sPlaneObjectBucket->clear(); + for (BucketHolderType& bucket : *sBuckets) { + bucket.clear(); + } + sMinMaxDistance = skWorstMinMaxDistance; +} + +void Buckets::Sort() { + float delta = std::max(1.f, sMinMaxDistance[1] - sMinMaxDistance[0]); + float pitch = 49.f / delta; + for (auto it = sPlaneObjectData->begin(); it != sPlaneObjectData->end(); ++it) { + if (sPlaneObjectBucket->size() != sPlaneObjectBucket->capacity()) { + sPlaneObjectBucket->push_back(s16(it - sPlaneObjectData->begin())); + } + } + + u32 precision = 50; + if (!sPlaneObjectBucket->empty()) { + std::sort(sPlaneObjectBucket->begin(), sPlaneObjectBucket->end(), + [](u16 a, u16 b) { return (*sPlaneObjectData)[a].GetDistance() < (*sPlaneObjectData)[b].GetDistance(); }); + precision = 50 / u32(sPlaneObjectBucket->size() + 1); + pitch = 1.f / (delta / float(precision - 2)); + + s32 accum = 0; + for (u16 idx : *sPlaneObjectBucket) { + ++accum; + CDrawablePlaneObject& planeObj = (*sPlaneObjectData)[idx]; + planeObj.x24_targetBucket = u16(precision * accum); + } + } + + for (CDrawable& drawable : *sData) { + s32 slot = -1; + float relDist = drawable.GetDistance() - sMinMaxDistance[0]; + if (sPlaneObjectBucket->empty()) { + slot = zeus::clamp(1, s32(relDist * pitch), 49); + } else { + slot = zeus::clamp(0, s32(relDist * pitch), s32(precision) - 2); + for (u16 idx : *sPlaneObjectBucket) { + CDrawablePlaneObject& planeObj = (*sPlaneObjectData)[idx]; + bool partial = false; + bool full = false; + if (planeObj.x3c_25_zOnly) { + partial = drawable.GetBounds().max.z() > planeObj.GetPlane().d(); + full = drawable.GetBounds().min.z() > planeObj.GetPlane().d(); + } else { + partial = planeObj.GetPlane().pointToPlaneDist( + drawable.GetBounds().closestPointAlongVector(planeObj.GetPlane().normal())) > 0.f; + full = planeObj.GetPlane().pointToPlaneDist( + drawable.GetBounds().furthestPointAlongVector(planeObj.GetPlane().normal())) > 0.f; + } + bool cont = false; + if (drawable.GetType() == EDrawableType::Particle) { + cont = planeObj.x3c_24_invertTest ? !partial : full; + } else { + cont = planeObj.x3c_24_invertTest ? (!partial || !full) : (partial || full); + } + if (!cont) { + break; + } + slot += s32(precision); + } + } + + if (slot == -1) { + slot = 49; + } + BucketHolderType& bucket = (*sBuckets)[slot]; + if (bucket.size() < bucket.capacity()) { + bucket.push_back(&drawable); + } + // else + // Log.report(logvisor::Fatal, FMT_STRING("Full bucket!!!")); + } + + u16 bucketIdx = u16(sBuckets->size()); + for (auto it = sBuckets->rbegin(); it != sBuckets->rend(); ++it) { + --bucketIdx; + sBucketIndex.push_back(bucketIdx); + BucketHolderType& bucket = *it; + if (bucket.size()) { + std::sort(bucket.begin(), bucket.end(), [](CDrawable* a, CDrawable* b) { + if (a->GetDistance() == b->GetDistance()) + return a->GetExtraSort() > b->GetExtraSort(); + return a->GetDistance() > b->GetDistance(); + }); + } + } + + for (auto it = sPlaneObjectBucket->rbegin(); it != sPlaneObjectBucket->rend(); ++it) { + CDrawablePlaneObject& planeObj = (*sPlaneObjectData)[*it]; + BucketHolderType& bucket = (*sBuckets)[planeObj.x24_targetBucket]; + bucket.push_back(&planeObj); + } +} + +void Buckets::InsertPlaneObject(float closeDist, float farDist, const zeus::CAABox& aabb, bool invertTest, + const zeus::CPlane& plane, bool zOnly, EDrawableType dtype, void* data) { + if (sPlaneObjectData->size() == sPlaneObjectData->capacity()) { + return; + } + sPlaneObjectData->emplace_back(dtype, closeDist, farDist, aabb, invertTest, plane, zOnly, data); +} + +void Buckets::Insert(const zeus::CVector3f& pos, const zeus::CAABox& aabb, EDrawableType dtype, void* data, + const zeus::CPlane& plane, u16 extraSort) { + if (sData->size() == sData->capacity()) { + Log.report(logvisor::Fatal, FMT_STRING("Rendering buckets filled to capacity")); + return; + } + + const float dist = plane.pointToPlaneDist(pos); + sData->emplace_back(dtype, extraSort, dist, aabb, data); + sMinMaxDistance[0] = std::min(sMinMaxDistance[0], dist); + sMinMaxDistance[1] = std::max(sMinMaxDistance[1], dist); +} + +void Buckets::Shutdown() { + sData = nullptr; + sBuckets = nullptr; + sPlaneObjectData = nullptr; + sPlaneObjectBucket = nullptr; +} + +void Buckets::Init() { + sData = &sDataHolder; + sBuckets = &sBucketsHolder; + sBuckets->resize(50); + sPlaneObjectData = &sPlaneObjectDataHolder; + sPlaneObjectBucket = &sPlaneObjectBucketHolder; + sMinMaxDistance = skWorstMinMaxDistance; +} + +CCubeRenderer::CAreaListItem::CAreaListItem(const std::vector* geom, + const CAreaRenderOctTree* octTree, + std::unique_ptr>>&& textures, + std::unique_ptr>>&& models, + s32 areaIdx) +: x0_geometry(geom) +, x4_octTree(octTree) +, x8_textures(std::move(textures)) +, x10_models(std::move(models)) +, x18_areaIdx(areaIdx) {} + +CCubeRenderer::CCubeRenderer(IObjectStore& store, IFactory& resFac) : x8_factory(resFac), xc_store(store) { + void* data = xe4_blackTex.Lock(); + memset(data, 0, 32); + xe4_blackTex.UnLock(); + GenerateReflectionTex(); + GenerateFogVolumeRampTex(); + GenerateSphereRampTex(); + LoadThermoPalette(); + g_Renderer = this; + Buckets::Init(); + // GX draw sync +} + +CCubeRenderer::~CCubeRenderer() { g_Renderer = nullptr; } + +void CCubeRenderer::GenerateReflectionTex() { + // TODO +} + +void CCubeRenderer::GenerateFogVolumeRampTex() { + constexpr double fogVolFar = 750.0; + constexpr double fogVolNear = 0.2; + u8* data = x1b8_fogVolumeRamp.Lock(); + u16 height = x1b8_fogVolumeRamp.GetHeight(); + u16 width = x1b8_fogVolumeRamp.GetWidth(); + for (size_t y = 0; y < height; ++y) { + for (size_t x = 0; x < width; ++x) { + const int tmp = int(y << 16 | x << 8 | 0x7f); + const double a = + zeus::clamp(0.0, + (-150.0 / (tmp / double(0xffffff) * (fogVolFar - fogVolNear) - fogVolFar) - fogVolNear) * 3.0 / + (fogVolFar - fogVolNear), + 1.0); + data[y * width + x] = (a * a + a) / 2.0; + } + } + x1b8_fogVolumeRamp.UnLock(); +} + +void CCubeRenderer::GenerateSphereRampTex() { + u8* data = x220_sphereRamp.Lock(); + const size_t height = x220_sphereRamp.GetHeight(); + const size_t width = x220_sphereRamp.GetWidth(); + const float halfRes = height / 2.f; + for (size_t y = 0; y < height; ++y) { + for (size_t x = 0; x < width; ++x) { + const zeus::CVector2f vec{ + (static_cast(x) - halfRes) / halfRes, + (static_cast(y) - halfRes) / halfRes, + }; + data[y * width + x] = 255 - zeus::clamp(0.f, vec.canBeNormalized() ? vec.magnitude() : 0.f, 1.f) * 255; + } + } + x220_sphereRamp.UnLock(); +} + +void CCubeRenderer::LoadThermoPalette() { + auto* out = x288_thermoPalette.Lock(); + TToken token = xc_store.GetObj("TXTR_ThermoPalette"); + const auto* data = token.GetObj()->GetPalette()->GetPaletteData(); + memcpy(out, data, 32); + x288_thermoPalette.UnLock(); +} + +void CCubeRenderer::ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, CTexture& maskTex, + CTexture& indTex, const zeus::CColor& modColor, float scale, + float offX, float offY) { + // TODO +} + +void CCubeRenderer::ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor, CTexture& maskTex) { + // TODO +} + +void CCubeRenderer::DoPhazonSuitIndirectAlphaBlur(float blurRadius, float f2) { + // TODO +} + +void CCubeRenderer::AddWorldSurfaces(CCubeModel& model) { + for (auto* it = model.GetFirstSortedSurface(); it != nullptr; it = it->GetNextSurface()) { + auto mat = model.GetMaterialByIndex(it->GetMaterialIndex()); + auto blend = mat.GetCompressedBlend(); + auto bounds = it->GetBounds(); + auto pos = bounds.closestPointAlongVector(xb0_viewPlane.normal()); + Buckets::Insert(pos, bounds, EDrawableType::WorldSurface, it, xb0_viewPlane, static_cast(blend == 0x50004)); + } +} + +void CCubeRenderer::AddStaticGeometry(const std::vector* geometry, + const CAreaRenderOctTree* octTree, s32 areaIdx) { + auto search = FindStaticGeometry(geometry); + if (search == x1c_areaListItems.end()) { + auto textures = std::make_unique>>(); + auto models = std::make_unique>>(); + if (!geometry->empty()) { + CCubeModel::MakeTexturesFromMats((*geometry)[0].GetMaterialPointer(), *textures.get(), &xc_store, false); + models->reserve(geometry->size()); + s32 instIdx = 0; + for (const CMetroidModelInstance& inst : *geometry) { + models->emplace_back( + std::make_unique(const_cast*>(inst.GetSurfaces()), textures.get(), + const_cast(inst.GetMaterialPointer()), + const_cast*>(inst.GetVertexPointer()), + const_cast*>(inst.GetColorPointer()), + const_cast*>(inst.GetNormalPointer()), + const_cast>*>(inst.GetTCPointer()), + const_cast>*>(inst.GetPackedTCPointer()), + inst.GetBoundingBox(), inst.GetFlags(), false, instIdx)); + ++instIdx; + } + } + x1c_areaListItems.emplace_back(geometry, octTree, std::move(textures), std::move(models), areaIdx); + } +} + +void CCubeRenderer::EnablePVS(const CPVSVisSet& set, u32 areaIdx) { + if (!xdc_) { + xc8_pvs.emplace(set); + xdc_ = true; + } else { + xc8_pvs.emplace(set); + } + + xe0_pvsAreaIdx = areaIdx; +} + +void CCubeRenderer::DisablePVS() { xc8_pvs.reset(); } + +void CCubeRenderer::RemoveStaticGeometry(const std::vector* geometry) { + auto search = FindStaticGeometry(geometry); + if (search != x1c_areaListItems.end()) { + x1c_areaListItems.erase(search); + } +} + +void CCubeRenderer::DrawUnsortedGeometry(s32 areaIdx, s32 mask, s32 targetMask) { + SCOPED_GRAPHICS_DEBUG_GROUP( + fmt::format(FMT_STRING("CCubeRenderer::DrawUnsortedGeometry areaIdx={} mask={} targetMask={}"), areaIdx, mask, + targetMask) + .c_str(), + zeus::skBlue); + + SetupRendererStates(true); + CModelFlags flags; + CAreaListItem* lastOctreeItem = nullptr; + + for (CAreaListItem& item : x1c_areaListItems) { + if (areaIdx != -1 && item.x18_areaIdx != areaIdx) { + continue; + } + + if (item.x4_octTree != nullptr) { + lastOctreeItem = &item; + } + + CPVSVisSet* pvs = nullptr; + if (xc8_pvs) { + pvs = &*xc8_pvs; + } + + if (xe0_pvsAreaIdx != item.x18_areaIdx) { + pvs = nullptr; + } + + u32 idx = 0; + for (auto it = item.x10_models->begin(); it != item.x10_models->end(); ++it, ++idx) { + const auto& model = *it; + if (pvs != nullptr) { + bool vis = pvs->GetVisible(idx) != EPVSVisSetState::EndOfTree; + switch (xc0_pvsMode) { + case EPVSMode::PVS: { + if (!vis) { + model->SetVisible(false); + continue; + } + break; + } + case EPVSMode::PVSAndMask: { + if (!vis && (model->GetFlags() & mask) != targetMask) { + model->SetVisible(false); + continue; + } + break; + } + default: + break; + } + } + + if ((model->GetFlags() & mask) != targetMask) { + model->SetVisible(false); + continue; + } + + if (!x44_frustumPlanes.aabbFrustumTest(model->GetBounds())) { + model->SetVisible(false); + continue; + } + + if (x318_25_drawWireframe) { + model->SetVisible(false); + HandleUnsortedModelWireframe(lastOctreeItem, *model); + continue; + } + + model->SetVisible(true); + HandleUnsortedModel(lastOctreeItem, *model, flags); + } + } + + SetupCGraphicsState(); +} + +void CCubeRenderer::DrawSortedGeometry(s32 areaIdx, s32 mask, s32 targetMask) { + SCOPED_GRAPHICS_DEBUG_GROUP( + fmt::format(FMT_STRING("CCubeRenderer::DrawSortedGeometry areaIdx={} mask={} targetMask={}"), areaIdx, mask, + targetMask) + .c_str(), + zeus::skBlue); + + SetupRendererStates(true); + const CAreaListItem* item = nullptr; + for (const auto& areaListItem : x1c_areaListItems) { + if (areaIdx == -1 || areaIdx == areaListItem.x18_areaIdx) { + if (areaListItem.x4_octTree != nullptr) { + item = &areaListItem; + } + + for (const auto& model : *areaListItem.x10_models) { + if (model->IsVisible()) { + AddWorldSurfaces(*model); + } + } + } + } + Buckets::Sort(); + RenderBucketItems(item); + SetupCGraphicsState(); + DrawRenderBucketsDebug(); + Buckets::Clear(); +} + +void CCubeRenderer::DrawStaticGeometry(s32 areaIdx, s32 mask, s32 targetMask) { + DrawUnsortedGeometry(areaIdx, mask, targetMask); + DrawSortedGeometry(areaIdx, mask, targetMask); +} + +void CCubeRenderer::DrawAreaGeometry(s32 areaIdx, s32 mask, s32 targetMask) { + SCOPED_GRAPHICS_DEBUG_GROUP( + fmt::format(FMT_STRING("CCubeRenderer::DrawAreaGeometry areaIdx={} mask={} targetMask={}"), areaIdx, mask, + targetMask) + .c_str(), + zeus::skBlue); + + x318_30_inAreaDraw = true; + SetupRendererStates(true); + constexpr CModelFlags flags{0, 0, 3, zeus::skWhite}; + + for (CAreaListItem& item : x1c_areaListItems) { + if (areaIdx == -1 || item.x18_areaIdx == areaIdx) { + CPVSVisSet* pvs = xc8_pvs ? &*xc8_pvs : nullptr; + if (xe0_pvsAreaIdx != item.x18_areaIdx) { + pvs = nullptr; + } + s32 modelIdx = 0; + for (auto it = item.x10_models->begin(); it != item.x10_models->end(); ++it, ++modelIdx) { + const auto& model = *it; + if (pvs != nullptr) { + bool visible = pvs->GetVisible(modelIdx) != EPVSVisSetState::EndOfTree; + if ((xc0_pvsMode == EPVSMode::PVS && !visible) || (xc0_pvsMode == EPVSMode::PVSAndMask && visible)) { + continue; + } + } + if ((model->GetFlags() & mask) != targetMask) { + continue; + } + if (!x44_frustumPlanes.aabbFrustumTest(model->GetBounds())) { + continue; + } + + model->SetArraysCurrent(); + for (const auto* surf = model->GetFirstUnsortedSurface(); surf != nullptr; surf = surf->GetNextSurface()) { + model->DrawSurface(*surf, flags); + } + for (const auto* surf = model->GetFirstSortedSurface(); surf != nullptr; surf = surf->GetNextSurface()) { + model->DrawSurface(*surf, flags); + } + } + } + } + + SetupCGraphicsState(); + x318_30_inAreaDraw = false; +} + +void CCubeRenderer::RenderBucketItems(const CAreaListItem* item) { + SCOPED_GRAPHICS_DEBUG_GROUP( + fmt::format(FMT_STRING("CCubeRenderer::RenderBucketItems areaIdx={}"), item->x18_areaIdx).c_str(), zeus::skBlue); + + CCubeModel* lastModel = nullptr; + EDrawableType lastDrawableType = EDrawableType::Invalid; + for (u16 idx : Buckets::sBucketIndex) { + BucketHolderType& bucket = (*Buckets::sBuckets)[idx]; + for (CDrawable* drawable : bucket) { + EDrawableType type = drawable->GetType(); + switch (type) { + case EDrawableType::Particle: { + if (lastDrawableType != EDrawableType::Particle) { + SetupCGraphicsState(); + } + + static_cast(drawable->GetData())->Render(); + break; + } + case EDrawableType::WorldSurface: { + if (lastDrawableType != EDrawableType::WorldSurface) { + SetupRendererStates(false); + lastModel = nullptr; + } + + auto* surface = static_cast(drawable->GetData()); + auto* model = surface->GetParent(); + if (model != lastModel) { + model->SetArraysCurrent(); + ActivateLightsForModel(item, *model); + } + model->DrawSurface(*surface, CModelFlags(0, 0, 1, zeus::skWhite)); + break; + } + default: { + if (type != lastDrawableType) { + CCubeMaterial::EnsureTevsDirect(); + } + if (xa8_drawableCallback != nullptr) { + xa8_drawableCallback(drawable->GetData(), xac_drawableCallbackUserData, s32(drawable->GetType()) - 2); + } + break; + } + } + lastDrawableType = type; + } + } +} + +void CCubeRenderer::PostRenderFogs() { + for (const auto& warp : x2c4_spaceWarps) { + ReallyDrawSpaceWarp(warp.first, warp.second); + } + x2c4_spaceWarps.clear(); + + x2ac_fogVolumes.sort([](const CFogVolumeListItem& a, const CFogVolumeListItem& b) { + zeus::CAABox aabbA = a.x34_aabb.getTransformedAABox(a.x0_transform); + bool insideA = + aabbA.pointInside(zeus::CVector3f(CGraphics::g_ViewPoint.x(), CGraphics::g_ViewPoint.y(), aabbA.min.z())); + + zeus::CAABox aabbB = b.x34_aabb.getTransformedAABox(b.x0_transform); + bool insideB = + aabbB.pointInside(zeus::CVector3f(CGraphics::g_ViewPoint.x(), CGraphics::g_ViewPoint.y(), aabbB.min.z())); + + if (insideA != insideB) { + return insideA; + } + + float dotA = aabbA.furthestPointAlongVector(CGraphics::g_ViewMatrix.basis[1]).dot(CGraphics::g_ViewMatrix.basis[1]); + float dotB = aabbB.furthestPointAlongVector(CGraphics::g_ViewMatrix.basis[1]).dot(CGraphics::g_ViewMatrix.basis[1]); + return dotA < dotB; + }); + for (const CFogVolumeListItem& fog : x2ac_fogVolumes) { + CGraphics::SetModelMatrix(fog.x0_transform); + ReallyRenderFogVolume(fog.x30_color, fog.x34_aabb, fog.x4c_model.GetObj(), fog.x5c_skinnedModel); + } + x2ac_fogVolumes.clear(); +} + +void CCubeRenderer::SetModelMatrix(const zeus::CTransform& xf) { CGraphics::SetModelMatrix(xf); } + +void CCubeRenderer::HandleUnsortedModel(CAreaListItem* areaItem, CCubeModel& model, const CModelFlags& flags) { + if (model.GetFirstUnsortedSurface() == nullptr) { + return; + } + model.SetArraysCurrent(); + ActivateLightsForModel(areaItem, model); + for (auto* it = model.GetFirstUnsortedSurface(); it != nullptr; it = it->GetNextSurface()) { + model.DrawSurface(*it, CModelFlags(0, 0, 3, zeus::skWhite)); + } +} + +void CCubeRenderer::HandleUnsortedModelWireframe(CAreaListItem* areaItem, CCubeModel& model) { + model.SetArraysCurrent(); + ActivateLightsForModel(areaItem, model); + for (auto* it = model.GetFirstUnsortedSurface(); it != nullptr; it = it->GetNextSurface()) { + model.DrawSurfaceWireframe(*it); + } + for (auto* it = model.GetFirstSortedSurface(); it != nullptr; it = it->GetNextSurface()) { + model.DrawSurfaceWireframe(*it); + } +} + +constexpr bool TestBit(const u32* words, size_t bit) { return (words[bit / 32] & (1U << (bit & 0x1f))) != 0; } + +void CCubeRenderer::ActivateLightsForModel(const CAreaListItem* areaItem, CCubeModel& model) { + constexpr u32 LightCount = 4; + GX::LightMask lightMask; + + if (!x300_dynamicLights.empty()) { + std::array addedLights{}; + std::array lightRads{-1.f, -1.f, -1.f, -1.f}; + + u32 lightOctreeWordCount = 0; + const u32* lightOctreeWords = nullptr; + if (areaItem != nullptr && model.GetIndex() != UINT32_MAX) { + lightOctreeWordCount = areaItem->x4_octTree->x14_bitmapWordCount; + lightOctreeWords = areaItem->x1c_lightOctreeWords.data(); + } + + u32 lightIdx = 0; + for (const auto& light : x300_dynamicLights) { + if (lightIdx >= LightCount) { + break; + } + + if (lightOctreeWords == nullptr || TestBit(lightOctreeWords, model.GetIndex())) { + bool loaded = false; + const float radius = + model.GetBounds().intersectionRadius(zeus::CSphere(light.GetPosition(), light.GetRadius())); + + if (lightIdx > 0) { + for (u32 i = 0; i < lightIdx; ++i) { + if (addedLights[i] == light.GetId()) { + if (radius >= 0.f && radius < lightRads[i]) { + lightRads[i] = radius; + CGraphics::LoadLight(i, light); + loaded = true; + } + break; + } + } + } + + if (!loaded) { + lightRads[lightIdx] = radius; + if (radius >= 0.f) { + CGraphics::LoadLight(lightIdx, light); + addedLights[lightIdx] = light.GetId(); + lightMask.set(lightIdx); + ++lightIdx; + } + } + } + + lightOctreeWords += lightOctreeWordCount; + } + } + + if (lightMask.any()) { + CGraphics::SetLightState(lightMask); + CGX::SetChanMatColor(CGX::EChannelId::Channel0, zeus::skWhite); + } else { + CGraphics::DisableAllLights(); + CGX::SetChanMatColor(CGX::EChannelId::Channel0, CGX::GetChanAmbColor(CGX::EChannelId::Channel0)); + } +} + +void CCubeRenderer::AddParticleGen(CParticleGen& gen) { + auto bounds = gen.GetBounds(); + + if (bounds) { + auto closestPoint = bounds->closestPointAlongVector(xb0_viewPlane.normal()); + Buckets::Insert(closestPoint, *bounds, EDrawableType::Particle, reinterpret_cast(&gen), xb0_viewPlane, 0); + } +} + +void CCubeRenderer::AddParticleGen(CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds) { + Buckets::Insert(pos, bounds, EDrawableType::Particle, reinterpret_cast(&gen), xb0_viewPlane, 0); +} + +void CCubeRenderer::AddPlaneObject(void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, s32 type) { + + const auto closestPoint = aabb.closestPointAlongVector(xb0_viewPlane.normal()); + const auto closestDist = xb0_viewPlane.pointToPlaneDist(closestPoint); + const auto furthestPoint = aabb.furthestPointAlongVector(xb0_viewPlane.normal()); + const auto furthestDist = xb0_viewPlane.pointToPlaneDist(furthestPoint); + + if (closestDist >= 0.f || furthestDist >= 0.f) { + const bool zOnly = plane.normal() == zeus::skUp; + const bool invertTest = zOnly ? CGraphics::g_GXModelView.origin.z() >= plane.d() + : plane.pointToPlaneDist(CGraphics::g_GXModelView.origin) >= 0.f; + Buckets::InsertPlaneObject(closestDist, furthestDist, aabb, invertTest, plane, zOnly, EDrawableType(type + 2), obj); + } +} + +void CCubeRenderer::AddDrawable(void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, s32 mode, + IRenderer::EDrawableSorting sorting) { + if (sorting == EDrawableSorting::UnsortedCallback) { + xa8_drawableCallback(obj, xac_drawableCallbackUserData, mode); + } else { + Buckets::Insert(pos, aabb, EDrawableType(mode + 2), obj, xb0_viewPlane, 0); + } +} + +void CCubeRenderer::SetDrawableCallback(IRenderer::TDrawableCallback cb, void* ctx) { + xa8_drawableCallback = cb; + xac_drawableCallbackUserData = ctx; +} + +void CCubeRenderer::SetWorldViewpoint(const zeus::CTransform& xf) { + CGraphics::SetViewPointMatrix(xf); + auto front = xf.frontVector(); + xb0_viewPlane = zeus::CPlane(front, front.dot(xf.origin)); +} + +void CCubeRenderer::SetPerspective(float fovy, float aspect, float znear, float zfar) { + CGraphics::SetPerspective(fovy, aspect, znear, zfar); +} + +void CCubeRenderer::SetPerspective(float fovy, float width, float height, float znear, float zfar) { + CGraphics::SetPerspective(fovy, width / height, znear, zfar); +} + +std::pair CCubeRenderer::SetViewportOrtho(bool centered, float znear, float zfar) { + auto left = static_cast(centered ? CGraphics::GetViewportLeft() - CGraphics::GetViewportHalfWidth() + : CGraphics::GetViewportLeft()); + auto bottom = static_cast(centered ? CGraphics::GetViewportTop() - CGraphics::GetViewportHalfHeight() + : CGraphics::GetViewportTop()); + auto right = static_cast(CGraphics::GetViewportLeft() + + (centered ? CGraphics::GetViewportWidth() / 2 : CGraphics::GetViewportWidth())); + auto top = static_cast(CGraphics::GetViewportTop() + + (centered ? CGraphics::GetViewportHeight() / 2 : CGraphics::GetViewportHeight())); + CGraphics::SetOrtho(left, right, top, bottom, znear, zfar); + CGraphics::SetViewPointMatrix({}); + CGraphics::SetModelMatrix({}); + return {{left, bottom}, {right, top}}; +} + +void CCubeRenderer::SetClippingPlanes(const zeus::CFrustum& frustum) { x44_frustumPlanes = frustum; } + +void CCubeRenderer::SetViewport(s32 left, s32 bottom, s32 width, s32 height) { + CGraphics::SetViewport(left, bottom, width, height); + CGraphics::SetScissor(left, bottom, width, height); +} + +void CCubeRenderer::BeginScene() { + CGraphics::SetUseVideoFilter(true); + CGraphics::SetViewport(0, 0, CGraphics::g_Viewport.x8_width, CGraphics::g_Viewport.xc_height); + + CGraphics::SetClearColor(zeus::skClear); + CGraphics::SetCullMode(ERglCullMode::Front); + CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + CGraphics::SetPerspective(75.f, CGraphics::g_Viewport.x8_width / CGraphics::g_Viewport.xc_height, 1.f, 4096.f); + CGraphics::SetModelMatrix(zeus::CTransform()); + if (x310_phazonSuitMaskCountdown != 0) { + --x310_phazonSuitMaskCountdown; + if (x310_phazonSuitMaskCountdown == 0) { + x314_phazonSuitMask.reset(); + } + } + + x318_27_currentRGBA6 = x318_26_requestRGBA6; + if (!x318_31_persistRGBA6) { + x318_26_requestRGBA6 = false; + } + + // GXSetPixelFmt(x318_27_currentRGBA6, GX_ZC_LINEAR); + GXSetAlphaUpdate(true); + GXSetDstAlpha(true, 0.f); + CGraphics::BeginScene(); +} + +void CCubeRenderer::EndScene() { + x318_31_persistRGBA6 = !CGraphics::g_IsBeginSceneClearFb; + CGraphics::EndScene(); + + if (x2dc_reflectionAge < 2) { + ++x2dc_reflectionAge; + } else { + x14c_reflectionTex.reset(); + }; +} + +void CCubeRenderer::SetDebugOption(IRenderer::EDebugOption option, s32 value) { + if (option == EDebugOption::PVSState) { + if (xc8_pvs) { + xc8_pvs->SetState(EPVSVisSetState(value)); + } + } else if (option == EDebugOption::PVSMode) { + xc0_pvsMode = EPVSMode(value); + } else if (option == EDebugOption::FogDisabled) { + x318_28_disableFog = true; + } +} + +void CCubeRenderer::BeginPrimitive(IRenderer::EPrimitiveType type, s32 nverts) { + constexpr std::array vtxDescList{ + GXVtxDescList{GX_VA_POS, GX_DIRECT}, + GXVtxDescList{GX_VA_NRM, GX_DIRECT}, + GXVtxDescList{GX_VA_CLR0, GX_DIRECT}, + GXVtxDescList{GX_VA_NULL, GX_NONE}, + }; + CGX::SetChanCtrl(CGX::EChannelId::Channel0, false, GX_SRC_REG, GX_SRC_VTX, {}, GX_DF_NONE, GX_AF_NONE); + CGX::SetNumChans(1); + CGX::SetNumTexGens(0); + CGX::SetNumTevStages(1); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + x18_primVertCount = nverts; + CGX::SetVtxDescv(vtxDescList.data()); + CGX::Begin(GXPrimitive(type), GX_VTXFMT0, nverts); +} + +void CCubeRenderer::BeginLines(s32 nverts) { BeginPrimitive(EPrimitiveType::Lines, nverts); } + +void CCubeRenderer::BeginLineStrip(s32 nverts) { BeginPrimitive(EPrimitiveType::LineStrip, nverts); } + +void CCubeRenderer::BeginTriangles(s32 nverts) { BeginPrimitive(EPrimitiveType::Triangles, nverts); } + +void CCubeRenderer::BeginTriangleStrip(s32 nverts) { BeginPrimitive(EPrimitiveType::TriangleStrip, nverts); } + +void CCubeRenderer::BeginTriangleFan(s32 nverts) { BeginPrimitive(EPrimitiveType::TriangleFan, nverts); } + +void CCubeRenderer::PrimVertex(const zeus::CVector3f& vertex) { + --x18_primVertCount; + GXPosition3f32(vertex); + GXNormal3f32(x2e4_primNormal); + GXColor4f32(x2e0_primColor); +} + +void CCubeRenderer::PrimNormal(const zeus::CVector3f& normal) { x2e4_primNormal = normal; } + +void CCubeRenderer::PrimColor(float r, float g, float b, float a) { PrimColor({r, g, b, a}); } + +void CCubeRenderer::PrimColor(const zeus::CColor& color) { x2e0_primColor = color; } + +void CCubeRenderer::EndPrimitive() { + while (x18_primVertCount > 0) { + PrimVertex(zeus::skZero3f); + } + CGX::End(); +} + +void CCubeRenderer::SetAmbientColor(const zeus::CColor& color) { CGraphics::SetAmbientColor(color); } + +void CCubeRenderer::DrawString(const char* string, s32 x, s32 y) { x10_font.DrawString(string, x, y, zeus::skWhite); } + +u32 CCubeRenderer::GetFPS() { return CGraphics::GetFPS(); } + +void CCubeRenderer::CacheReflection(IRenderer::TReflectionCallback cb, void* ctx, bool clearAfter) { + // TODO +} + +void CCubeRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength) { + if (pt.z() < 1.f) { + ReallyDrawSpaceWarp(pt, strength); + } +} + +void CCubeRenderer::DrawThermalModel(CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol, + TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) { + model.UpdateLastFrame(); + DoThermalModelDraw(model.GetInstance(), multCol, addCol, positions, normals, flags); +} + +void CCubeRenderer::DrawModelDisintegrate(CModel& model, CTexture& tex, const zeus::CColor& color, + TConstVectorRef positions, TConstVectorRef normals, float t) { + tex.Load(GX_TEXMAP0, EClampMode::Clamp); + CGX::SetNumIndStages(0); + CGX::SetNumTevStages(2); + CGX::SetNumTexGens(2); + CGX::SetNumChans(0); + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE1); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + CGX::SetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_KONST); + CGX::SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_APREV, GX_CA_ZERO); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetTevKColorSel(GX_TEVSTAGE1, GX_TEV_KCSEL_K0); + CGX::SetTevKColor(GX_KCOLOR0, color); + const auto bounds = model.GetInstance().GetBounds(); + const auto rotation = zeus::CTransform::RotateX(zeus::degToRad(-45.f)); + const auto transformedBounds = bounds.getTransformedAABox(rotation); + const auto xf = zeus::CTransform::Scale(5.f / (transformedBounds.max - transformedBounds.min)) * + zeus::CTransform::Translate(-transformedBounds.min) * rotation; + const zeus::CTransform ptTex1{ + zeus::CMatrix3f{ + 1.f, 1.f, 0.f, + 0.f, 0.f, 1.f, + 0.f, 0.f, 0.f, + }, + zeus::CVector3f{t * -0.85f - 0.15f, -(1.f - t) * 6.f + 1.f, 1.f}, + }; + const zeus::CTransform ptTex0{ + zeus::CMatrix3f{ + 1.f, 1.f, 0.f, + 0.f, 0.f, 1.f, + 0.f, 0.f, 0.f, + }, + zeus::CVector3f{t, ptTex1.origin.y(), 1.f}, + }; + GXLoadTexMtxImm(&xf, GX_TEXMTX0, GX_MTX3x4); + GXLoadTexMtxImm(&ptTex0, GX_PTTEXMTX0, GX_MTX3x4); + GXLoadTexMtxImm(&ptTex1, GX_PTTEXMTX1, GX_MTX3x4); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0, false, GX_PTTEXMTX0); + CGX::SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0, false, GX_PTTEXMTX1); + CGX::SetAlphaCompare(GX_GREATER, 0, GX_AOP_AND, GX_ALWAYS, 0); + CGX::SetZMode(true, GX_LEQUAL, true); + model.UpdateLastFrame(); + model.GetInstance().DrawFlat(positions, normals, ESurfaceSelection::All); + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); +} + +void CCubeRenderer::DrawModelFlat(CModel& model, const CModelFlags& flags, bool unsortedOnly, TConstVectorRef positions, + TConstVectorRef normals) { + if (flags.x0_blendMode >= 7) { + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_ONE, GX_LO_CLEAR); + } else if (flags.x0_blendMode >= 5) { + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + } else { + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + } + CGX::SetZMode(true, flags.x2_flags & CModelFlagBits::DepthTest ? GX_LEQUAL : GX_ALWAYS, + flags.x2_flags.IsSet(CModelFlagBits::DepthUpdate)); + CGX::SetNumTevStages(1); + CGX::SetNumTexGens(1); + CGX::SetNumChans(0); + CGX::SetNumIndStages(0); + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + CGX::SetTevKColor(GX_KCOLOR0, flags.x4_color); + CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetTevDirect(GX_TEVSTAGE0); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_POS, GX_IDENTITY, false, GX_PTIDENTITY); + model.UpdateLastFrame(); + model.GetInstance().DrawFlat(positions, normals, unsortedOnly ? ESurfaceSelection::Unsorted : ESurfaceSelection::All); +} + +void CCubeRenderer::SetWireframeFlags(s32 flags) { + CCubeModel::SetModelWireframe((flags & 0x1) != 0); + x318_25_drawWireframe = (flags & 0x2) != 0; +} + +void CCubeRenderer::SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) { + CGraphics::SetFog(x318_28_disableFog ? ERglFogMode::None : mode, startz, endz, color); +} + +void CCubeRenderer::RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, + const TLockedToken* model, const CSkinnedModel* sModel) { + if (!x318_28_disableFog) { + x2ac_fogVolumes.emplace_back(CGraphics::g_GXModelMatrix, color, aabb, model, sModel); + } +} + +void CCubeRenderer::SetThermal(bool thermal, float level, const zeus::CColor& color) { + x318_29_thermalVisor = thermal; + x2f0_thermalVisorLevel = level; + x2f4_thermColor = color; + CDecal::SetMoveRedToAlphaBuffer(false); + CElementGen::SetMoveRedToAlphaBuffer(false); +} + +void CCubeRenderer::SetThermalColdScale(float scale) { x2f8_thermColdScale = zeus::clamp(0.f, scale, 1.f); } + +void CCubeRenderer::DoThermalBlendCold() { + SCOPED_GRAPHICS_DEBUG_GROUP("CCubeRenderer::DoThermalBlendCold", zeus::skBlue); + + // Capture EFB + x318_26_requestRGBA6 = true; + GXSetAlphaUpdate(true); + GXSetDstAlpha(false, 0); + const auto height = CGraphics::GetViewportHeight(); + const auto width = CGraphics::GetViewportWidth(); + const auto top = CGraphics::GetViewportTop(); + const auto left = CGraphics::GetViewportLeft(); + CGX::SetZMode(true, GX_LEQUAL, false); + GXSetTexCopySrc(left, top, width, height); + GXSetTexCopyDst(width, height, GX_TF_I4, false); + GXCopyTex(CGraphics::sSpareTextureData, true); + CGraphics::LoadDolphinSpareTexture(width, height, GX_TF_I4, nullptr, GX_TEXMAP7); + + // Upload random static texture (game reads from .text) + const u8* buf = CDvdFile::GetDolBuf() + 0x4f60; + u8* out = m_thermalRandomStatic.Lock(); + memcpy(out, buf + ROUND_UP_32(x2a8_thermalRand.Next()), m_thermalRandomStatic.GetMemoryAllocated()); + m_thermalRandomStatic.UnLock(); + m_thermalRandomStatic.Load(GX_TEXMAP0, EClampMode::Clamp); + m_thermalRandomStatic.Load(GX_TEXMAP1, EClampMode::Clamp); + + // Configure indirect texturing + const float level = std::clamp(x2f0_thermalVisorLevel * 0.5f, 0.f, 0.5f); + const aurora::Mat3x2 mtx{ + aurora::Vec2{(1.f - level) * 0.1f, 0.f}, + aurora::Vec2{0.f, 0.f}, + aurora::Vec2{0.f, level}, + }; + GXSetIndTexMtx(GX_ITM_0, &mtx, -2); + CGX::SetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_STU, GX_ITM_0, GX_ITW_OFF, GX_ITW_OFF, false, + false, GX_ITBA_OFF); + GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP0); + + // Configure register colors + const auto color0 = zeus::CColor::lerp(x2f4_thermColor, zeus::skWhite, x2f8_thermColdScale); + const float bAlpha = x2f8_thermColdScale < 0.5f ? x2f8_thermColdScale * 2.f : 1.f; + const float bFac = (1.f - bAlpha) / 8.f; + const zeus::CColor color1{bFac, bAlpha}; + float cFac; + if (x2f8_thermColdScale < 0.25f) { + cFac = 0.f; + } else if (x2f8_thermColdScale >= 1.f) { + cFac = 1.f; + } else { + cFac = (x2f8_thermColdScale - 0.25f) * 4.f / 3.f; + } + const zeus::CColor color2{cFac, cFac}; + GXSetTevColor(GX_TEVREG0, to_gx_color(color0)); + GXSetTevColor(GX_TEVREG1, to_gx_color(color1)); + GXSetTevColor(GX_TEVREG2, to_gx_color(color2)); + + // Configure TEV stage 0 + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP1); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_C2); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_A1, GX_CA_A2); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP7, GX_COLOR_NULL); + + // Configure TEV stage 1 + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP1); + CGX::SetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C1, GX_CC_CPREV); + CGX::SetTevColorOp(GX_TEVSTAGE1, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_A1, GX_CA_TEXA, GX_CA_APREV); + CGX::SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_4, true, GX_TEVPREV); + CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP1, GX_COLOR_NULL); + + // Configure everything else + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + CGX::SetNumTevStages(2); + CGX::SetNumTexGens(1); + CGX::SetNumChans(0); + CGX::SetNumIndStages(1); + CGX::SetZMode(false, GX_ALWAYS, false); + constexpr std::array vtxDescList{ + GXVtxDescList{GX_VA_POS, GX_DIRECT}, + GXVtxDescList{GX_VA_TEX0, GX_DIRECT}, + GXVtxDescList{GX_VA_NULL, GX_NONE}, + }; + CGX::SetVtxDescv(vtxDescList.data()); + CGX::SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + + // Backup & set viewport/projection + const auto backupViewMatrix = CGraphics::g_ViewMatrix; + const auto backupProjectionState = CGraphics::GetProjectionState(); + CGraphics::SetOrtho(0.f, static_cast(width), 0.f, static_cast(height), -4096.f, 4096.f); + CGraphics::SetViewPointMatrix({}); + CGraphics::SetModelMatrix({}); + GXPixModeSync(); + + // Draw + CGX::Begin(GX_TRIANGLEFAN, GX_VTXFMT0, 4); + GXPosition3f32(0.f, 0.5f, 0.f); + GXTexCoord2f32(0.f, 0.f); + GXPosition3f32(0.f, 0.5f, static_cast(height)); + GXTexCoord2f32(0.f, 1.f); + GXPosition3f32(static_cast(width), 0.5f, static_cast(height)); + GXTexCoord2f32(1.f, 1.f); + GXPosition3f32(static_cast(width), 0.5f, 0.f); + GXTexCoord2f32(1.f, 0.f); + CGX::End(); + + // Cleanup + GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0); + GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0); + CGX::SetNumIndStages(0); + CGX::SetTevDirect(GX_TEVSTAGE0); + GXSetDstAlpha(false, 255); + CGraphics::SetProjectionState(backupProjectionState); + CGraphics::SetViewPointMatrix(backupViewMatrix); + CDecal::SetMoveRedToAlphaBuffer(true); + CElementGen::SetMoveRedToAlphaBuffer(true); +} + +void CCubeRenderer::DoThermalBlendHot() { + SCOPED_GRAPHICS_DEBUG_GROUP("CCubeRenderer::DoThermalBlendHot", zeus::skRed); + + GXSetAlphaUpdate(false); + GXSetDstAlpha(true, 0); + const auto height = CGraphics::GetViewportHeight(); + const auto width = CGraphics::GetViewportWidth(); + const auto top = CGraphics::GetViewportTop(); + const auto left = CGraphics::GetViewportLeft(); + CGX::SetZMode(true, GX_LEQUAL, true); + GXSetTexCopySrc(left, top, width, height); + GXSetTexCopyDst(width, height, GX_TF_I4, false); + GXCopyTex(CGraphics::sSpareTextureData, false); + x288_thermoPalette.Load(); + CGraphics::LoadDolphinSpareTexture(width, height, GX_TF_C4, GX_TLUT0, nullptr, GX_TEXMAP7); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXA, GX_CC_TEXC, GX_CC_ZERO); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP7, GX_COLOR_NULL); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + CGX::SetNumTevStages(1); + CGX::SetNumTexGens(1); + CGX::SetNumChans(0); + CGX::SetZMode(false, GX_LEQUAL, false); + constexpr std::array vtxDescList{ + GXVtxDescList{GX_VA_POS, GX_DIRECT}, + GXVtxDescList{GX_VA_TEX0, GX_DIRECT}, + GXVtxDescList{GX_VA_NULL, GX_NONE}, + }; + CGX::SetVtxDescv(vtxDescList.data()); + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_DSTALPHA, GX_BL_INVDSTALPHA, GX_LO_CLEAR); + + // Backup & set viewport/projection + const auto backupViewMatrix = CGraphics::g_ViewMatrix; + const auto backupProjectionState = CGraphics::GetProjectionState(); + CGraphics::SetOrtho(0.f, static_cast(width), 0.f, static_cast(height), -4096.f, 4096.f); + CGraphics::SetViewPointMatrix({}); + CGraphics::SetModelMatrix({}); + GXPixModeSync(); + + // Draw + CGX::Begin(GX_TRIANGLEFAN, GX_VTXFMT0, 4); + GXPosition3f32(0.f, 0.5f, 0.f); + GXTexCoord2f32(0.f, 0.f); + GXPosition3f32(0.f, 0.5f, static_cast(height)); + GXTexCoord2f32(0.f, 1.f); + GXPosition3f32(static_cast(width), 0.5f, static_cast(height)); + GXTexCoord2f32(1.f, 1.f); + GXPosition3f32(static_cast(width), 0.5f, 0.f); + GXTexCoord2f32(1.f, 0.f); + CGX::End(); + + // Cleanup + CGX::SetNumIndStages(0); + CGX::SetTevDirect(GX_TEVSTAGE0); + GXSetAlphaUpdate(true); + CGraphics::SetProjectionState(backupProjectionState); + CGraphics::SetViewPointMatrix(backupViewMatrix); + CDecal::SetMoveRedToAlphaBuffer(false); + CElementGen::SetMoveRedToAlphaBuffer(false); +} + +u32 CCubeRenderer::GetStaticWorldDataSize() { + // TODO + return 0; +} + +void CCubeRenderer::SetGXRegister1Color(const zeus::CColor& color) { GXSetTevColor(GX_TEVREG1, to_gx_color(color)); } + +void CCubeRenderer::SetWorldLightFadeLevel(float level) { x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f); } + +void CCubeRenderer::PrepareDynamicLights(const std::vector& lights) { + x300_dynamicLights = lights; + + for (CAreaListItem& area : x1c_areaListItems) { + if (const CAreaRenderOctTree* arot = area.x4_octTree) { + area.x1c_lightOctreeWords.clear(); + area.x1c_lightOctreeWords.resize(arot->x14_bitmapWordCount * lights.size()); + u32* wordPtr = area.x1c_lightOctreeWords.data(); + for (const CLight& light : lights) { + float radius = light.GetRadius(); + zeus::CVector3f vMin = light.GetPosition() - radius; + zeus::CVector3f vMax = light.GetPosition() + radius; + zeus::CAABox aabb(vMin, vMax); + arot->FindOverlappingModels(wordPtr, aabb); + wordPtr += arot->x14_bitmapWordCount; + } + } + } +} + +void CCubeRenderer::AllocatePhazonSuitMaskTexture() { + x318_26_requestRGBA6 = true; + if (!x314_phazonSuitMask) { + x314_phazonSuitMask = std::make_unique(ETexelFormat::I8, CGraphics::GetViewportWidth() / 4, + CGraphics::GetViewportHeight() / 4, 1, "Phazon Suit Mask"sv); + } + x310_phazonSuitMaskCountdown = 2; +} + +void CCubeRenderer::DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod, + const TLockedToken& indTex, const zeus::CColor& indirectMod, + float blurRadius, float scale, float offX, float offY) { + if (x318_27_currentRGBA6 && x310_phazonSuitMaskCountdown != 0) { + const auto backupViewMatrix = CGraphics::g_ViewMatrix; + const auto backupProjectionState = CGraphics::GetProjectionState(); + if (!x314_phazonSuitMask || x314_phazonSuitMask->GetWidth() != CGraphics::GetViewportWidth() / 4 || + x314_phazonSuitMask->GetHeight() != CGraphics::GetViewportHeight() / 4) { + return; + } + DoPhazonSuitIndirectAlphaBlur(blurRadius, blurRadius); + // TODO copy into x314_phazonSuitMask + if (indTex) { + ReallyDrawPhazonSuitIndirectEffect(zeus::skWhite, *x314_phazonSuitMask, const_cast(*indTex), + indirectMod, scale, offX, offY); + } else { + ReallyDrawPhazonSuitEffect(nonIndirectMod, *x314_phazonSuitMask); + } + // TODO unlock x314 + CGraphics::SetViewPointMatrix(backupViewMatrix); + CGraphics::SetProjectionState(backupProjectionState); + x310_phazonSuitMaskCountdown = 2; + } + GXSetDstAlpha(false, 0.f); +} + +void CCubeRenderer::DrawXRayOutline(const zeus::CAABox& aabb) { + // TODO +} + +std::list::iterator +CCubeRenderer::FindStaticGeometry(const std::vector* geometry) { + return std::find_if(x1c_areaListItems.begin(), x1c_areaListItems.end(), + [&](const CAreaListItem& item) { return item.x0_geometry == geometry; }); +} + +void CCubeRenderer::FindOverlappingWorldModels(std::vector& modelBits, const zeus::CAABox& aabb) const { + u32 bitmapWords = 0; + for (const CAreaListItem& item : x1c_areaListItems) { + if (item.x4_octTree != nullptr) { + bitmapWords += item.x4_octTree->x14_bitmapWordCount; + } + } + + if (bitmapWords == 0u) { + modelBits.clear(); + return; + } + + modelBits.clear(); + modelBits.resize(bitmapWords); + + u32 curWord = 0; + for (const CAreaListItem& item : x1c_areaListItems) { + if (item.x4_octTree == nullptr) { + continue; + } + + item.x4_octTree->FindOverlappingModels(modelBits.data() + curWord, aabb); + + u32 wordModel = 0; + for (u32 i = 0; i < item.x4_octTree->x14_bitmapWordCount; ++i, wordModel += 32) { + u32& word = modelBits[curWord + i]; + if (word == 0) { + continue; + } + for (u32 j = 0; j < 32; ++j) { + if (((1U << j) & word) != 0) { + const zeus::CAABox& modelAABB = (*item.x10_models)[wordModel + j]->GetBounds(); + if (!modelAABB.intersects(aabb)) { + word &= ~(1U << j); + } + } + } + } + + curWord += item.x4_octTree->x14_bitmapWordCount; + } +} + +s32 CCubeRenderer::DrawOverlappingWorldModelIDs(s32 alphaVal, const std::vector& modelBits, + const zeus::CAABox& aabb) { + SCOPED_GRAPHICS_DEBUG_GROUP("CCubeRenderer::DrawOverlappingWorldModelIDs", zeus::skGrey); + SetupRendererStates(true); + + constexpr CModelFlags flags{0, 0, 3, zeus::skWhite}; + + u32 curWord = 0; + for (const CAreaListItem& item : x1c_areaListItems) { + if (item.x4_octTree == nullptr) { + continue; + } + + u32 wordModel = 0; + for (u32 i = 0; i < item.x4_octTree->x14_bitmapWordCount; ++i, wordModel += 32) { + const u32& word = modelBits[curWord + i]; + if (word == 0) { + continue; + } + for (u32 j = 0; j < 32; ++j) { + if (((1U << j) & word) != 0) { + if (alphaVal > 255) { + SetupCGraphicsState(); + return alphaVal; + } + + auto& model = *(*item.x10_models)[wordModel + j]; + GXSetDstAlpha(true, alphaVal); + CCubeMaterial::KillCachedViewDepState(); + model.SetArraysCurrent(); + for (const auto* surf = model.GetFirstUnsortedSurface(); surf != nullptr; surf = surf->GetNextSurface()) { + if (surf->GetBounds().intersects(aabb)) { + model.DrawSurface(*surf, flags); + } + } + alphaVal += 4; + } + } + } + + curWord += item.x4_octTree->x14_bitmapWordCount; + } + + SetupCGraphicsState(); + return alphaVal; +} + +void CCubeRenderer::DrawOverlappingWorldModelShadows(s32 alphaVal, const std::vector& modelBits, + const zeus::CAABox& aabb) { + SCOPED_GRAPHICS_DEBUG_GROUP("CBooRenderer::DrawOverlappingWorldModelShadows", zeus::skGrey); + + u32 curWord = 0; + for (const CAreaListItem& item : x1c_areaListItems) { + if (item.x4_octTree == nullptr) { + continue; + } + + u32 wordModel = 0; + for (u32 i = 0; i < item.x4_octTree->x14_bitmapWordCount; ++i, wordModel += 32) { + const u32& word = modelBits[curWord + i]; + if (word == 0) { + continue; + } + for (u32 j = 0; j < 32; ++j) { + if (((1U << j) & word) != 0) { + if (alphaVal > 255) { + return; + } + + auto& model = *(*item.x10_models)[wordModel + j]; + CGX::SetTevKColor(GX_KCOLOR0, zeus::CColor{0.f, static_cast(alphaVal) / 255.f}); + model.SetArraysCurrent(); + for (const auto* surf = model.GetFirstUnsortedSurface(); surf != nullptr; surf = surf->GetNextSurface()) { + if (surf->GetBounds().intersects(aabb)) { + const auto& material = model.GetMaterialByIndex(surf->GetMaterialIndex()); + CGX::SetVtxDescv_Compressed(material.GetVertexDesc()); + CGX::CallDisplayList(surf->GetDisplayList(), surf->GetDisplayListSize()); + } + } + alphaVal += 4; + } + } + } + + curWord += item.x4_octTree->x14_bitmapWordCount; + } +} + +void CCubeRenderer::SetupCGraphicsState() { + CGraphics::DisableAllLights(); + CGraphics::SetModelMatrix({}); + CTevCombiners::ResetStates(); + CGraphics::SetAmbientColor({0.4f}); + CGX::SetChanMatColor(CGX::EChannelId::Channel0, zeus::skWhite); + CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true); + CGX::SetChanCtrl(CGX::EChannelId::Channel1, false, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + CCubeMaterial::EnsureTevsDirect(); +} + +void CCubeRenderer::SetupRendererStates(bool depthWrite) { + CGraphics::DisableAllLights(); + CGraphics::SetModelMatrix({}); + CGraphics::SetAmbientColor(zeus::skClear); + CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, depthWrite); + CCubeMaterial::ResetCachedMaterials(); + GXSetTevColor(GX_TEVREG1, to_gx_color(x2fc_tevReg1Color)); +} + +constexpr zeus::CTransform MvPostXf{ + {zeus::CVector3f{0.5f, 0.f, 0.f}, {0.f, 0.f, 0.f}, {0.f, 0.5f, 0.f}}, + {0.5f, 0.5f, 1.f}, +}; + +void CCubeRenderer::DoThermalModelDraw(CCubeModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol, + TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) { + SCOPED_GRAPHICS_DEBUG_GROUP("CCubeRenderer::DoThermalModelDraw", zeus::skBlue); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_NRM, GX_TEXMTX0, true, GX_PTTEXMTX0); + CGX::SetNumTexGens(1); + CGX::SetNumChans(0); + x220_sphereRamp.Load(GX_TEXMAP0, EClampMode::Clamp); + zeus::CTransform xf = CGraphics::g_ViewMatrix.inverse().multiplyIgnoreTranslation(CGraphics::g_GXModelMatrix); + xf.origin.zeroOut(); + GXLoadTexMtxImm(&xf, GX_TEXMTX0, GX_MTX3x4); + GXLoadTexMtxImm(&MvPostXf, GX_PTTEXMTX0, GX_MTX3x4); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_KONST); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_A0, GX_CA_KONST); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetNumTevStages(1); + CGX::SetTevKColor(GX_KCOLOR0, addCol); + CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + GXSetTevColor(GX_TEVREG0, to_gx_color(multCol)); + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + CGX::SetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_CLEAR); + CGX::SetZMode(flags.x2_flags.IsSet(CModelFlagBits::DepthTest), GX_LEQUAL, + flags.x2_flags.IsSet(CModelFlagBits::DepthUpdate)); + model.DrawFlat(positions, normals, + flags.x2_flags.IsSet(CModelFlagBits::ThermalUnsortedOnly) ? ESurfaceSelection::Unsorted + : ESurfaceSelection::All); +} + +void CCubeRenderer::ReallyDrawSpaceWarp(const zeus::CVector3f& pt, float strength) { + return; // TODO + + float vpLeft = static_cast(CGraphics::GetViewportLeft()); + float vpTop = static_cast(CGraphics::GetViewportTop()); + float vpHalfWidth = static_cast(CGraphics::GetViewportWidth() / 2); + float vpHalfHeight = static_cast(CGraphics::GetViewportHeight() / 2); + float local_100 = vpLeft + vpHalfWidth * pt.x() + vpHalfWidth; + float local_fc = vpTop + vpHalfHeight * -pt.y() + vpHalfHeight; + zeus::CVector2i CStack264{static_cast(local_100) & ~3, static_cast(local_fc) & ~3}; + auto v2right = CStack264 - zeus::CVector2i{96, 96}; + auto v2left = CStack264 + zeus::CVector2i{96, 96}; + zeus::CVector2f uv1min{0.f, 0.f}; + zeus::CVector2f uv1max{1.f, 1.f}; + + s32 aleft = CGraphics::GetViewportLeft() & ~3; + s32 atop = CGraphics::GetViewportTop() & ~3; + s32 aright = (CGraphics::GetViewportLeft() + CGraphics::GetViewportWidth() + 3) & ~3; + s32 abottom = (CGraphics::GetViewportTop() + CGraphics::GetViewportHeight() + 3) & ~3; + if (v2right.x < aleft) { + uv1min.x() = static_cast(aleft - v2right.x) * 0.005208333f; + v2right.x = aleft; + } + if (v2right.y < atop) { + uv1min.y() = static_cast(atop - v2right.x) * 0.005208333f; + v2right.y = atop; + } + if (v2left.x > aright) { + uv1max.x() = 1.f - static_cast(v2left.x - aright) * 0.005208333f; + v2left.x = aright; + } + if (v2left.y > abottom) { + uv1max.y() = 1.f - static_cast(v2left.y - abottom) * 0.005208333f; + v2left.y = abottom; + } + const auto v2sub = v2left - v2right; + if (v2sub.x > 0 && v2sub.y > 0) { + GXFogType fogType; + float fogStartZ; + float fogEndZ; + float fogNearZ; + float fogFarZ; + GXColor fogColor; + CGX::GetFog(&fogType, &fogStartZ, &fogEndZ, &fogNearZ, &fogFarZ, &fogColor); + CGX::SetFog(GX_FOG_NONE, fogStartZ, fogEndZ, fogNearZ, fogFarZ, fogColor); + GXSetTexCopySrc(v2right.x, v2right.y, v2sub.x, v2sub.y); + GXSetTexCopyDst(v2sub.x, v2sub.y, GX_TF_RGBA8, false); + GXCopyTex(CGraphics::sSpareTextureData, false); + GXPixModeSync(); + CGraphics::LoadDolphinSpareTexture(v2sub.x, v2sub.y, GX_TF_RGBA8, nullptr, GX_TEXMAP7); + x150_reflectionTex.Load(GX_TEXMAP1, EClampMode::Clamp); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC); + CGX::SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX3x4, GX_TG_TEX1, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP7, GX_COLOR_NULL); + } +} + +void CCubeRenderer::ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const CModel* model, + const CSkinnedModel* sModel) { + // TODO +} +} // namespace metaforce diff --git a/Runtime/Graphics/CCubeRenderer.hpp b/Runtime/Graphics/CCubeRenderer.hpp new file mode 100644 index 000000000..7c0a96a97 --- /dev/null +++ b/Runtime/Graphics/CCubeRenderer.hpp @@ -0,0 +1,243 @@ +#pragma once + +#include "Runtime/Graphics/CCubeModel.hpp" +#include "Runtime/Graphics/CPVSVisSet.hpp" +#include "Runtime/Graphics/CTexture.hpp" +#include "Runtime/Graphics/IRenderer.hpp" +#include "Runtime/CRandom16.hpp" +#include "Runtime/Graphics/CFont.hpp" + +#include + +namespace metaforce { +class IObjectStore; +class IFactory; + +class CCubeRenderer final : public IRenderer { + // TODO function for controlling x318_26_requestRGBA6 + // then these can be removed + friend class CMorphBallShadow; + friend class CWorldTransManager; + + struct CAreaListItem { + const std::vector* x0_geometry; + const CAreaRenderOctTree* x4_octTree; + /* originally auto_ptrs of vectors */ + std::unique_ptr>> x8_textures; + std::unique_ptr>> x10_models; + s32 x18_areaIdx; + /* Per-area octree-word major, light bits minor */ + std::vector x1c_lightOctreeWords; + + CAreaListItem(const std::vector* geom, const CAreaRenderOctTree* octTree, + std::unique_ptr>>&& textures, + std::unique_ptr>>&& models, s32 areaIdx); + }; + + struct CFogVolumeListItem { + zeus::CTransform x0_transform; + zeus::CColor x30_color; + zeus::CAABox x34_aabb; + TLockedToken x4c_model; + // bool x58_b; Optional for model token + const CSkinnedModel* x5c_skinnedModel = nullptr; + CFogVolumeListItem(const zeus::CTransform& xf, const zeus::CColor& color, const zeus::CAABox& aabb, + const TLockedToken* model, const CSkinnedModel* sModel) + : x0_transform(xf), x30_color(color), x34_aabb(aabb), x5c_skinnedModel(sModel) { + if (model) + x4c_model = *model; + } + }; + +private: + IFactory& x8_factory; + IObjectStore& xc_store; + CFont x10_font{1.f}; + u32 x18_primVertCount = 0; + std::list x1c_areaListItems; + // TODO x34...x40 + zeus::CFrustum x44_frustumPlanes; // {zeus::skIdentityMatrix4f, 1.5707964f, 1.f, 1.f, false, 100.f} + TDrawableCallback xa8_drawableCallback = nullptr; + void* xac_drawableCallbackUserData = nullptr; + zeus::CPlane xb0_viewPlane{0.f, 1.f, 0.f, 0.f}; + enum class EPVSMode : u8 { Mask, PVS, PVSAndMask } xc0_pvsMode = EPVSMode::Mask; + std::optional xc8_pvs; + bool xdc_{}; + u32 xe0_pvsAreaIdx = UINT32_MAX; + CTexture xe4_blackTex{ETexelFormat::RGB565, 4, 4, 1, "Black Texture"}; + std::unique_ptr x14c_reflectionTex; + CTexture x150_reflectionTex{ETexelFormat::IA8, 32, 32, 1, "Reflection Texture"}; + CTexture x1b8_fogVolumeRamp{ETexelFormat::I8, 256, 256, 1, "Fog Volume Ramp Texture"}; + CTexture x220_sphereRamp{ETexelFormat::I8, 32, 32, 1, "Sphere Ramp Texture"}; + CGraphicsPalette x288_thermoPalette{EPaletteFormat::RGB565, 16}; + CRandom16 x2a8_thermalRand{20}; + std::list x2ac_fogVolumes; + std::list> x2c4_spaceWarps; + u32 x2dc_reflectionAge = 2; + zeus::CColor x2e0_primColor = zeus::skWhite; + zeus::CVector3f x2e4_primNormal = zeus::skForward; + float x2f0_thermalVisorLevel = 1.f; + zeus::CColor x2f4_thermColor{1.f, 0.f, 1.f, 1.f}; + float x2f8_thermColdScale = 0.f; // ??? byte in code + zeus::CColor x2fc_tevReg1Color{1.f, 0.f, 1.f, 1.f}; + std::vector x300_dynamicLights; + u32 x310_phazonSuitMaskCountdown = 0; + std::unique_ptr x314_phazonSuitMask; + bool x318_24_refectionDirty : 1 = false; + bool x318_25_drawWireframe : 1 = false; + bool x318_26_requestRGBA6 : 1 = false; + bool x318_27_currentRGBA6 : 1 = false; + bool x318_28_disableFog : 1 = false; + bool x318_29_thermalVisor : 1 = false; + bool x318_30_inAreaDraw : 1 = false; + bool x318_31_persistRGBA6 : 1 = false; + + CTexture m_thermalRandomStatic{ETexelFormat::IA4, 640, 448, 1, "Thermal Random Static"}; + + void GenerateReflectionTex(); + void GenerateFogVolumeRampTex(); + void GenerateSphereRampTex(); + void LoadThermoPalette(); + + void ReallyDrawPhazonSuitIndirectEffect(const zeus::CColor& vertColor, CTexture& maskTex, CTexture& indTex, + const zeus::CColor& modColor, float scale, float offX, float offY); + void ReallyDrawPhazonSuitEffect(const zeus::CColor& modColor, CTexture& maskTex); + void DoPhazonSuitIndirectAlphaBlur(float blurRadius, float f2); + void ReallyDrawSpaceWarp(const zeus::CVector3f& pt, float strength); + void ReallyRenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const CModel* model, + const CSkinnedModel* sModel); + +public: + CCubeRenderer(IObjectStore& store, IFactory& resFac); + ~CCubeRenderer() override; + + void AddWorldSurfaces(CCubeModel& model); + void AddStaticGeometry(const std::vector* geometry, const CAreaRenderOctTree* octTree, + s32 areaIdx) override; + void EnablePVS(const CPVSVisSet& set, u32 areaIdx) override; + void DisablePVS() override; + void RemoveStaticGeometry(const std::vector* geometry) override; + void DrawUnsortedGeometry(s32 areaIdx, s32 mask, s32 targetMask) override; + void DrawSortedGeometry(s32 areaIdx, s32 mask, s32 targetMask) override; + void DrawStaticGeometry(s32 areaIdx, s32 mask, s32 targetMask) override; + void DrawAreaGeometry(s32 areaIdx, s32 mask, s32 targetMask) override; + void PostRenderFogs() override; + void SetModelMatrix(const zeus::CTransform& xf) override; + void AddParticleGen(CParticleGen& gen) override; + void AddParticleGen(CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds) override; + void AddPlaneObject(void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, s32 type) override; + void AddDrawable(void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, s32 mode, + EDrawableSorting sorting) override; + void SetDrawableCallback(TDrawableCallback cb, void* ctx) override; + void SetWorldViewpoint(const zeus::CTransform& xf) override; + void SetPerspective(float fovy, float aspect, float znear, float zfar) override; + void SetPerspective(float fovy, float width, float height, float znear, float zfar) override; + std::pair SetViewportOrtho(bool centered, float znear, float zfar) override; + void SetClippingPlanes(const zeus::CFrustum& frustum) override; + void SetViewport(s32 left, s32 right, s32 width, s32 height) override; + void SetDepthReadWrite(bool read, bool write) override { + CGraphics::SetDepthWriteMode(read, ERglEnum::LEqual, write); + } + void SetBlendMode_AdditiveAlpha() override { + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear); + } + void SetBlendMode_AlphaBlended() override { + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + } + void SetBlendMode_ColorMultiply() override { + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::Zero, ERglBlendFactor::SrcColor, ERglLogicOp::Clear); + } + void SetBlendMode_InvertDst() override { + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::InvSrcColor, ERglBlendFactor::Zero, + ERglLogicOp::Clear); + } + void SetBlendMode_InvertSrc() override { + CGraphics::SetBlendMode(ERglBlendMode::Logic, ERglBlendFactor::One, ERglBlendFactor::Zero, ERglLogicOp::InvCopy); + } + void SetBlendMode_NoColorWrite() override { + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::Zero, ERglBlendFactor::One, ERglLogicOp::Clear); + } + void SetBlendMode_Replace() override { + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::Zero, ERglLogicOp::Clear); + } + void SetBlendMode_AdditiveDestColor() override { + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcColor, ERglBlendFactor::One, ERglLogicOp::Clear); + } + void BeginScene() override; + void EndScene() override; + void SetDebugOption(EDebugOption, s32) override; + void BeginPrimitive(EPrimitiveType, s32) override; + void BeginLines(int) override; + void BeginLineStrip(int) override; + void BeginTriangles(int) override; + void BeginTriangleStrip(int) override; + void BeginTriangleFan(int) override; + void PrimVertex(const zeus::CVector3f&) override; + void PrimNormal(const zeus::CVector3f&) override; + void PrimColor(float, float, float, float) override; + void PrimColor(const zeus::CColor&) override; + void EndPrimitive() override; + void SetAmbientColor(const zeus::CColor& color) override; + void DrawString(const char* string, s32, s32) override; + u32 GetFPS() override; + void CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter) override; + void DrawSpaceWarp(const zeus::CVector3f& pt, float strength) override; + void DrawThermalModel(CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol, + TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) override; + void DrawModelDisintegrate(CModel& model, CTexture& tex, const zeus::CColor& color, TConstVectorRef positions, + TConstVectorRef normals, float t) override; + void DrawModelFlat(CModel& model, const CModelFlags& flags, bool unsortedOnly, TConstVectorRef positions, + TConstVectorRef normals) override; + void SetWireframeFlags(s32 flags) override; + void SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) override; + void RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const TLockedToken* model, + const CSkinnedModel* sModel) override; + void SetThermal(bool thermal, float level, const zeus::CColor& color) override; + void SetThermalColdScale(float scale) override; + void DoThermalBlendCold() override; + void DoThermalBlendHot() override; + u32 GetStaticWorldDataSize() override; + void SetGXRegister1Color(const zeus::CColor& color) override; + void SetWorldLightFadeLevel(float level) override; + void PrepareDynamicLights(const std::vector& lights) override; + + // Non-virtual functions + void SetupRendererStates(bool depthWrite); + void AllocatePhazonSuitMaskTexture(); + void DrawPhazonSuitIndirectEffect(const zeus::CColor& nonIndirectMod, const TLockedToken& indTex, + const zeus::CColor& indirectMod, float blurRadius, float scale, float offX, + float offY); + void DrawXRayOutline(const zeus::CAABox& aabb); + std::list::iterator FindStaticGeometry(const std::vector* geometry); + void FindOverlappingWorldModels(std::vector& modelBits, const zeus::CAABox& aabb) const; + s32 DrawOverlappingWorldModelIDs(s32 alphaVal, const std::vector& modelBits, const zeus::CAABox& aabb); + void DrawOverlappingWorldModelShadows(s32 alphaVal, const std::vector& modelBits, const zeus::CAABox& aabb); + void RenderBucketItems(const CAreaListItem* lights); + void DrawRenderBucketsDebug() {} + + void HandleUnsortedModel(CAreaListItem* areaItem, CCubeModel& model, const CModelFlags& flags); + void HandleUnsortedModelWireframe(CAreaListItem* areaItem, CCubeModel& model); + + void ActivateLightsForModel(const CAreaListItem* areaItem, CCubeModel& model); + + void DoThermalModelDraw(CCubeModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol, + TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags); + + // Getters + [[nodiscard]] bool IsInAreaDraw() const { return x318_30_inAreaDraw; } + [[nodiscard]] bool IsReflectionDirty() const { return x318_24_refectionDirty; } + void SetReflectionDirty(bool v) { x318_24_refectionDirty = v; } + [[nodiscard]] bool IsThermalVisorActive() const { return x318_29_thermalVisor; } + CTexture* GetRealReflection() { + x2dc_reflectionAge = 0; + if (x14c_reflectionTex) { + return x14c_reflectionTex.get(); + } + + return &xe4_blackTex; + } + + static void SetupCGraphicsState(); +}; +} // namespace metaforce diff --git a/Runtime/Graphics/CCubeSurface.cpp b/Runtime/Graphics/CCubeSurface.cpp new file mode 100644 index 000000000..9edc0c44c --- /dev/null +++ b/Runtime/Graphics/CCubeSurface.cpp @@ -0,0 +1,19 @@ +#include "CCubeSurface.hpp" + +#include "Streams/IOStreams.hpp" + +namespace metaforce { +CCubeSurface::CCubeSurface(const u8* ptr, u32 len) : x0_data(ptr) { + CMemoryInStream mem(ptr, len, CMemoryInStream::EOwnerShip::NotOwned); + x0_center = mem.Get(); + xc_materialIndex = mem.ReadLong(); + x10_displayListSize = mem.ReadLong(); + mem.ReadLong(); // x14_parent + mem.ReadLong(); // x18_nextSurface + x1c_extraSize = mem.ReadLong(); + x20_normal = mem.Get(); + if (x1c_extraSize > 0) { + x24_bounds = mem.Get(); + } +} +} // namespace metaforce diff --git a/Runtime/Graphics/CCubeSurface.hpp b/Runtime/Graphics/CCubeSurface.hpp new file mode 100644 index 000000000..fa1197afd --- /dev/null +++ b/Runtime/Graphics/CCubeSurface.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +#include "GCNTypes.hpp" + +#include +#include + +namespace metaforce { +class CCubeModel; + +class CCubeSurface { + static constexpr zeus::CVector3f skDefaultNormal{1.f, 0.f, 0.f}; + const u8* x0_data; + + // Extracted from surface data + zeus::CVector3f x0_center; + u32 xc_materialIndex; + u32 x10_displayListSize; + CCubeModel* x14_parent = nullptr; + CCubeSurface* x18_nextSurface = nullptr; + u32 x1c_extraSize; + zeus::CVector3f x20_normal; + zeus::CAABox x24_bounds; + +public: + explicit CCubeSurface(const u8* ptr, u32 len); // Metaforce addition for extracting surface data + + // bool IsValid() const; + [[nodiscard]] CCubeModel* GetParent() { return x14_parent; } + [[nodiscard]] const CCubeModel* GetParent() const { return x14_parent; } + void SetParent(CCubeModel* parent) { x14_parent = parent; } + [[nodiscard]] CCubeSurface* GetNextSurface() { return x18_nextSurface; } + [[nodiscard]] const CCubeSurface* GetNextSurface() const { return x18_nextSurface; } + void SetNextSurface(CCubeSurface* next) { x18_nextSurface = next; } + [[nodiscard]] u32 GetMaterialIndex() const { return xc_materialIndex; } + [[nodiscard]] u32 GetDisplayListSize() const { return x10_displayListSize & 0x7fffffff; } + [[nodiscard]] u32 GetNormalHint() const { return (x10_displayListSize >> 31) & 1; } + [[nodiscard]] const u8* GetDisplayList() const { return x0_data + GetSurfaceHeaderSize(); } + [[nodiscard]] u32 GetSurfaceHeaderSize() const { return (0x4b + x1c_extraSize) & ~31; } + [[nodiscard]] zeus::CVector3f GetCenter() const { return x0_center; } + [[nodiscard]] zeus::CAABox GetBounds() const { + return x1c_extraSize != 0 ? x24_bounds : zeus::CAABox{x0_center, x0_center}; + } +}; +} // namespace metaforce diff --git a/Runtime/Graphics/CDrawable.hpp b/Runtime/Graphics/CDrawable.hpp index 5a84a1dd5..19f584a91 100644 --- a/Runtime/Graphics/CDrawable.hpp +++ b/Runtime/Graphics/CDrawable.hpp @@ -4,7 +4,14 @@ #include namespace metaforce { -enum class EDrawableType : u16 { WorldSurface, Particle, Actor, SimpleShadow, Decal }; +enum class EDrawableType : u16 { + WorldSurface, + Particle, + Actor, + SimpleShadow, + Decal, + Invalid = 0xFFFF, +}; class CDrawable { EDrawableType x0_type; diff --git a/Runtime/Graphics/CFont.cpp b/Runtime/Graphics/CFont.cpp new file mode 100644 index 000000000..16d771e11 --- /dev/null +++ b/Runtime/Graphics/CFont.cpp @@ -0,0 +1,86 @@ +#include "Runtime/Graphics/CFont.hpp" + +#include "Runtime/Graphics/CGraphics.hpp" + +namespace metaforce { +/* TODO: Custom I8 font */ +std::array CFont::sSystemFont = { + /* Omitted due to copyright issues */}; + +u32 CFont::sNumInstances = 0; +std::unique_ptr CFont::mpTexture; + +CFont::CFont(float scale) : x0_fontSize(16.f * scale), x4_scale(scale) { + if (sNumInstances == 0) { + mpTexture = std::make_unique(ETexelFormat::I8, 256, 256, 1, "Font Texture"); + u8* fontData = new u8[(mpTexture->GetBitDepth() * mpTexture->GetWidth() * mpTexture->GetHeight()) / 8]; + memcpy(fontData, sSystemFont.data(), sSystemFont.size()); + // u8* textureData = mpTexture->GetBitMapData(); + // LinearToTile8(textureData, fontData); + delete[] fontData; + // mpTexture->UnLock(); + } + ++sNumInstances; +} + +void CFont::Shutdown() { + mpTexture.reset(); +} + +void CFont::TileCopy8(u8* dest, const u8* src) { + for (u32 i = 0; i < 4; ++i) { + dest[0] = src[0]; + dest[1] = src[1]; + dest[2] = src[2]; + dest[3] = src[3]; + dest[4] = src[4]; + dest[5] = src[5]; + dest[6] = src[6]; + dest[7] = src[7]; + src += 256; + dest += 8; + } +} + +void CFont::LinearToTile8(u8* dest, const u8* src) { + int iVar1 = 0; + int iVar2 = 0; + for (size_t y = 0; y < 256; y += 4) { + iVar2 = iVar1; + for (size_t x = 0; x < 256; x += 8) { + TileCopy8(dest, src + iVar2); + dest += 32; + iVar2 += 8; + } + iVar1 += 1024; + } +} + +void CFont::DrawString(const char* str, int x, int y, const zeus::CColor& col) { + bool bVar2 = CGraphics::BeginRender2D(*mpTexture.get()); + char chr = *str; + while (chr != 0) { + u32 cellSize = static_cast(16.f * x4_scale); + ++str; + CGraphics::DoRender2D(*mpTexture, x, y, (chr & 0xf) * 16, 0xf0, 0x10, cellSize, cellSize, col); + chr = *str; + } + CGraphics::EndRender2D(bVar2); +} + +u32 CFont::StringWidth(const char* str) const { + u32 width = 0; + char chr = *str; + while (chr != 0) { + ++str; + width += static_cast(15.f * x4_scale); + chr = *str; + } + + return width; +} + +u32 CFont::CharsWidth(const char* str, u32 len) const { return len * (15.f * x4_scale); } + +u32 CFont::CharWidth(const char chr) const { return 15.f * x4_scale; } +} // namespace metaforce diff --git a/Runtime/Graphics/CFont.hpp b/Runtime/Graphics/CFont.hpp new file mode 100644 index 000000000..f37e54bfb --- /dev/null +++ b/Runtime/Graphics/CFont.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "Runtime/GCNTypes.hpp" +#include "Runtime/Graphics/CTexture.hpp" + +#include + +#include +#include + +namespace metaforce { +class CFont { + static std::array sSystemFont; + static u32 sNumInstances; + static std::unique_ptr mpTexture; + float x0_fontSize; + float x4_scale; + void TileCopy8(u8* dest, const u8* src); + void LinearToTile8(u8* dest, const u8* src); +public: + explicit CFont(float scale); + + void DrawString(const char* str, int x, int y, const zeus::CColor& color); + u32 StringWidth(const char* str) const; + u32 CharsWidth(const char* str, u32 len) const; + u32 CharWidth(const char chr) const; + + static void Shutdown(); +}; +} \ No newline at end of file diff --git a/Runtime/Graphics/CGX.cpp b/Runtime/Graphics/CGX.cpp new file mode 100644 index 000000000..ce3c618dc --- /dev/null +++ b/Runtime/Graphics/CGX.cpp @@ -0,0 +1,33 @@ +#include "CGX.hpp" + +#include "Graphics/CTexture.hpp" + +namespace metaforce::CGX { +SGXState sGXState{}; +std::array sVtxDescList{}; + +void ResetGXStates() noexcept { + sGXState.x48_descList = 0; + GXClearVtxDesc(); + sGXState.x0_arrayPtrs.fill(nullptr); + for (GXTexMapID id = GX_TEXMAP0; id < GX_MAX_TEXMAP; id = static_cast(id + 1)) { + CTexture::InvalidateTexMap(id); + } + for (GXTevKColorID id = GX_KCOLOR0; const auto& item : sGXState.x58_kColors) { + GXSetTevKColor(id, item); + id = static_cast(id + 1); + } + GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_RED); + GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_GREEN); + GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_BLUE); + SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetCurrentMtx(GX_PNMTX0); + SetNumIndStages(0); + // TODO GXSetIndTexCoordScale + for (GXTevStageID id = GX_TEVSTAGE0; id < GX_MAX_TEVSTAGE; id = static_cast(id + 1)) { + SetTevDirect(id); + } + // GXSetTexCoordCylWrap + // GXSetZTexture +} +} // namespace metaforce::CGX diff --git a/Runtime/Graphics/CGX.hpp b/Runtime/Graphics/CGX.hpp new file mode 100644 index 000000000..efa17c9ba --- /dev/null +++ b/Runtime/Graphics/CGX.hpp @@ -0,0 +1,465 @@ +#pragma once + +#include "Graphics/GX.hpp" +#include "RetroTypes.hpp" + +#include + +namespace metaforce::CGX { +enum class EChannelId { + Channel0, // GX_COLOR0 + Channel1, // GX_COLOR1 +}; + +struct STevState { + u32 x0_colorInArgs = 0; + u32 x4_alphaInArgs = 0; + u32 x8_colorOps = 0; + u32 xc_alphaOps = 0; + u32 x10_indFlags = 0; + u32 x14_tevOrderFlags = 0; + GXTevKColorSel x18_kColorSel = GX_TEV_KCSEL_1; + GXTevKAlphaSel x19_kAlphaSel = GX_TEV_KASEL_1; +}; +struct STexState { + u32 x0_coordGen = 0; +}; +struct SGXState { + std::array x0_arrayPtrs{}; + std::array x30_prevChanCtrls{}; + std::array x34_chanCtrls{0x4000, 0x4000}; + std::array x38_chanAmbColors; + std::array x40_chanMatColors; + u32 x48_descList = 0; + u8 x4c_dirtyChans = 0; + u8 x4d_prevNumChans = 0; + u8 x4e_numChans = 0; + u8 x4f_numTexGens = 0; + u8 x50_numTevStages = 0; + u8 x51_numIndStages = 0; + u8 x52_zmode = 0; + GXFogType x53_fogType = GX_FOG_NONE; + u16 x54_lineWidthAndOffset = 0; + u16 x56_blendMode = 0; + std::array x58_kColors; + std::array x68_tevStates; + std::array x228_texStates; + u32 x248_alphaCompare = 0; + float x24c_fogStartZ = 0.f; + float x250_fogEndZ = 0.f; + float x254_fogNearZ = 0.f; + float x258_fogFarZ = 0.f; + GXColor x25c_fogColor; +}; +extern SGXState sGXState; +extern std::array sVtxDescList; + +static inline void update_fog(u32 value) noexcept { + if (sGXState.x53_fogType == GX_FOG_NONE || (sGXState.x56_blendMode & 0xE0) == (value & 0xE0)) { + return; + } + if ((value & 0xE0) == 0x20) { + GXSetFogColor(GX_CLEAR); + return; + } + GXSetFogColor(sGXState.x25c_fogColor); +} + +static inline void FlushState() noexcept { + if ((sGXState.x4c_dirtyChans & 1) != 0) { + u8 numChans = sGXState.x4e_numChans; + GXSetNumChans(numChans); + sGXState.x4d_prevNumChans = numChans; + } + if ((sGXState.x4c_dirtyChans & 2) != 0) { + auto flags = sGXState.x34_chanCtrls[0]; + GXSetChanCtrl(GX_COLOR0, GXBool(flags & 1), GXColorSrc(flags >> 1 & 1), GXColorSrc(flags >> 2 & 1), + flags >> 3 & 0xFF, GXDiffuseFn(flags >> 11 & 3), GXAttnFn(flags >> 13 & 3)); + sGXState.x30_prevChanCtrls[0] = flags; + } + if ((sGXState.x4c_dirtyChans & 4) != 0) { + auto flags = sGXState.x34_chanCtrls[1]; + GXSetChanCtrl(GX_COLOR1, GXBool(flags & 1), GXColorSrc(flags >> 1 & 1), GXColorSrc(flags >> 2 & 1), + flags >> 3 & 0xFF, GXDiffuseFn(flags >> 11 & 3), GXAttnFn(flags >> 13 & 3)); + sGXState.x30_prevChanCtrls[1] = flags; + } + sGXState.x4c_dirtyChans = 0; +} + +static inline void Begin(GXPrimitive primitive, GXVtxFmt fmt, u16 nverts) noexcept { + if (sGXState.x4c_dirtyChans != 0) { + FlushState(); + } + GXBegin(primitive, fmt, nverts); +} + +static inline void End() noexcept { GXEnd(); } + +static inline void CallDisplayList(const void* data, u32 nbytes) noexcept { + if (sGXState.x4c_dirtyChans != 0) { + FlushState(); + } + GXCallDisplayList(data, nbytes); +} + +static inline const GXColor& GetChanAmbColor(EChannelId id) noexcept { + const auto idx = std::underlying_type_t(id); + return sGXState.x38_chanAmbColors[idx]; +} + +void ResetGXStates() noexcept; + +static inline void SetAlphaCompare(GXCompare comp0, u8 ref0, GXAlphaOp op, GXCompare comp1, u8 ref1) noexcept { + u32 flags = ref1 << 17 | (comp1 & 7) << 14 | (op & 7) << 11 | ref0 << 3 | (comp0 & 7); + if (flags != sGXState.x248_alphaCompare) { + sGXState.x248_alphaCompare = flags; + GXSetAlphaCompare(comp0, ref0, op, comp1, ref1); + GXSetZCompLoc(comp0 == GX_ALWAYS); + } +} + +template +static inline void SetArray(GXAttr attr, const std::vector* data, bool isStatic) noexcept { + if (data != nullptr && sGXState.x0_arrayPtrs[attr - GX_VA_POS] != data) { + GXSetArray(attr, data->data(), data->size() * sizeof(T), sizeof(T)); + } +} + +static inline void SetBlendMode(GXBlendMode mode, GXBlendFactor srcFac, GXBlendFactor dstFac, GXLogicOp op) noexcept { + const u16 flags = (op & 0xF) << 8 | (dstFac & 7) << 5 | (srcFac & 7) << 2 | (mode & 3); + if (flags != sGXState.x56_blendMode) { + update_fog(flags); + sGXState.x56_blendMode = flags; + GXSetBlendMode(mode, srcFac, dstFac, op); + } +} + +static inline void SetChanAmbColor(EChannelId id, GXColor color) noexcept { + const auto idx = std::underlying_type_t(id); + if (color != sGXState.x38_chanAmbColors[idx]) { + sGXState.x38_chanAmbColors[idx] = color; + GXSetChanAmbColor(GXChannelID(idx + GX_COLOR0A0), color); + } +} +static inline void SetChanAmbColor(EChannelId id, const zeus::CColor& color) noexcept { + SetChanAmbColor(id, to_gx_color(color)); +} + +static inline void SetChanCtrl(EChannelId id, GXBool enable, GXColorSrc ambSrc, GXColorSrc matSrc, GX::LightMask lights, + GXDiffuseFn diffFn, GXAttnFn attnFn) noexcept { + const auto idx = std::underlying_type_t(id); + if (lights.none()) { + enable = false; + } + const u32 flags = (attnFn & 3) << 13 | (diffFn & 3) << 11 | (lights.to_ulong() & 0xFF) << 3 | (matSrc & 1) << 2 | + (ambSrc & 1) << 1 | (u8(enable) & 1); + sGXState.x34_chanCtrls[idx] = flags; + sGXState.x4c_dirtyChans = 7; // TODO +} + +// Flags with lights override +static inline void SetChanCtrl(EChannelId id, u32 flags, GX::LightMask lights) noexcept { + const auto idx = std::underlying_type_t(id); + sGXState.x34_chanCtrls[idx] = lights.any() ? (flags | lights.to_ulong() << 3) : (flags & 0xFFFFFFFE); + sGXState.x4c_dirtyChans = 7; // TODO +} + +// Helper function for common logic +static inline void SetChanCtrl(EChannelId id, GX::LightMask lights) noexcept { + const bool hasLights = lights.any(); + SetChanCtrl(id, hasLights, GX_SRC_REG, GX_SRC_REG, lights, hasLights ? GX_DF_CLAMP : GX_DF_NONE, + hasLights ? GX_AF_SPOT : GX_AF_NONE); +} + +static inline void SetChanMatColor(EChannelId id, GXColor color) noexcept { + const auto idx = std::underlying_type_t(id); + if (color != sGXState.x40_chanMatColors[idx]) { + sGXState.x40_chanMatColors[idx] = color; + GXSetChanMatColor(GXChannelID(idx + GX_COLOR0A0), color); + } +} +static inline void SetChanMatColor(EChannelId id, const zeus::CColor& color) noexcept { + SetChanMatColor(id, to_gx_color(color)); +} + +static inline void SetFog(GXFogType type, float startZ, float endZ, float nearZ, float farZ, + const GXColor& color) noexcept { + sGXState.x25c_fogColor = color; + sGXState.x53_fogType = type; + sGXState.x24c_fogStartZ = startZ; + sGXState.x250_fogEndZ = endZ; + sGXState.x254_fogNearZ = nearZ; + sGXState.x258_fogFarZ = farZ; + auto fogColor = color; + if ((sGXState.x56_blendMode & 0xE0) == 0x20) { + fogColor = GX_CLEAR; + } + GXSetFog(type, startZ, endZ, nearZ, farZ, fogColor); +} + +void SetIndTexMtxSTPointFive(GXIndTexMtxID id, s8 scaleExp) noexcept; + +void SetLineWidth(u8 width, GXTexOffset offset) noexcept; + +static inline void SetNumChans(u8 num) noexcept { + sGXState.x4c_dirtyChans = 7; // TODO + sGXState.x4e_numChans = num; +} + +static inline void SetNumIndStages(u8 num) noexcept { + auto& state = sGXState.x51_numIndStages; + if (num != state) { + state = num; + GXSetNumIndStages(num); + } +} + +static inline void SetNumTevStages(u8 num) noexcept { + auto& state = sGXState.x50_numTevStages; + if (num != state) { + state = num; + GXSetNumTevStages(num); + } +} + +static inline void SetNumTexGens(u8 num) noexcept { + auto& state = sGXState.x4f_numTexGens; + if (num != state) { + state = num; + GXSetNumTexGens(num); + } +} + +static inline void SetStandardTevColorAlphaOp(GXTevStageID stageId) noexcept { + auto& state = sGXState.x68_tevStates[stageId]; + if (state.x8_colorOps != 0x100 || state.xc_alphaOps != 0x100) { + state.x8_colorOps = 0x100; + state.xc_alphaOps = 0x100; + GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + } +} + +static inline void SetTevAlphaIn(GXTevStageID stageId, GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, + GXTevAlphaArg d) noexcept { + u32 flags = (d & 31) << 15 | (c & 31) << 10 | (b & 31) << 5 | (a & 31); + auto& state = sGXState.x68_tevStates[stageId].x4_alphaInArgs; + if (flags != state) { + state = flags; + GXSetTevAlphaIn(stageId, a, b, c, d); + } +} + +static inline void SetTevAlphaOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID outReg) noexcept { + u32 flags = (outReg & 3) << 9 | (u8(clamp) & 1) << 8 | (scale & 3) << 6 | (bias & 3) << 4 | (op & 15); + auto& state = sGXState.x68_tevStates[stageId].xc_alphaOps; + if (flags != state) { + state = flags; + GXSetTevAlphaOp(stageId, op, bias, scale, clamp, outReg); + } +} + +static inline void SetTevAlphaOp_Compressed(GXTevStageID stageId, u32 ops) noexcept { + auto& state = sGXState.x68_tevStates[stageId].xc_alphaOps; + if (ops != state) { + state = ops; + GXSetTevAlphaOp(stageId, GXTevOp(ops & 31), GXTevBias(ops >> 4 & 3), GXTevScale(ops >> 6 & 3), GXBool(ops >> 8 & 1), + GXTevRegID(ops >> 9 & 3)); + } +} + +static inline void SetTevColorIn(GXTevStageID stageId, GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, + GXTevColorArg d) noexcept { + u32 flags = (d & 31) << 15 | (c & 31) << 10 | (b & 31) << 5 | (a & 31); + auto& state = sGXState.x68_tevStates[stageId].x0_colorInArgs; + if (flags != state) { + state = flags; + GXSetTevColorIn(stageId, a, b, c, d); + } +} + +static inline void SetTevColorOp(GXTevStageID stageId, GXTevOp op, GXTevBias bias, GXTevScale scale, GXBool clamp, + GXTevRegID outReg) noexcept { + u32 flags = (outReg & 3) << 9 | (u8(clamp) & 1) << 8 | (scale & 3) << 6 | (bias & 3) << 4 | (op & 15); + auto& state = sGXState.x68_tevStates[stageId].x8_colorOps; + if (flags != state) { + state = flags; + GXSetTevColorOp(stageId, op, bias, scale, clamp, outReg); + } +} + +static inline void SetTevColorOp_Compressed(GXTevStageID stageId, u32 ops) noexcept { + auto& state = sGXState.x68_tevStates[stageId].x8_colorOps; + if (ops != state) { + state = ops; + GXSetTevColorOp(stageId, GXTevOp(ops & 31), GXTevBias(ops >> 4 & 3), GXTevScale(ops >> 6 & 3), GXBool(ops >> 8 & 1), + GXTevRegID(ops >> 9 & 3)); + } +} + +static inline void SetTevDirect(GXTevStageID stageId) noexcept { + auto& state = sGXState.x68_tevStates[stageId].x10_indFlags; + if (state != 0) { + state = 0; + GXSetTevDirect(stageId); + } +} + +static inline void SetStandardDirectTev_Compressed(GXTevStageID stageId, u32 colorArgs, u32 alphaArgs, u32 colorOps, + u32 alphaOps) noexcept { + auto& state = sGXState.x68_tevStates[stageId]; + SetTevDirect(stageId); + if (state.x0_colorInArgs != colorArgs) { + state.x0_colorInArgs = colorArgs; + GXSetTevColorIn(stageId, GXTevColorArg(colorArgs & 31), GXTevColorArg(colorArgs >> 5 & 31), + GXTevColorArg(colorArgs >> 10 & 31), GXTevColorArg(colorArgs >> 15 & 31)); + } + if (state.x4_alphaInArgs != alphaArgs) { + state.x4_alphaInArgs = alphaArgs; + GXSetTevAlphaIn(stageId, GXTevAlphaArg(alphaArgs & 31), GXTevAlphaArg(alphaArgs >> 5 & 31), + GXTevAlphaArg(alphaArgs >> 10 & 31), GXTevAlphaArg(alphaArgs >> 15 & 31)); + } + if (colorOps != alphaOps || (colorOps & 0x1FF) != 0x100) { + SetTevColorOp_Compressed(stageId, colorOps); + SetTevAlphaOp_Compressed(stageId, alphaOps); + } else if (colorOps != state.x8_colorOps || colorOps != state.xc_alphaOps) { + state.x8_colorOps = colorOps; + state.xc_alphaOps = colorOps; + const auto outReg = GXTevRegID(colorOps >> 9 & 3); + GXSetTevColorOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, outReg); + GXSetTevAlphaOp(stageId, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, outReg); + } +} + +static inline void SetTevIndirect(GXTevStageID stageId, GXIndTexStageID indStage, GXIndTexFormat fmt, + GXIndTexBiasSel biasSel, GXIndTexMtxID mtxSel, GXIndTexWrap wrapS, GXIndTexWrap wrapT, + GXBool addPrev, GXBool indLod, GXIndTexAlphaSel alphaSel) noexcept { + // TODO + GXSetTevIndirect(stageId, indStage, fmt, biasSel, mtxSel, wrapS, wrapT, addPrev, indLod, alphaSel); +} + +static inline void SetTevIndWarp(GXTevStageID stageId, GXIndTexStageID indStage, GXBool signedOffset, + GXBool replaceMode, GXIndTexMtxID mtxSel) noexcept { + // TODO + GXSetTevIndWarp(stageId, indStage, signedOffset, replaceMode, mtxSel); +} + +static inline void SetTevKAlphaSel(GXTevStageID stageId, GXTevKAlphaSel sel) noexcept { + auto& state = sGXState.x68_tevStates[stageId].x19_kAlphaSel; + if (sel != state) { + state = sel; + GXSetTevKAlphaSel(stageId, sel); + } +} + +static inline void SetTevKColor(GXTevKColorID id, const GXColor& color) noexcept { + auto& state = sGXState.x58_kColors[id]; + if (color != state) { + state = color; + GXSetTevKColor(id, color); + } +} +static inline void SetTevKColor(GXTevKColorID id, const zeus::CColor& color) noexcept { + SetTevKColor(id, to_gx_color(color)); +} + +static inline void SetTevKColorSel(GXTevStageID stageId, GXTevKColorSel sel) noexcept { + auto& state = sGXState.x68_tevStates[stageId].x18_kColorSel; + if (sel != state) { + state = sel; + GXSetTevKColorSel(stageId, sel); + } +} + +static inline void SetTevOrder(GXTevStageID stageId, GXTexCoordID texCoord, GXTexMapID texMap, + GXChannelID color) noexcept { + u32 flags = (color & 0xFF) << 16 | (texMap & 0xFF) << 8 | (texCoord & 0xFF); + auto& state = sGXState.x68_tevStates[stageId].x14_tevOrderFlags; + if (flags != state) { + state = flags; + GXSetTevOrder(stageId, texCoord, texMap, color); + } +} + +static inline void SetTexCoordGen(GXTexCoordID dstCoord, GXTexGenType fn, GXTexGenSrc src, GXTexMtx mtx, + GXBool normalize, GXPTTexMtx postMtx) noexcept { + u32 flags = ((postMtx - GX_PTTEXMTX0) & 63) << 15 | (u8(normalize) & 1) << 14 | ((mtx - GX_TEXMTX0) & 31) << 9 | + (src & 31) << 4 | (fn & 15); + auto& state = sGXState.x228_texStates[dstCoord].x0_coordGen; + if (flags != state) { + state = flags; + GXSetTexCoordGen2(dstCoord, fn, src, mtx, normalize, postMtx); + } +} + +static inline void SetTexCoordGen(GXTexCoordID dstCoord, u32 flags) noexcept { + auto& state = sGXState.x228_texStates[dstCoord].x0_coordGen; + if (flags != state) { + state = flags; + GXSetTexCoordGen2(dstCoord, GXTexGenType(flags & 15), GXTexGenSrc(flags >> 4 & 31), + GXTexMtx((flags >> 9 & 31) + GX_TEXMTX0), GXBool(flags >> 14 & 1), + GXPTTexMtx((flags >> 15 & 63) + GX_PTTEXMTX0)); + } +} + +static inline void SetVtxDescv_Compressed(u32 descList) noexcept { + u32 currentDescList = sGXState.x48_descList; + if (descList != currentDescList) { + size_t remain = sVtxDescList.size() - 1; + u32 shift = 0; + u32 attrIdx = 0; + do { + sVtxDescList[attrIdx] = { + GXAttr(GX_VA_POS + attrIdx), + GXAttrType(descList >> shift & 3), + }; + shift += 2; + ++attrIdx; + --remain; + } while (remain != 0); + sVtxDescList[attrIdx] = {GX_VA_NULL, GX_NONE}; + GXSetVtxDescv(sVtxDescList.data()); + sGXState.x48_descList = descList; + } +} + +static inline void SetVtxDescv(const GXVtxDescList* descList) noexcept { + u32 flags = 0; + for (; descList->attr != GX_VA_NULL; ++descList) { + flags |= (descList->type & 3) << (descList->attr - GX_VA_POS) * 2; + } + SetVtxDescv_Compressed(flags); +} + +static inline void SetZMode(GXBool compareEnable, GXCompare func, GXBool updateEnable) noexcept { + u32 flags = (func & 0xFF) << 2 | (u8(updateEnable) << 1) | (u8(compareEnable) & 1); + auto& state = sGXState.x52_zmode; + if (flags != state) { + state = flags; + GXSetZMode(compareEnable, func, updateEnable); + } +} + +static inline void GetFog(GXFogType* fogType, float* fogStartZ, float* fogEndZ, float* fogNearZ, float* fogFarZ, + GXColor* fogColor) { + if (fogType != nullptr) { + *fogType = sGXState.x53_fogType; + } + if (fogStartZ != nullptr) { + *fogStartZ = sGXState.x24c_fogStartZ; + } + if (fogEndZ != nullptr) { + *fogEndZ = sGXState.x250_fogEndZ; + } + if (fogNearZ != nullptr) { + *fogNearZ = sGXState.x254_fogNearZ; + } + if (fogFarZ != nullptr) { + *fogFarZ = sGXState.x258_fogFarZ; + } + if (fogColor != nullptr) { + *fogColor = sGXState.x25c_fogColor; + } +} +} // namespace metaforce::CGX diff --git a/Runtime/Graphics/CGraphics.cpp b/Runtime/Graphics/CGraphics.cpp index a591ba669..aca9da9a6 100644 --- a/Runtime/Graphics/CGraphics.cpp +++ b/Runtime/Graphics/CGraphics.cpp @@ -1,26 +1,25 @@ #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/CTimeProvider.hpp" -#include "Runtime/Graphics/CLight.hpp" #include "Runtime/Graphics/CLineRenderer.hpp" +#include "Runtime/Graphics/CTexture.hpp" #include "Runtime/Graphics/Shaders/CTextSupportShader.hpp" #include "Runtime/GuiSys/CGuiSys.hpp" +#include "Runtime/Graphics/CGX.hpp" #include namespace metaforce { - CGraphics::CProjectionState CGraphics::g_Proj; -CGraphics::CFogState CGraphics::g_Fog; -std::array CGraphics::g_ColorRegs{}; +// CFogState CGraphics::g_Fog; float CGraphics::g_ProjAspect = 1.f; -u32 CGraphics::g_NumLightsActive = 0; u32 CGraphics::g_NumBreakpointsWaiting = 0; u32 CGraphics::g_FlippingState; bool CGraphics::g_LastFrameUsedAbove = false; bool CGraphics::g_InterruptLastFrameUsedAbove = false; -ERglLightBits CGraphics::g_LightActive = ERglLightBits::None; -ERglLightBits CGraphics::g_LightsWereOn = ERglLightBits::None; +GX::LightMask CGraphics::g_LightActive{}; +std::array CGraphics::g_LightObjs; +std::array CGraphics::g_LightTypes; zeus::CTransform CGraphics::g_GXModelView; zeus::CTransform CGraphics::g_GXModelViewInvXpose; zeus::CTransform CGraphics::g_GXModelMatrix = zeus::CTransform(); @@ -30,14 +29,19 @@ zeus::CTransform CGraphics::g_GXViewPointMatrix; zeus::CTransform CGraphics::g_CameraMatrix; SClipScreenRect CGraphics::g_CroppedViewport; bool CGraphics::g_IsGXModelMatrixIdentity = true; -SViewport g_Viewport = { +zeus::CColor CGraphics::g_ClearColor = zeus::skClear; +float CGraphics::g_ClearDepthValue = 1.f; +bool CGraphics::g_IsBeginSceneClearFb = true; + +SViewport CGraphics::g_Viewport = { 0, 0, 640, 480, 640 / 2.f, 480 / 2.f, 0.0f, }; u32 CGraphics::g_FrameCounter = 0; u32 CGraphics::g_Framerate = 0; u32 CGraphics::g_FramesPast = 0; frame_clock::time_point CGraphics::g_FrameStartTime = frame_clock::now(); -bool CGraphics::g_commitAsLazy = false; +ERglEnum CGraphics::g_depthFunc = ERglEnum::Never; +ERglCullMode CGraphics::g_cullMode = ERglCullMode::None; const std::array CGraphics::skCubeBasisMats{{ /* Right */ @@ -53,62 +57,116 @@ const std::array CGraphics::skCubeBasisMats{{ /* Forward */ {-1.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, -1.f}, }}; +// We don't actually store anything here +u8 CGraphics::sSpareTextureData[] = {0}; + +// Stream API +static u32 sStreamFlags; +static GXPrimitive sStreamPrimitive; +static u32 sVerticesCount; +static zeus::CColor sQueuedColor; +// Originally writes directly to GX FIFO +struct StreamVertex { + zeus::CColor color; + zeus::CVector2f texCoord; + zeus::CVector3f normal; + zeus::CVector3f vertex; + constexpr StreamVertex(const zeus::CColor& color) : color(color) {} + constexpr StreamVertex(const StreamVertex&) = default; +}; +static std::vector sQueuedVertices; void CGraphics::DisableAllLights() { - g_NumLightsActive = 0; - g_LightActive = ERglLightBits::None; - // TODO: turn lights off for real + g_LightActive.reset(); + CGX::SetChanCtrl(CGX::EChannelId::Channel0, {}); } void CGraphics::LoadLight(ERglLight light, const CLight& info) { - // TODO: load light for real + const auto lightId = static_cast(1 << light); + + auto& obj = g_LightObjs[light]; + zeus::CVector3f pos = info.GetPosition(); + zeus::CVector3f dir = info.GetDirection(); + const auto type = info.GetType(); + if (type == ELightType::Directional) { + dir = -(g_CameraMatrix.buildMatrix3f() * dir); + GXInitLightPos(&obj, dir.x() * 1048576.f, dir.y() * 1048576.f, dir.z() * 1048576.f); + GXInitLightAttn(&obj, 1.f, 0.f, 0.f, 1.f, 0.f, 0.f); + } else if (type == ELightType::Spot) { + pos = g_CameraMatrix * pos; + GXInitLightPos(&obj, pos.x(), pos.y(), pos.z()); + dir = g_CameraMatrix.buildMatrix3f() * dir; + GXInitLightDir(&obj, dir.x(), dir.y(), dir.z()); + GXInitLightAttn(&obj, 1.f, 0.f, 0.f, info.GetAttenuationConstant(), info.GetAttenuationLinear(), + info.GetAttenuationQuadratic()); + GXInitLightSpot(&obj, info.GetSpotCutoff(), GX_SP_COS2); + } else if (type == ELightType::Custom) { + pos = g_CameraMatrix * pos; + GXInitLightPos(&obj, pos.x(), pos.y(), pos.z()); + dir = g_CameraMatrix.buildMatrix3f() * dir; + GXInitLightDir(&obj, dir.x(), dir.y(), dir.z()); + GXInitLightAttn(&obj, info.GetAngleAttenuationConstant(), info.GetAngleAttenuationLinear(), + info.GetAngleAttenuationQuadratic(), info.GetAttenuationConstant(), info.GetAttenuationLinear(), + info.GetAttenuationQuadratic()); + } else if (type == ELightType::LocalAmbient || type == ELightType::Point) { + pos = g_CameraMatrix * pos; + GXInitLightPos(&obj, pos.x(), pos.y(), pos.z()); + GXInitLightAttn(&obj, 1.f, 0.f, 0.f, info.GetAttenuationConstant(), info.GetAttenuationLinear(), + info.GetAttenuationQuadratic()); + } + + g_LightTypes[light] = type; + zeus::CColor col(info.GetColor().r(), info.GetColor().g(), info.GetColor().b()); + GXInitLightColor(&obj, to_gx_color(col)); + GXLoadLightObjImm(&obj, lightId); } void CGraphics::EnableLight(ERglLight light) { - ERglLightBits lightBit = ERglLightBits(1 << int(light)); - if ((lightBit & g_LightActive) == ERglLightBits::None) { - g_LightActive |= lightBit; - ++g_NumLightsActive; - // TODO: turn light on for real + CGX::SetNumChans(1); + if (!g_LightActive.test(light)) { + g_LightActive.set(light); + CGX::SetChanCtrl(CGX::EChannelId::Channel0, g_LightActive); } - g_LightsWereOn = g_LightActive; } -void CGraphics::SetLightState(ERglLightBits lightState) { - // TODO: set state for real +void CGraphics::SetLightState(GX::LightMask lightState) { g_LightActive = lightState; - g_NumLightsActive = zeus::PopCount(lightState); + const bool hasLights = lightState.any(); + CGX::SetChanCtrl(CGX::EChannelId::Channel0, hasLights, GX_SRC_REG, + sStreamFlags & 2 /* fHasColor */ ? GX_SRC_VTX : GX_SRC_REG, lightState, + hasLights ? GX_DF_CLAMP : GX_DF_NONE, hasLights ? GX_AF_SPOT : GX_AF_NONE); } void CGraphics::SetAmbientColor(const zeus::CColor& col) { - // TODO: set for real + CGX::SetChanAmbColor(CGX::EChannelId::Channel0, col); + CGX::SetChanAmbColor(CGX::EChannelId::Channel1, col); } void CGraphics::SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) { - g_Fog.m_mode = mode > ERglFogMode::PerspRevExp2 ? ERglFogMode(int(mode) - 8) : mode; - g_Fog.m_color = color; - if (CGraphics::g_Proj.x18_far == CGraphics::g_Proj.x14_near || endz == startz) { - g_Fog.m_A = 0.f; - g_Fog.m_B = 0.5f; - g_Fog.m_C = 0.f; - } else { - float depthrange = CGraphics::g_Proj.x18_far - CGraphics::g_Proj.x14_near; - float fogrange = endz - startz; - g_Fog.m_A = (CGraphics::g_Proj.x18_far * CGraphics::g_Proj.x14_near) / (depthrange * fogrange); - g_Fog.m_B = CGraphics::g_Proj.x18_far / depthrange; - g_Fog.m_C = startz / fogrange; - } + CGX::SetFog(GXFogType(mode), startz, endz, g_Proj.x14_near, g_Proj.x18_far, to_gx_color(color)); } -void CGraphics::SetDepthWriteMode(bool test, ERglEnum comp, bool write) {} +void CGraphics::SetDepthWriteMode(bool compare_enable, ERglEnum comp, bool update_enable) { + g_depthFunc = comp; + CGX::SetZMode(compare_enable, GXCompare(comp), update_enable); +} -void CGraphics::SetBlendMode(ERglBlendMode, ERglBlendFactor, ERglBlendFactor, ERglLogicOp) {} +void CGraphics::SetBlendMode(ERglBlendMode mode, ERglBlendFactor src, ERglBlendFactor dst, ERglLogicOp op) { + CGX::SetBlendMode(GXBlendMode(mode), GXBlendFactor(src), GXBlendFactor(dst), GXLogicOp(op)); +} -void CGraphics::SetCullMode(ERglCullMode) {} +void CGraphics::SetCullMode(ERglCullMode mode) { + g_cullMode = mode; + GXSetCullMode(GXCullMode(mode)); +} -void CGraphics::BeginScene() {} +void CGraphics::BeginScene() { + // ClearBackAndDepthBuffers(); +} void CGraphics::EndScene() { + CGX::SetZMode(true, GX_LEQUAL, true); + /* Spinwait until g_NumBreakpointsWaiting is 0 */ /* ++g_NumBreakpointsWaiting; */ /* GXCopyDisp to g_CurrenFrameBuf with clear enabled */ @@ -123,18 +181,70 @@ void CGraphics::EndScene() { g_InterruptLastFrameUsedAbove ^= 1; g_LastFrameUsedAbove = g_InterruptLastFrameUsedAbove; - /* Flush text instance buffers just before GPU command list submission */ - CTextSupportShader::UpdateBuffers(); - - /* Same with line renderer */ - CLineRenderer::UpdateBuffers(); - ++g_FrameCounter; UpdateFPSCounter(); } -void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1) {} +void CGraphics::Render2D(CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col) { + const auto oldProj = g_Proj; + const auto oldCull = g_cullMode; + const auto oldLights = g_LightActive; + SetOrtho(-g_Viewport.x10_halfWidth, g_Viewport.x10_halfWidth, g_Viewport.x14_halfHeight, -g_Viewport.x14_halfHeight, + -1.f, -10.f); + GXLoadPosMtxImm(&zeus::skIdentityMatrix4f, GX_PNMTX0); + DisableAllLights(); + SetCullMode(ERglCullMode::None); + tex.Load(GX_TEXMAP0, EClampMode::Repeat); + + // float hPad, vPad; + // if (CGraphics::GetViewportAspect() >= 1.78f) { + // hPad = 1.78f / CGraphics::GetViewportAspect(); + // vPad = 1.78f / 1.33f; + // } else { + // hPad = 1.f; + // vPad = CGraphics::GetViewportAspect() / 1.33f; + // } + // TODO make this right + float scaledX = static_cast(x) / 640.f * static_cast(g_Viewport.x8_width); + float scaledY = static_cast(y) / 448.f * static_cast(g_Viewport.xc_height); + float scaledW = static_cast(w) / 640.f * static_cast(g_Viewport.x8_width); + float scaledH = static_cast(h) / 448.f * static_cast(g_Viewport.xc_height); + + float x1 = scaledX - g_Viewport.x10_halfWidth; + float y1 = scaledY - g_Viewport.x14_halfHeight; + float x2 = x1 + scaledW; + float y2 = y1 + scaledH; + StreamBegin(GX_TRIANGLESTRIP); + StreamColor(col); + StreamTexcoord(0.f, 0.f); + StreamVertex(x1, y1, 1.f); + StreamTexcoord(1.f, 0.f); + StreamVertex(x2, y1, 1.f); + StreamTexcoord(0.f, 1.f); + StreamVertex(x1, y2, 1.f); + StreamTexcoord(1.f, 1.f); + StreamVertex(x2, y2, 1.f); + StreamEnd(); + + SetLightState(g_LightActive); + g_Proj = oldProj; + FlushProjection(); + SetModelMatrix({}); + SetCullMode(oldCull); +} + +bool CGraphics::BeginRender2D(const CTexture& tex) { return false; } + +void CGraphics::DoRender2D(const CTexture& tex, s32 x, s32 y, s32 w1, s32 w2, s32 w3, s32 w4, s32 w5, + const zeus::CColor& col) {} + +void CGraphics::EndRender2D(bool v) {} + +void CGraphics::SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1) { + CGX::SetAlphaCompare(static_cast(comp0), ref0, static_cast(op), static_cast(comp1), + ref1); +} void CGraphics::SetViewPointMatrix(const zeus::CTransform& xf) { g_ViewMatrix = xf; @@ -151,11 +261,12 @@ void CGraphics::SetViewMatrix() { else g_GXModelView = g_CameraMatrix * g_GXModelMatrix; /* Load position matrix */ + GXLoadPosMtxImm(&g_GXModelView, GX_PNMTX0); /* Inverse-transpose */ g_GXModelViewInvXpose = g_GXModelView.inverse(); - g_GXModelViewInvXpose.origin.zeroOut(); g_GXModelViewInvXpose.basis.transpose(); /* Load normal matrix */ + GXLoadNrmMtxImm(&g_GXModelViewInvXpose, GX_PNMTX0); } void CGraphics::SetModelMatrix(const zeus::CTransform& xf) { @@ -164,13 +275,7 @@ void CGraphics::SetModelMatrix(const zeus::CTransform& xf) { SetViewMatrix(); } -constexpr zeus::CMatrix4f PlusOneZ(1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 0.f, 0.f, 0.f, 0.f, 1.f, 1.f, 0.f, 0.f, 0.f, 1.f); - -constexpr zeus::CMatrix4f VulkanCorrect(1.f, 0.f, 0.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.5f, 0.5f + FLT_EPSILON, - 0.f, 0.f, 0.f, 1.f); - -zeus::CMatrix4f CGraphics::CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar, - bool forRenderer) { +zeus::CMatrix4f CGraphics::CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar) { CProjectionState st; float tfov = std::tan(zeus::degToRad(fovy * 0.5f)); st.x14_near = znear; @@ -186,33 +291,17 @@ zeus::CMatrix4f CGraphics::CalculatePerspectiveMatrix(float fovy, float aspect, float tpb = st.xc_top + st.x10_bottom; float fpn = st.x18_far + st.x14_near; float fmn = st.x18_far - st.x14_near; - - if (!forRenderer) { - return zeus::CMatrix4f(2.f * st.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * st.x14_near / tmb, tpb / tmb, 0.f, - 0.f, 0.f, -fpn / fmn, -2.f * st.x18_far * st.x14_near / fmn, 0.f, 0.f, -1.f, 0.f); - } - - switch (g_BooPlatform) { - case boo::IGraphicsDataFactory::Platform::OpenGL: - default: { - return zeus::CMatrix4f(2.f * st.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * st.x14_near / tmb, tpb / tmb, 0.f, - 0.f, 0.f, -fpn / fmn, -2.f * st.x18_far * st.x14_near / fmn, 0.f, 0.f, -1.f, 0.f); - } - case boo::IGraphicsDataFactory::Platform::D3D11: - case boo::IGraphicsDataFactory::Platform::Metal: { - zeus::CMatrix4f mat2(2.f * st.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * st.x14_near / tmb, tpb / tmb, 0.f, - 0.f, 0.f, st.x18_far / fmn, st.x14_near * st.x18_far / fmn, 0.f, 0.f, -1.f, 0.f); - return PlusOneZ * mat2; - } - case boo::IGraphicsDataFactory::Platform::Vulkan: { - zeus::CMatrix4f mat2(2.f * st.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * st.x14_near / tmb, tpb / tmb, 0.f, - 0.f, 0.f, -fpn / fmn, -2.f * st.x18_far * st.x14_near / fmn, 0.f, 0.f, -1.f, 0.f); - return VulkanCorrect * mat2; - } - } + // clang-format off + return { + 2.f * st.x14_near / rml, 0.f, rpl / rml, 0.f, + 0.f, 2.f * st.x14_near / tmb, tpb / tmb, 0.f, + 0.f, 0.f, -fpn / fmn, -2.f * st.x18_far * st.x14_near / fmn, + 0.f, 0.f, -1.f, 0.f, + }; + // clang-format on } -zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix(bool forRenderer) { +zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix() { if (g_Proj.x0_persp) { float rml = g_Proj.x8_right - g_Proj.x4_left; float rpl = g_Proj.x8_right + g_Proj.x4_left; @@ -220,65 +309,28 @@ zeus::CMatrix4f CGraphics::GetPerspectiveProjectionMatrix(bool forRenderer) { float tpb = g_Proj.xc_top + g_Proj.x10_bottom; float fpn = g_Proj.x18_far + g_Proj.x14_near; float fmn = g_Proj.x18_far - g_Proj.x14_near; - - if (!forRenderer) { - return zeus::CMatrix4f(2.f * g_Proj.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * g_Proj.x14_near / tmb, - tpb / tmb, 0.f, 0.f, 0.f, -fpn / fmn, -2.f * g_Proj.x18_far * g_Proj.x14_near / fmn, 0.f, - 0.f, -1.f, 0.f); - } - - switch (g_BooPlatform) { - case boo::IGraphicsDataFactory::Platform::OpenGL: - default: { - return zeus::CMatrix4f(2.f * g_Proj.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * g_Proj.x14_near / tmb, - tpb / tmb, 0.f, 0.f, 0.f, -fpn / fmn, -2.f * g_Proj.x18_far * g_Proj.x14_near / fmn, 0.f, - 0.f, -1.f, 0.f); - } - case boo::IGraphicsDataFactory::Platform::D3D11: - case boo::IGraphicsDataFactory::Platform::Metal: { - zeus::CMatrix4f mat2(2.f * g_Proj.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * g_Proj.x14_near / tmb, - tpb / tmb, 0.f, 0.f, 0.f, g_Proj.x18_far / fmn, g_Proj.x14_near * g_Proj.x18_far / fmn, 0.f, - 0.f, -1.f, 0.f); - return PlusOneZ * mat2; - } - case boo::IGraphicsDataFactory::Platform::Vulkan: { - zeus::CMatrix4f mat2(2.f * g_Proj.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, 2.f * g_Proj.x14_near / tmb, - tpb / tmb, 0.f, 0.f, 0.f, -fpn / fmn, -2.f * g_Proj.x18_far * g_Proj.x14_near / fmn, 0.f, - 0.f, -1.f, 0.f); - return VulkanCorrect * mat2; - } - } + // clang-format off + return { + 2.f * g_Proj.x14_near / rml, 0.f, rpl / rml, 0.f, 0.f, + 2.f * g_Proj.x14_near / tmb, tpb / tmb, 0.f, + 0.f, 0.f, -g_Proj.x14_near / fmn, -(g_Proj.x18_far * g_Proj.x14_near) / fmn, + 0.f, 0.f, -1.f, 0.f, + }; + // clang-format on } else { float rml = g_Proj.x8_right - g_Proj.x4_left; float rpl = g_Proj.x8_right + g_Proj.x4_left; float tmb = g_Proj.xc_top - g_Proj.x10_bottom; float tpb = g_Proj.xc_top + g_Proj.x10_bottom; - float fpn = g_Proj.x18_far + g_Proj.x14_near; float fmn = g_Proj.x18_far - g_Proj.x14_near; - - if (!forRenderer) { - return zeus::CMatrix4f(2.f / rml, 0.f, 0.f, -rpl / rml, 0.f, 2.f / tmb, 0.f, -tpb / tmb, 0.f, 0.f, -2.f / fmn, - -fpn / fmn, 0.f, 0.f, 0.f, 1.f); - } - - switch (g_BooPlatform) { - case boo::IGraphicsDataFactory::Platform::OpenGL: - default: { - return zeus::CMatrix4f(2.f / rml, 0.f, 0.f, -rpl / rml, 0.f, 2.f / tmb, 0.f, -tpb / tmb, 0.f, 0.f, -2.f / fmn, - -fpn / fmn, 0.f, 0.f, 0.f, 1.f); - } - case boo::IGraphicsDataFactory::Platform::D3D11: - case boo::IGraphicsDataFactory::Platform::Metal: { - zeus::CMatrix4f mat2(2.f / rml, 0.f, 0.f, -rpl / rml, 0.f, 2.f / tmb, 0.f, -tpb / tmb, 0.f, 0.f, 1.f / fmn, - g_Proj.x14_near / fmn, 0.f, 0.f, 0.f, 1.f); - return PlusOneZ * mat2; - } - case boo::IGraphicsDataFactory::Platform::Vulkan: { - zeus::CMatrix4f mat2(2.f / rml, 0.f, 0.f, -rpl / rml, 0.f, 2.f / tmb, 0.f, -tpb / tmb, 0.f, 0.f, -2.f / fmn, - -fpn / fmn, 0.f, 0.f, 0.f, 1.f); - return VulkanCorrect * mat2; - } - } + // clang-format off + return { + 2.f / rml, 0.f, 0.f, -rpl / rml, + 0.f, 2.f / tmb, 0.f, -tpb / tmb, + 0.f, 0.f, -1.f / fmn, -g_Proj.x18_far / fmn, + 0.f, 0.f, 0.f, 1.f + }; + // clang-format on } } @@ -317,15 +369,18 @@ void CGraphics::SetOrtho(float left, float right, float top, float bottom, float } void CGraphics::FlushProjection() { + const auto mtx = GetPerspectiveProjectionMatrix(); if (g_Proj.x0_persp) { // Convert and load persp + GXSetProjection(&mtx, GX_PERSPECTIVE); } else { // Convert and load ortho + GXSetProjection(&mtx, GX_ORTHOGRAPHIC); } } zeus::CVector2i CGraphics::ProjectPoint(const zeus::CVector3f& point) { - zeus::CVector3f projPt = GetPerspectiveProjectionMatrix(false).multiplyOneOverW(point); + zeus::CVector3f projPt = GetPerspectiveProjectionMatrix().multiplyOneOverW(point); return {int(projPt.x() * g_Viewport.x10_halfWidth) + int(g_Viewport.x10_halfWidth), int(g_Viewport.xc_height) - (int(projPt.y() * g_Viewport.x14_halfHeight) + int(g_Viewport.x14_halfHeight))}; } @@ -390,16 +445,6 @@ SClipScreenRect CGraphics::ClipScreenRectFromVS(const zeus::CVector3f& p1, const 1.f - minY2 / float(g_Viewport.xc_height)}; } -zeus::CVector3f CGraphics::ProjectModelPointToViewportSpace(const zeus::CVector3f& point) { - zeus::CVector3f pt = g_GXModelView * point; - return GetPerspectiveProjectionMatrix(true).multiplyOneOverW(pt); -} - -zeus::CVector3f CGraphics::ProjectModelPointToViewportSpace(const zeus::CVector3f& point, float& wOut) { - zeus::CVector3f pt = g_GXModelView * point; - return GetPerspectiveProjectionMatrix(true).multiplyOneOverW(pt, wOut); -} - void CGraphics::SetViewportResolution(const zeus::CVector2i& res) { g_Viewport.x8_width = res.x; g_Viewport.xc_height = res.y; @@ -413,26 +458,27 @@ void CGraphics::SetViewportResolution(const zeus::CVector2i& res) { g_GuiSys->OnViewportResize(); } -static boo::SWindowRect CachedVP; +static zeus::CRectangle CachedVP; zeus::CVector2f CGraphics::g_CachedDepthRange = {0.f, 1.f}; void CGraphics::SetViewport(int leftOff, int bottomOff, int width, int height) { - CachedVP.location[0] = leftOff; - CachedVP.location[1] = bottomOff; + CachedVP.position[0] = leftOff; + CachedVP.position[1] = bottomOff; CachedVP.size[0] = width; CachedVP.size[1] = height; - g_BooMainCommandQueue->setViewport(CachedVP, g_CachedDepthRange[0], g_CachedDepthRange[1]); + GXSetViewport(CachedVP.position[0], CachedVP.position[1], CachedVP.size[0], CachedVP.size[1], g_CachedDepthRange[0], + g_CachedDepthRange[1]); } void CGraphics::SetScissor(int leftOff, int bottomOff, int width, int height) { - boo::SWindowRect rect(leftOff, bottomOff, width, height); - g_BooMainCommandQueue->setScissor(rect); + GXSetScissor(leftOff, bottomOff, width, height); } void CGraphics::SetDepthRange(float znear, float zfar) { g_CachedDepthRange[0] = znear; g_CachedDepthRange[1] = zfar; - g_BooMainCommandQueue->setViewport(CachedVP, g_CachedDepthRange[0], g_CachedDepthRange[1]); + GXSetViewport(CachedVP.position[0], CachedVP.position[1], CachedVP.size[0], CachedVP.size[1], g_CachedDepthRange[0], + g_CachedDepthRange[1]); } CTimeProvider* CGraphics::g_ExternalTimeProvider = nullptr; @@ -463,64 +509,267 @@ void CGraphics::UpdateFPSCounter() { } } -boo::IGraphicsDataFactory::Platform CGraphics::g_BooPlatform = boo::IGraphicsDataFactory::Platform::Null; -boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr; -boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr; -boo::ObjToken CGraphics::g_SpareTexture; -const char* CGraphics::g_BooPlatformName = nullptr; +static bool g_UseVideoFilter = false; +void CGraphics::SetUseVideoFilter(bool filter) { + g_UseVideoFilter = filter; + // GXSetCopyFilter(CGraphics::mRenderModeObj.aa, CGraphics::mRenderModeObj.sample_pattern, filter, + // CGraphics::mRenderModeObj.vfilter); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a564c({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, - GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, - GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}); +void CGraphics::SetClearColor(const zeus::CColor& color) { + g_ClearColor = color; + GXSetCopyClear(to_gx_color(color), g_ClearDepthValue); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5698({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC, - GX::TevColorArg::CC_C0, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA, - GX::TevAlphaArg::CA_A0, GX::TevAlphaArg::CA_ZERO}); +void CGraphics::SetCopyClear(const zeus::CColor& color, float depth) { + g_ClearColor = color; + g_ClearDepthValue = depth; // 1.6777215E7 * depth; Metroid Prime needed this to convert float [0,1] depth into 24 bit + // range, we no longer have this requirement + GXSetCopyClear(to_gx_color(g_ClearColor), g_ClearDepthValue); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5e70({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, - GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_C0}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, - GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_A0}); +void CGraphics::SetIsBeginSceneClearFb(bool clear) { g_IsBeginSceneClearFb = clear; } -const CTevCombiners::CTevPass CGraphics::sTevPass805a5ebc({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC, - GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA, - GX::TevAlphaArg::CA_TEXA, GX::TevAlphaArg::CA_ZERO}); +void CGraphics::SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass) { + CTevCombiners::SetupPass(stage, pass); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5f08({GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_TEXC, - GX::TevColorArg::CC_TEXA, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, - GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}); +void CGraphics::StreamBegin(GXPrimitive primitive) { + // Originally ResetVertexDataStream(true); + sQueuedVertices.clear(); + sQueuedVertices.emplace_back(sQueuedColor); + sVerticesCount = 0; + // End + sStreamFlags = 2; + sStreamPrimitive = primitive; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5f54({GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ONE, - GX::TevColorArg::CC_TEXC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA, - GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}); +void CGraphics::StreamNormal(const zeus::CVector3f& nrm) { + sQueuedVertices.back().normal = nrm; + sStreamFlags |= 1; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5fa0({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, - GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_TEXC}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, - GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA}); +void CGraphics::StreamColor(const zeus::CColor& color) { + if (sStreamFlags) { + sQueuedVertices.back().color = color; + } else { + sQueuedColor = color; + } + sStreamFlags |= 2; +} -const CTevCombiners::CTevPass CGraphics::sTevPass804bfcc0({GX::TevColorArg::CC_C0, GX::TevColorArg::CC_TEXC, - GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, - GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_RASA}); +void CGraphics::StreamTexcoord(const zeus::CVector2f& uv) { + sQueuedVertices.back().texCoord = uv; + sStreamFlags |= 4; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a5fec({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_ZERO, - GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_RASC}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_TEXA, - GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}); +void CGraphics::StreamVertex(const zeus::CVector3f& pos) { + sQueuedVertices.back().vertex = pos; + UpdateVertexDataStream(); +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a6038({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_TEXC, - GX::TevColorArg::CC_RASC, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_KONST, - GX::TevAlphaArg::CA_RASA, GX::TevAlphaArg::CA_ZERO}); +void CGraphics::StreamEnd() { + if (sVerticesCount != 0) { + FlushStream(); + } + sStreamFlags = {}; +} -const CTevCombiners::CTevPass CGraphics::sTevPass805a6084({GX::TevColorArg::CC_ZERO, GX::TevColorArg::CC_CPREV, - GX::TevColorArg::CC_APREV, GX::TevColorArg::CC_ZERO}, - {GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_ZERO, - GX::TevAlphaArg::CA_ZERO, GX::TevAlphaArg::CA_APREV}); +void CGraphics::UpdateVertexDataStream() { + ++sVerticesCount; + if (sVerticesCount == 240) { + FlushStream(); + ResetVertexDataStream(false); + } else { + sQueuedVertices.emplace_back(sQueuedVertices.back()); + } +} + +void CGraphics::FlushStream() { + std::array vtxDescList{}; + size_t idx = 0; + vtxDescList[idx++] = {GX_VA_POS, GX_DIRECT}; + if (sStreamFlags & 1) { + vtxDescList[idx++] = {GX_VA_NRM, GX_DIRECT}; + } + if (sStreamFlags & 2) { + vtxDescList[idx++] = {GX_VA_CLR0, GX_DIRECT}; + } + if (sStreamFlags & 4) { + vtxDescList[idx++] = {GX_VA_TEX0, GX_DIRECT}; + } + vtxDescList[idx] = {GX_VA_NULL, GX_NONE}; + CGX::SetVtxDescv(vtxDescList.data()); + SetTevStates(sStreamFlags); + FullRender(); +} + +void CGraphics::FullRender() { + CGX::Begin(sStreamPrimitive, GX_VTXFMT0, sVerticesCount); + for (size_t i = 0; i < sVerticesCount; ++i) { + const auto& item = sQueuedVertices[i]; + GXPosition3f32(item.vertex); + if (sStreamFlags & 1) { + GXNormal3f32(item.normal); + } + if (sStreamFlags & 2) { + GXColor4f32(item.color); + } + if (sStreamFlags & 4) { + GXTexCoord2f32(item.texCoord); + } + } + CGX::End(); +} + +void CGraphics::ResetVertexDataStream(bool end) { + if (end) { + sQueuedVertices.clear(); + } else { + const auto lastVertex = sQueuedVertices.back(); + sQueuedVertices.clear(); + sQueuedVertices.emplace_back(lastVertex); + } + sVerticesCount = 0; + if (!end) { + // TODO something with triangle fans + } +} + +void CGraphics::DrawPrimitive(GXPrimitive primitive, const zeus::CVector3f* pos, const zeus::CVector3f& normal, + const zeus::CColor& col, s32 numVerts) { + StreamBegin(primitive); + StreamColor(col); + StreamNormal(normal); + for (u32 i = 0; i < numVerts; ++i) { + StreamVertex(pos[i]); + } + StreamEnd(); +} + +void CGraphics::SetTevStates(u32 flags) noexcept { + if (flags & 4 /* fHasTexture */) { + CGX::SetNumTexGens(1); // sTextureUsed & 3? + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0); + } else { + CGX::SetNumTexGens(0); + CGX::SetNumTevStages(1); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0); + } + CGX::SetNumChans(1); + CGX::SetNumIndStages(0); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY, false, GX_PTIDENTITY); + const bool hasLights = g_LightActive.any(); + CGX::SetChanCtrl(CGX::EChannelId::Channel0, hasLights, GX_SRC_REG, + flags & 2 /* fHasColor */ ? GX_SRC_VTX : GX_SRC_REG, g_LightActive, + hasLights ? GX_DF_CLAMP : GX_DF_NONE, hasLights ? GX_AF_SPOT : GX_AF_NONE); + CGX::FlushState(); // normally would be handled in FullRender TODO +} + +void CGraphics::Startup() { + // Setup GXFifo + CGX::ResetGXStates(); + InitGraphicsVariables(); + // ConfigureFrameBuffer(...); + InitGraphicsDefaults(); + // GXInitTexCacheRegion + // GXSetTexRegionCallback +} + +void CGraphics::InitGraphicsVariables() { + g_LightTypes.fill(ELightType::Directional); + g_LightActive = {}; + SetDepthWriteMode(false, g_depthFunc, false); + SetCullMode(ERglCullMode::None); + SetAmbientColor(zeus::CColor{0.2f, 1.f}); + g_IsGXModelMatrixIdentity = false; + // SetIdentityViewPointMatrix(); + // SetIdentityModelMatrix(); + SetViewport(0, 0, g_Viewport.x8_width, g_Viewport.xc_height); + SetPerspective(60.f, g_Viewport.x8_width / g_Viewport.xc_height, g_Proj.x14_near, g_Proj.x18_far); + SetCopyClear(g_ClearColor, 1.f); + CGX::SetChanMatColor(CGX::EChannelId::Channel0, zeus::skWhite); + // g_RenderState.ResetFlushAll(); +} + +void CGraphics::InitGraphicsDefaults() { + SetDepthRange(0.f, 1.f); + g_IsGXModelMatrixIdentity = false; + SetModelMatrix(g_GXModelMatrix); + SetViewPointMatrix(g_GXModelView); + SetDepthWriteMode(false, g_depthFunc, false); + SetCullMode(g_cullMode); + SetViewport(g_Viewport.x0_left, g_Viewport.x4_top, g_Viewport.x8_width, g_Viewport.xc_height); + FlushProjection(); + CTevCombiners::Init(); + DisableAllLights(); + SetDefaultVtxAttrFmt(); +} + +void CGraphics::SetDefaultVtxAttrFmt() { + // Unneeded, all attributes are expected to be full floats + // Left here for reference + + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 14); + GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_NRM, GX_NRM_XYZ, GX_S16, 14); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT2, GX_VA_TEX0, GX_TEX_ST, GX_U16, 15); + for (GXAttr attr = GX_VA_TEX1; attr <= GX_VA_TEX7; attr = GXAttr(attr + 1)) { + GXSetVtxAttrFmt(GX_VTXFMT0, attr, GX_TEX_ST, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT1, attr, GX_TEX_ST, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT2, attr, GX_TEX_ST, GX_F32, 0); + } +} + +void CGraphics::ResetGfxStates() noexcept { + // sRenderState.x0_ = 0; +} + +void CGraphics::LoadDolphinSpareTexture(int width, int height, GXTexFmt format, void* data, GXTexMapID id) { + void* ptr = static_cast(sSpareTextureData); + if (data != nullptr) { + ptr = data; + } + GXTexObj obj; + GXInitTexObj(&obj, ptr, width, height, format, GX_CLAMP, GX_CLAMP, false); + GXInitTexObjLOD(&obj, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1); + GXLoadTexObj(&obj, id); + // CTexture::InvalidateTexmap(id); + if (id == GX_TEXMAP7) { + // GXInvalidateTexRegion(...); + } +#ifdef AURORA + GXDestroyTexObj(&obj); +#endif +} + +void CGraphics::LoadDolphinSpareTexture(int width, int height, GXCITexFmt format, GXTlut tlut, void* data, + GXTexMapID id) { + void* ptr = static_cast(sSpareTextureData); + if (data != nullptr) { + ptr = data; + } + GXTexObj obj; + GXInitTexObjCI(&obj, ptr, width, height, format, GX_CLAMP, GX_CLAMP, false, tlut); + GXInitTexObjLOD(&obj, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1); + GXLoadTexObj(&obj, id); + // CTexture::InvalidateTexmap(id); + if (id == GX_TEXMAP7) { + // GXInvalidateTexRegion(...); + } +#ifdef AURORA + GXDestroyTexObj(&obj); +#endif +} } // namespace metaforce diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index bd09bd4ca..433a1f1ef 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -1,110 +1,132 @@ #pragma once -#include -#include -#include -#include "optick.h" - +#include "Runtime/ConsoleVariables/CVar.hpp" +#include "Runtime/Graphics/CLight.hpp" +#include "Runtime/Graphics/CTevCombiners.hpp" +#include "Runtime/Graphics/GX.hpp" #include "Runtime/RetroTypes.hpp" -#include "DataSpec/DNACommon/GX.hpp" - -#include -#include - -#include -#include +#include +#include +#include #include #include -#include #include +#include + +#include +#include using frame_clock = std::chrono::high_resolution_clock; namespace metaforce { -extern hecl::CVar* g_disableLighting; -class CLight; +class CTexture; +extern CVar* g_disableLighting; class CTimeProvider; -enum class ERglLight : u8 { Zero = 0, One, Two, Three, Four, Five, Six, Seven }; - -enum class ERglLightBits : u8 { - None = 0, - Zero = 1, - One = 1 << 1, - Two = 1 << 2, - Three = 1 << 3, - Four = 1 << 4, - Five = 1 << 5, - Six = 1 << 6, - Seven = 1 << 7 -}; -ENABLE_BITWISE_ENUM(ERglLightBits) - -enum class ERglEnum { Never = 0, Less = 1, Equal = 2, LEqual = 3, Greater = 4, NEqual = 5, GEqual = 6, Always = 7 }; - -enum class ERglBlendMode { None = 0, Blend = 1, Logic = 2, Subtract = 3 }; - -enum class ERglBlendFactor { - Zero = 0, - One = 1, - SrcColor = 2, - InvSrcColor = 3, - SrcAlpha = 4, - InvSrcAlpha = 5, - DstAlpha = 6, - InvDstAlpha = 7 +enum class ERglCullMode : std::underlying_type_t { + None = GX_CULL_NONE, + Front = GX_CULL_FRONT, + Back = GX_CULL_BACK, + All = GX_CULL_ALL, }; -enum class ERglLogicOp { - Clear = 0, - And = 1, - RevAnd = 2, - Copy = 3, - InvAnd = 4, - NoOp = 5, - Xor = 6, - Or = 7, - Nor = 8, - Equiv = 9, - Inv = 10, - RevOr = 11, - InvCopy = 12, - InvOr = 13, - NAnd = 14, - Set = 15 +enum class ERglBlendMode : std::underlying_type_t { + None = GX_BM_NONE, + Blend = GX_BM_BLEND, + Logic = GX_BM_LOGIC, + Subtract = GX_BM_SUBTRACT, + Max = GX_MAX_BLENDMODE, }; -enum class ERglCullMode { None = 0, Front = 1, Back = 2, All = 3 }; - -enum class ERglAlphaFunc { - Never = 0, - Less = 1, - Equal = 2, - LEqual = 3, - Greater = 4, - NEqual = 5, - GEqual = 6, - Always = 7 +enum class ERglBlendFactor : std::underlying_type_t { + Zero = GX_BL_ZERO, + One = GX_BL_ONE, + SrcColor = GX_BL_SRCCLR, + InvSrcColor = GX_BL_INVSRCCLR, + SrcAlpha = GX_BL_SRCALPHA, + InvSrcAlpha = GX_BL_INVSRCALPHA, + DstAlpha = GX_BL_DSTALPHA, + InvDstAlpha = GX_BL_INVDSTALPHA, + DstColor = GX_BL_DSTCLR, + InvDstColor = GX_BL_INVDSTCLR, }; -enum class ERglAlphaOp { And = 0, Or = 1, Xor = 2, XNor = 3 }; +enum class ERglLogicOp : std::underlying_type_t { + Clear = GX_LO_CLEAR, + And = GX_LO_AND, + RevAnd = GX_LO_REVAND, + Copy = GX_LO_COPY, + InvAnd = GX_LO_INVAND, + NoOp = GX_LO_NOOP, + Xor = GX_LO_XOR, + Or = GX_LO_OR, + Nor = GX_LO_NOR, + Equiv = GX_LO_EQUIV, + Inv = GX_LO_INV, + RevOr = GX_LO_REVOR, + InvCopy = GX_LO_INVCOPY, + InvOr = GX_LO_INVOR, + NAnd = GX_LO_NAND, + Set = GX_LO_SET, +}; -enum class ERglFogMode : uint32_t { - None = 0x00, +enum class ERglAlphaFunc : std::underlying_type_t { + Never = GX_NEVER, + Less = GX_LESS, + Equal = GX_EQUAL, + LEqual = GX_LEQUAL, + Greater = GX_GREATER, + NEqual = GX_NEQUAL, + GEqual = GX_GEQUAL, + Always = GX_ALWAYS, +}; - PerspLin = 0x02, - PerspExp = 0x04, - PerspExp2 = 0x05, - PerspRevExp = 0x06, - PerspRevExp2 = 0x07, +enum class ERglAlphaOp : std::underlying_type_t { + And = GX_AOP_AND, + Or = GX_AOP_OR, + Xor = GX_AOP_XOR, + XNor = GX_AOP_XNOR, + Max = GX_MAX_ALPHAOP, +}; - OrthoLin = 0x0A, - OrthoExp = 0x0C, - OrthoExp2 = 0x0D, - OrthoRevExp = 0x0E, - OrthoRevExp2 = 0x0F +enum class ERglEnum : std::underlying_type_t { + Never = GX_NEVER, + Less = GX_LESS, + Equal = GX_EQUAL, + LEqual = GX_LEQUAL, + Greater = GX_GREATER, + NEqual = GX_NEQUAL, + GEqual = GX_GEQUAL, + Always = GX_ALWAYS, +}; + +using ERglLight = u8; + +enum class ERglTexOffset : std::underlying_type_t { + Zero = GX_TO_ZERO, + Sixteenth = GX_TO_SIXTEENTH, + Eighth = GX_TO_EIGHTH, + Fourth = GX_TO_FOURTH, + Half = GX_TO_HALF, + One = GX_TO_ONE, +}; + +enum class ERglFogMode : std::underlying_type_t { + None = GX_FOG_NONE, + + PerspLin = GX_FOG_PERSP_LIN, + PerspExp = GX_FOG_PERSP_EXP, + PerspExp2 = GX_FOG_ORTHO_EXP2, + PerspRevExp = GX_FOG_PERSP_REVEXP, + PerspRevExp2 = GX_FOG_PERSP_REVEXP2, + + OrthoLin = GX_FOG_ORTHO_LIN, + OrthoExp = GX_FOG_ORTHO_EXP, + OrthoExp2 = GX_FOG_ORTHO_EXP2, + OrthoRevExp = GX_FOG_ORTHO_REVEXP, + OrthoRevExp2 = GX_FOG_ORTHO_REVEXP2, }; struct SViewport { @@ -117,8 +139,6 @@ struct SViewport { float aspect; }; -extern SViewport g_Viewport; - struct SClipScreenRect { bool x0_valid = false; int x4_left = 0; @@ -145,14 +165,6 @@ struct SClipScreenRect { , x20_uvYMin(uvYMin) , x24_uvYMax(uvYMax) {} - SClipScreenRect(const boo::SWindowRect& rect) { - x4_left = rect.location[0]; - x8_top = rect.location[1]; - xc_width = rect.size[0]; - x10_height = rect.size[1]; - x14_dstWidth = rect.size[0]; - } - SClipScreenRect(const SViewport& vp) { x4_left = vp.x0_left; x8_top = vp.x4_top; @@ -161,24 +173,6 @@ struct SClipScreenRect { } }; -enum class ETexelFormat { - I4 = 0, - I8 = 1, - IA4 = 2, - IA8 = 3, - C4 = 4, - C8 = 5, - C14X2 = 6, - RGB565 = 7, - RGB5A3 = 8, - RGBA8 = 9, - CMPR = 10, - RGBA8PC = 16, - C8PC = 17, - CMPRPC = 18, - CMPRPCA = 19, -}; - #define DEPTH_FAR 1.f #define DEPTH_SKY 0.999f #define DEPTH_TARGET_MANAGER 0.12500012f @@ -190,47 +184,6 @@ enum class ETexelFormat { #define CUBEMAP_RES 256 #define CUBEMAP_MIPS 6 -static s32 sNextUniquePass = 0; -namespace CTevCombiners { -struct CTevOp { - bool x0_clamp = true; - GX::TevOp x4_op = GX::TevOp::TEV_ADD; - GX::TevBias x8_bias = GX::TevBias::TB_ZERO; - GX::TevScale xc_scale = GX::TevScale::CS_SCALE_1; - GX::TevRegID xc_regId = GX::TevRegID::TEVPREV; -}; - -struct ColorPass { - GX::TevColorArg x0_a; - GX::TevColorArg x4_b; - GX::TevColorArg x8_c; - GX::TevColorArg xc_d; -}; -struct AlphaPass { - GX::TevAlphaArg x0_a; - GX::TevAlphaArg x4_b; - GX::TevAlphaArg x8_c; - GX::TevAlphaArg xc_d; -}; - -class CTevPass { - u32 x0_id; - ColorPass x4_colorPass; - AlphaPass x14_alphaPass; - CTevOp x24_colorOp; - CTevOp x38_alphaOp; - -public: - CTevPass(const ColorPass& colPass, const AlphaPass& alphaPass, const CTevOp& colorOp = CTevOp(), - const CTevOp alphaOp = CTevOp()) - : x0_id(++sNextUniquePass) - , x4_colorPass(colPass) - , x14_alphaPass(alphaPass) - , x24_colorOp(colorOp) - , x38_alphaOp(alphaOp) {} -}; -}; // namespace CTevCombiners - class CGraphics { public: struct CProjectionState { @@ -243,26 +196,18 @@ public: float x18_far; }; - struct CFogState { - zeus::CColor m_color; - float m_A = 0.f; - float m_B = 0.5f; - float m_C = 0.f; - ERglFogMode m_mode; - }; - static CProjectionState g_Proj; static zeus::CVector2f g_CachedDepthRange; - static CFogState g_Fog; - static std::array g_ColorRegs; + // static CFogState g_Fog; + static SViewport g_Viewport; static float g_ProjAspect; - static u32 g_NumLightsActive; static u32 g_NumBreakpointsWaiting; static u32 g_FlippingState; static bool g_LastFrameUsedAbove; static bool g_InterruptLastFrameUsedAbove; - static ERglLightBits g_LightActive; - static ERglLightBits g_LightsWereOn; + static GX::LightMask g_LightActive; + static std::array g_LightObjs; + static std::array g_LightTypes; static zeus::CTransform g_GXModelView; static zeus::CTransform g_GXModelViewInvXpose; static zeus::CTransform g_GXModelMatrix; @@ -272,11 +217,21 @@ public: static zeus::CTransform g_CameraMatrix; static SClipScreenRect g_CroppedViewport; static bool g_IsGXModelMatrixIdentity; + static zeus::CColor g_ClearColor; + static float g_ClearDepthValue; // Was a 24bit value, we use a float range from [0,1] + static bool g_IsBeginSceneClearFb; + static ERglEnum g_depthFunc; + static ERglCullMode g_cullMode; + + static void Startup(); + static void InitGraphicsVariables(); + static void InitGraphicsDefaults(); + static void SetDefaultVtxAttrFmt(); static void DisableAllLights(); static void LoadLight(ERglLight light, const CLight& info); static void EnableLight(ERglLight light); - static void SetLightState(ERglLightBits lightState); + static void SetLightState(GX::LightMask lightState); static void SetAmbientColor(const zeus::CColor& col); static void SetFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color); static void SetDepthWriteMode(bool test, ERglEnum comp, bool write); @@ -284,13 +239,17 @@ public: static void SetCullMode(ERglCullMode); static void BeginScene(); static void EndScene(); + static void Render2D(CTexture& tex, u32 x, u32 y, u32 w, u32 h, const zeus::CColor& col); + static bool BeginRender2D(const CTexture& tex); + static void DoRender2D(const CTexture& tex, s32 x, s32 y, s32 w1, s32 w2, s32 w3, s32 w4, s32 w5, + const zeus::CColor& col); + static void EndRender2D(bool v); static void SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, u8 ref1); static void SetViewPointMatrix(const zeus::CTransform& xf); static void SetViewMatrix(); static void SetModelMatrix(const zeus::CTransform& xf); - static zeus::CMatrix4f CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar, - bool forRenderer); - static zeus::CMatrix4f GetPerspectiveProjectionMatrix(bool forRenderer); + static zeus::CMatrix4f CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar); + static zeus::CMatrix4f GetPerspectiveProjectionMatrix(); static const CProjectionState& GetProjectionState(); static void SetProjectionState(const CProjectionState&); static void SetPerspective(float fovy, float aspect, float znear, float zfar); @@ -299,8 +258,6 @@ public: static zeus::CVector2i ProjectPoint(const zeus::CVector3f& point); static SClipScreenRect ClipScreenRectFromMS(const zeus::CVector3f& p1, const zeus::CVector3f& p2); static SClipScreenRect ClipScreenRectFromVS(const zeus::CVector3f& p1, const zeus::CVector3f& p2); - static zeus::CVector3f ProjectModelPointToViewportSpace(const zeus::CVector3f& point); - static zeus::CVector3f ProjectModelPointToViewportSpace(const zeus::CVector3f& point, float& wOut); static void SetViewportResolution(const zeus::CVector2i& res); static void SetViewport(int leftOff, int bottomOff, int width, int height); @@ -320,95 +277,54 @@ public: static u32 GetFrameCounter() { return g_FrameCounter; } static u32 GetFPS() { return g_Framerate; } static void UpdateFPSCounter(); - - static boo::IGraphicsDataFactory::Platform g_BooPlatform; - static const char* g_BooPlatformName; - static boo::IGraphicsDataFactory* g_BooFactory; - static boo::IGraphicsCommandQueue* g_BooMainCommandQueue; - static boo::ObjToken g_SpareTexture; + static void SetUseVideoFilter(bool); + static void SetClearColor(const zeus::CColor& color); + static void SetCopyClear(const zeus::CColor& color, float depth); + static void SetIsBeginSceneClearFb(bool clear); + static u32 GetViewportLeft() { return g_Viewport.x0_left; } + static u32 GetViewportTop() { return g_Viewport.x4_top; } + static u32 GetViewportWidth() { return g_Viewport.x8_width; } + static u32 GetViewportHeight() { return g_Viewport.xc_height; } + static float GetViewportHalfWidth() { return g_Viewport.x10_halfWidth; } + static float GetViewportHalfHeight() { return g_Viewport.x14_halfHeight; } + static float GetViewportAspect() { return g_Viewport.aspect; } + static bool IsCroppedViewportValid() { return g_CroppedViewport.x0_valid; } + static int GetCroppedViewportLeft() { return g_CroppedViewport.x4_left; } + static int GetCroppedViewportTop() { return g_CroppedViewport.x8_top; } + static int GetCroppedViewportWidth() { return g_CroppedViewport.xc_width; } + static int GetCroppedViewportHeight() { return g_CroppedViewport.x10_height; } + static float GetCroppedViewportDstWidth() { return g_CroppedViewport.x14_dstWidth; } + static float GetCroppedViewportUVXMin() { return g_CroppedViewport.x18_uvXMin; } + static float GetCroppedViewportUVXMax() { return g_CroppedViewport.x1c_uvXMax; } + static float GetCroppedViewportUVYMin() { return g_CroppedViewport.x20_uvYMin; } + static float GetCroppedViewportUVYMax() { return g_CroppedViewport.x24_uvYMax; } static const std::array skCubeBasisMats; + static u8 sSpareTextureData[]; - static void InitializeBoo(boo::IGraphicsDataFactory* factory, boo::IGraphicsCommandQueue* cc, - const boo::ObjToken& spareTex) { - g_BooPlatform = factory->platform(); - g_BooPlatformName = factory->platformName(); - g_BooFactory = factory; - g_BooMainCommandQueue = cc; - g_SpareTexture = spareTex; - } + static void LoadDolphinSpareTexture(int width, int height, GXTexFmt format, void* data, GXTexMapID id); + static void LoadDolphinSpareTexture(int width, int height, GXCITexFmt format, GXTlut tlut, void* data, GXTexMapID id); - static void ShutdownBoo() { - g_BooFactory = nullptr; - g_BooMainCommandQueue = nullptr; - g_SpareTexture.reset(); - } - - static const char* PlatformName() { return g_BooPlatformName; } - - - static bool g_commitAsLazy; - static void SetCommitResourcesAsLazy(bool newStatus) { - if (newStatus != g_commitAsLazy) { - g_commitAsLazy = newStatus; - if (!newStatus && g_BooFactory) { - g_BooFactory->commitPendingTransaction(); - } - } - } - - static void CommitResources(const boo::FactoryCommitFunc& commitFunc __BooTraceArgs) { - CommitResources(commitFunc __BooTraceArgsUse, g_commitAsLazy); - } - - static void CommitResources(const boo::FactoryCommitFunc& commitFunc __BooTraceArgs, bool lazy) { - if (!g_BooFactory) { - return; - } - if (lazy) { - g_BooFactory->lazyCommitTransaction(commitFunc __BooTraceArgsUse); - } else { - g_BooFactory->commitTransaction(commitFunc __BooTraceArgsUse); - } - } - - static void SetShaderDataBinding(const boo::ObjToken& binding) { - g_BooMainCommandQueue->setShaderDataBinding(binding); - } - static void ResolveSpareTexture(const SClipScreenRect& rect, int bindIdx = 0, bool clearDepth = false) { - boo::SWindowRect wrect = {rect.x4_left, rect.x8_top, rect.xc_width, rect.x10_height}; - g_BooMainCommandQueue->resolveBindTexture(g_SpareTexture, wrect, true, bindIdx, true, false, clearDepth); - } - static void ResolveSpareDepth(const SClipScreenRect& rect, int bindIdx = 0) { - boo::SWindowRect wrect = {rect.x4_left, rect.x8_top, rect.xc_width, rect.x10_height}; - g_BooMainCommandQueue->resolveBindTexture(g_SpareTexture, wrect, true, bindIdx, false, true); - } - static void DrawInstances(size_t start, size_t count, size_t instCount, size_t startInst = 0) { - g_BooMainCommandQueue->drawInstances(start, count, instCount, startInst); - } - static void DrawArray(size_t start, size_t count) { g_BooMainCommandQueue->draw(start, count); } - static void DrawArrayIndexed(size_t start, size_t count) { g_BooMainCommandQueue->drawIndexed(start, count); } - - static const CTevCombiners::CTevPass sTevPass805a564c; - static const CTevCombiners::CTevPass sTevPass805a5698; - - static const CTevCombiners::CTevPass sTevPass805a5e70; - - static const CTevCombiners::CTevPass sTevPass805a5ebc; - - static const CTevCombiners::CTevPass sTevPass805a5f08; - - static const CTevCombiners::CTevPass sTevPass805a5f54; - - static const CTevCombiners::CTevPass sTevPass805a5fa0; - - static const CTevCombiners::CTevPass sTevPass804bfcc0; - - static const CTevCombiners::CTevPass sTevPass805a5fec; - - static const CTevCombiners::CTevPass sTevPass805a6038; - - static const CTevCombiners::CTevPass sTevPass805a6084; + static void ResetGfxStates() noexcept; + static void SetTevStates(u32 flags) noexcept; + static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass); + static void StreamBegin(GXPrimitive primitive); + static void StreamNormal(const zeus::CVector3f& nrm); + static void StreamColor(const zeus::CColor& color); + static inline void StreamColor(float r, float g, float b, float a) { StreamColor({r, g, b, a}); } + static void StreamTexcoord(const zeus::CVector2f& uv); + static inline void StreamTexcoord(float x, float y) { StreamTexcoord({x, y}); } + static void StreamVertex(const zeus::CVector3f& pos); + static inline void StreamVertex(float xyz) { StreamVertex({xyz, xyz, xyz}); } + static inline void StreamVertex(float x, float y, float z) { StreamVertex({x, y, z}); } + static void StreamEnd(); + static void UpdateVertexDataStream(); + static void ResetVertexDataStream(bool end); + static void FlushStream(); + static void FullRender(); + static void DrawPrimitive(GXPrimitive primitive, const zeus::CVector3f* pos, const zeus::CVector3f& normal, + const zeus::CColor& col, s32 numVerts); + static void SetLineWidth(float width, ERglTexOffset offs); }; template @@ -441,25 +357,17 @@ public: m_vec.emplace_back(std::forward<_Args>(args)...); } - void Draw() const { CGraphics::DrawArray(m_start, m_vec.size() - m_start); } + // void Draw() const { CGraphics::DrawArray(m_start, m_vec.size() - m_start); } }; -#ifdef BOO_GRAPHICS_DEBUG_GROUPS -class GraphicsDebugGroup { - /* Stack only */ - void* operator new(size_t); - void operator delete(void*); - void* operator new[](size_t); - void operator delete[](void*); - -public: - explicit GraphicsDebugGroup(const char* name, const zeus::CColor& color = zeus::skWhite) { - zeus::simd_floats f(color.mSimd); - CGraphics::g_BooMainCommandQueue->pushDebugGroup(name, f.array()); - } - ~GraphicsDebugGroup() { CGraphics::g_BooMainCommandQueue->popDebugGroup(); } +#ifdef AURORA_GFX_DEBUG_GROUPS +struct ScopedDebugGroup { + inline ScopedDebugGroup(const char* label) noexcept { push_debug_group(label); } + inline ~ScopedDebugGroup() noexcept { pop_debug_group(); } }; -#define SCOPED_GRAPHICS_DEBUG_GROUP(...) GraphicsDebugGroup _GfxDbg_(__VA_ARGS__); +#define SCOPED_GRAPHICS_DEBUG_GROUP(name, ...) \ + OPTICK_EVENT_DYNAMIC(name); \ + ScopedDebugGroup _GfxDbg_ { name } #else #define SCOPED_GRAPHICS_DEBUG_GROUP(name, ...) OPTICK_EVENT_DYNAMIC(name) #endif diff --git a/Runtime/Graphics/CGraphicsPalette.cpp b/Runtime/Graphics/CGraphicsPalette.cpp new file mode 100644 index 000000000..eb59bd9cc --- /dev/null +++ b/Runtime/Graphics/CGraphicsPalette.cpp @@ -0,0 +1,39 @@ +#include "Runtime/Graphics/CGraphicsPalette.hpp" +#include "Runtime/Streams/CInputStream.hpp" + +namespace metaforce { +u32 CGraphicsPalette::sCurrentFrameCount = 0; + +CGraphicsPalette::CGraphicsPalette(EPaletteFormat fmt, int count) +: x0_fmt(fmt), x8_entryCount(count), xc_entries(std::make_unique(count)) { + GXInitTlutObj(&x10_tlutObj, xc_entries.get(), static_cast(x0_fmt), x8_entryCount); +} + +CGraphicsPalette::CGraphicsPalette(CInputStream& in) : x0_fmt(EPaletteFormat(in.ReadLong())) { + u16 w = in.ReadShort(); + u16 h = in.ReadShort(); + x8_entryCount = w * h; + xc_entries = std::make_unique(x8_entryCount); + in.Get(reinterpret_cast(xc_entries.get()), x8_entryCount * sizeof(u16)); + GXInitTlutObj(&x10_tlutObj, xc_entries.get(), static_cast(x0_fmt), x8_entryCount); + // DCFlushRange(xc_entries.get(), x8_entryCount * 2); +} + +CGraphicsPalette::~CGraphicsPalette() { +#ifdef AURORA + GXDestroyTlutObj(&x10_tlutObj); +#endif +} + +void CGraphicsPalette::Load() { + GXLoadTlut(&x10_tlutObj, GX_TLUT0); + x4_frameLoaded = sCurrentFrameCount; +} + +void CGraphicsPalette::UnLock() { + // DCStoreRange(xc_lut, x8_numEntries << 1); + GXInitTlutObj(&x10_tlutObj, xc_entries.get(), static_cast(x0_fmt), x8_entryCount); + // DCFlushRange(xc_lut, x8_numEntries << 1); + x1c_locked = false; +} +} // namespace metaforce diff --git a/Runtime/Graphics/CGraphicsPalette.hpp b/Runtime/Graphics/CGraphicsPalette.hpp index 3c83d78b7..5ffe01bc4 100644 --- a/Runtime/Graphics/CGraphicsPalette.hpp +++ b/Runtime/Graphics/CGraphicsPalette.hpp @@ -1,35 +1,44 @@ #pragma once +#include "RetroTypes.hpp" +#include "GX.hpp" + #include -#include "Runtime/RetroTypes.hpp" namespace metaforce { +class CInputStream; -enum class EPaletteFormat { - IA8 = 0x0, - RGB565 = 0x1, - RGB5A3 = 0x2, +enum class EPaletteFormat : std::underlying_type_t { + IA8 = GX_TL_IA8, + RGB565 = GX_TL_RGB565, + RGB5A3 = GX_TL_RGB5A3, }; class CGraphicsPalette { + static u32 sCurrentFrameCount; friend class CTextRenderBuffer; EPaletteFormat x0_fmt; - u32 x4_; - int x8_entryCount; + u32 x4_frameLoaded{}; + u32 x8_entryCount; std::unique_ptr xc_entries; - /* x10_ GXTlutObj here */ - bool x1c_ = false; + GXTlutObj x10_tlutObj; + bool x1c_locked = false; public: - explicit CGraphicsPalette(EPaletteFormat fmt, int count) - : x0_fmt(fmt), x8_entryCount(count), xc_entries(new u16[count]) {} - explicit CGraphicsPalette(CInputStream& in) : x0_fmt(EPaletteFormat(in.readUint32Big())) { - u16 w = in.readUint16Big(); - u16 h = in.readUint16Big(); - x8_entryCount = w * h; + explicit CGraphicsPalette(EPaletteFormat fmt, int count); + explicit CGraphicsPalette(CInputStream& in); + ~CGraphicsPalette(); - /* GX Tlut init here */ + u16* Lock() { + x1c_locked = true; + return xc_entries.get(); } + void UnLock(); + void Load(); + + [[nodiscard]] const u16* GetPaletteData() const { return xc_entries.get(); } + + static void SetCurrentFrameCount(u32 frameCount) { sCurrentFrameCount = frameCount; } }; } // namespace metaforce diff --git a/Runtime/Graphics/CLight.cpp b/Runtime/Graphics/CLight.cpp index 4ebf58ca7..832ee02eb 100644 --- a/Runtime/Graphics/CLight.cpp +++ b/Runtime/Graphics/CLight.cpp @@ -8,20 +8,21 @@ constexpr zeus::CVector3f kDefaultPosition(0.f, 0.f, 0.f); constexpr zeus::CVector3f kDefaultDirection(0.f, -1.f, 0.f); float CLight::CalculateLightRadius() const { - if (FLT_EPSILON > x28_distL && FLT_EPSILON > x2c_distQ) { - return 0.f; + if (x28_distL < FLT_EPSILON && x2c_distQ < FLT_EPSILON) { + return FLT_MAX; } float intensity = GetIntensity(); - if (x2c_distQ <= FLT_EPSILON) { + float ret = 0.f; + if (x2c_distQ > FLT_EPSILON) { constexpr float mulVal = std::min(0.05882353f, 0.2f); // Yes, retro really did do this - if (x28_distL > FLT_EPSILON) { - return intensity / (mulVal * x28_distL); + if (intensity > FLT_EPSILON) { + return std::sqrt(intensity / (mulVal * x2c_distQ)); } } else { constexpr float mulVal = std::min(0.05882353f, 0.2f); // See above comment - if (intensity > FLT_EPSILON) { - return std::sqrt(intensity / (mulVal * x2c_distQ)); + if (x28_distL > FLT_EPSILON) { + return intensity / (mulVal * x28_distL); } } @@ -69,7 +70,7 @@ zeus::CColor CLight::GetNormalIndependentLightingAtPoint(const zeus::CVector3f& return x18_color; float dist = std::max((x0_pos - point).magnitude(), FLT_EPSILON); - return x18_color * (1.f / (x2c_distQ * dist * dist + x28_distL * dist + x24_distC)); + return x18_color * (1.f / (dist * (x2c_distQ * dist) + (x28_distL * dist + x24_distC))); } CLight CLight::BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& color) { @@ -77,8 +78,8 @@ CLight CLight::BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& } CLight CLight::BuildSpot(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CColor& color, - float angle) { - return CLight(ELightType::Spot, pos, dir, color, angle); + float cutoff) { + return CLight(ELightType::Spot, pos, dir, color, cutoff); } CLight CLight::BuildPoint(const zeus::CVector3f& pos, const zeus::CColor& color) { diff --git a/Runtime/Graphics/CLight.hpp b/Runtime/Graphics/CLight.hpp index 4321de1b4..7610b1c31 100644 --- a/Runtime/Graphics/CLight.hpp +++ b/Runtime/Graphics/CLight.hpp @@ -27,11 +27,11 @@ class CLight { zeus::CColor x18_color = zeus::skClear; ELightType x1c_type = ELightType::Custom; float x20_spotCutoff = 0.f; - float x24_distC = 1.f; - float x28_distL = 0.f; + float x24_distC = 0.f; + float x28_distL = 1.f; float x2c_distQ = 0.f; - float x30_angleC = 1.f; - float x34_angleL = 0.f; + float x30_angleC = 0.f; + float x34_angleL = 1.f; float x38_angleQ = 0.f; u32 x3c_priority = 0; u32 x40_lightId = 0; // Serves as unique key @@ -72,6 +72,7 @@ public: x4c_24_intensityDirty = true; x4c_25_radiusDirty = true; } + float GetSpotCutoff() const { return x20_spotCutoff; } float GetAttenuationConstant() const { return x24_distC; } float GetAttenuationLinear() const { return x28_distL; } float GetAttenuationQuadratic() const { return x2c_distQ; } @@ -88,7 +89,8 @@ public: float GetAngleAttenuationQuadratic() const { return x38_angleQ; } ELightType GetType() const { return x1c_type; } - + u32 GetId() const { return x40_lightId; } + u32 GetPriority() const { return x3c_priority; } float GetIntensity() const; float GetRadius() const; const zeus::CColor& GetColor() const { return x18_color; } @@ -96,7 +98,7 @@ public: static CLight BuildDirectional(const zeus::CVector3f& dir, const zeus::CColor& color); static CLight BuildSpot(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CColor& color, - float angle); + float cutoff); static CLight BuildPoint(const zeus::CVector3f& pos, const zeus::CColor& color); static CLight BuildCustom(const zeus::CVector3f& pos, const zeus::CVector3f& dir, const zeus::CColor& color, float distC, float distL, float distQ, float angleC, float angleL, float angleQ); diff --git a/Runtime/Graphics/CLineRenderer.cpp b/Runtime/Graphics/CLineRenderer.cpp index 036ce7b63..c1bbff3f0 100644 --- a/Runtime/Graphics/CLineRenderer.cpp +++ b/Runtime/Graphics/CLineRenderer.cpp @@ -11,48 +11,16 @@ void CLineRenderer::Initialize() { CLineRendererShaders::Initialize(); } void CLineRenderer::Shutdown() { CLineRendererShaders::Shutdown(); - s_vertPoolTex.doDestroy(); - s_vertPoolNoTex.doDestroy(); - s_uniformPool.doDestroy(); +// s_vertPoolTex.doDestroy(); +// s_vertPoolNoTex.doDestroy(); +// s_uniformPool.doDestroy(); } -hecl::VertexBufferPool CLineRenderer::s_vertPoolTex = {}; -hecl::VertexBufferPool CLineRenderer::s_vertPoolNoTex = {}; -hecl::UniformBufferPool CLineRenderer::s_uniformPool = {}; +//hecl::VertexBufferPool CLineRenderer::s_vertPoolTex = {}; +//hecl::VertexBufferPool CLineRenderer::s_vertPoolNoTex = {}; +//hecl::UniformBufferPool CLineRenderer::s_uniformPool = {}; -CLineRenderer::CLineRenderer(boo::IGraphicsDataFactory::Context& ctx, EPrimitiveMode mode, u32 maxVerts, - const boo::ObjToken& texture, bool additive, bool zTest, bool zGEqual) -: m_mode(mode), m_maxVerts(maxVerts) { - OPTICK_EVENT(); - if (maxVerts < 2) { - LineRendererLog.report(logvisor::Fatal, FMT_STRING("maxVerts < 2, maxVerts = {}"), maxVerts); - return; - } - m_textured = bool(texture); - - u32 maxTriVerts = 0; - switch (mode) { - case EPrimitiveMode::Lines: - case EPrimitiveMode::LineStrip: - maxTriVerts = maxVerts * 4; - break; - case EPrimitiveMode::LineLoop: - maxTriVerts = maxVerts * 4 + 4; - break; - } - - if (texture) { - m_vertBufTex = s_vertPoolTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); - } else { - m_vertBufNoTex = s_vertPoolNoTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); - } - - m_uniformBuf = s_uniformPool.allocateBlock(CGraphics::g_BooFactory); - - CLineRendererShaders::BuildShaderDataBinding(ctx, *this, texture, additive, zTest, zGEqual); -} - -CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, const boo::ObjToken& texture, +CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, u32 texture, bool additive, bool zTest, bool zGEqual) : m_mode(mode), m_maxVerts(maxVerts) { OPTICK_EVENT(); @@ -73,22 +41,22 @@ CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, const boo::ObjTo break; } - if (texture) { - m_vertBufTex = s_vertPoolTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); - } else { - m_vertBufNoTex = s_vertPoolNoTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); - } - - m_uniformBuf = s_uniformPool.allocateBlock(CGraphics::g_BooFactory); - - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - CLineRendererShaders::BuildShaderDataBinding(ctx, *this, texture, additive, zTest, zGEqual); - return true; - } BooTrace); +// if (texture) { +// m_vertBufTex = s_vertPoolTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); +// } else { +// m_vertBufNoTex = s_vertPoolNoTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts); +// } +// +// m_uniformBuf = s_uniformPool.allocateBlock(CGraphics::g_BooFactory); +// +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// CLineRendererShaders::BuildShaderDataBinding(ctx, *this, texture, additive, zTest, zGEqual); +// return true; +// } BooTrace); } -rstl::reserved_vector CLineRenderer::g_StaticLineVertsTex = {}; -rstl::reserved_vector CLineRenderer::g_StaticLineVertsNoTex = {}; +//rstl::reserved_vector CLineRenderer::g_StaticLineVertsTex = {}; +//rstl::reserved_vector CLineRenderer::g_StaticLineVertsNoTex = {}; static bool IntersectLines(const zeus::CVector2f& pa1, const zeus::CVector2f& pa2, const zeus::CVector2f& pb1, const zeus::CVector2f& pb2, zeus::CVector3f& intersect) { @@ -106,20 +74,20 @@ static bool IntersectLines(const zeus::CVector2f& pa1, const zeus::CVector2f& pa void CLineRenderer::Reset() { m_nextVert = 0; m_final = false; - if (m_textured) - g_StaticLineVertsTex.clear(); - else - g_StaticLineVertsNoTex.clear(); +// if (m_textured) +// g_StaticLineVertsTex.clear(); +// else +// g_StaticLineVertsNoTex.clear(); } void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColor& color, float width, const zeus::CVector2f& uv) { - if (m_final || !m_shaderBind[0] || m_nextVert >= m_maxVerts) + if (m_final /*|| !m_shaderBind[0]*/ || m_nextVert >= m_maxVerts) return; float adjWidth = width / 480.f; - float w; - zeus::CVector3f projPt = CGraphics::ProjectModelPointToViewportSpace(position, w); + float w = 0.f; + zeus::CVector3f projPt = {}; // CGraphics::ProjectModelPointToViewportSpace(position, w); if (m_mode == EPrimitiveMode::LineLoop) { if (m_nextVert == 0) { @@ -150,13 +118,13 @@ void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColo if (m_textured) { if (m_mode == EPrimitiveMode::Lines) { if (m_nextVert & 1) { - g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back()); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back()); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back()); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back()); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV}); } else { - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV}); } } else { zeus::CVector3f intersect1; @@ -174,25 +142,25 @@ void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColo if (good1 && good2) { intersect1.z() = float(m_lastPos.z()); intersect2.z() = float(m_lastPos.z()); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); } else { - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV}); } } } else { if (m_mode == EPrimitiveMode::Lines) { if (m_nextVert & 1) { - g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back()); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back()); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back()); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back()); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor}); } else { - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor}); } } else { zeus::CVector3f intersect1; @@ -210,13 +178,13 @@ void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColo if (good1 && good2) { intersect1.z() = float(m_lastPos.z()); intersect2.z() = float(m_lastPos.z()); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); } else { - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor}); } } } @@ -227,11 +195,11 @@ void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColo dv = dv.normalized().perpendicularVector() * m_lastWidth; dv.x() /= CGraphics::g_ProjAspect; if (m_textured) { - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor, m_lastUV}); } else { - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor}); } } @@ -278,25 +246,25 @@ void CLineRenderer::Render(bool alphaWrite, const zeus::CColor& moduColor) { if (good1 && good2) { intersect1.z() = float(m_lastPos.z()); intersect2.z() = float(m_lastPos.z()); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); } else { - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV}); } } else { if (good1 && good2) { intersect1.z() = float(m_lastPos.z()); intersect2.z() = float(m_lastPos.z()); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); } else { - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor}); } } } @@ -329,25 +297,25 @@ void CLineRenderer::Render(bool alphaWrite, const zeus::CColor& moduColor) { if (good1 && good2) { intersect1.z() = float(m_firstPos.z()); intersect2.z() = float(m_firstPos.z()); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV}); } else { - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor, m_lastUV}); } } else { if (good1 && good2) { intersect1.z() = float(m_firstPos.z()); intersect2.z() = float(m_firstPos.z()); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor}); } else { - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor}); } } } @@ -360,14 +328,14 @@ void CLineRenderer::Render(bool alphaWrite, const zeus::CColor& moduColor) { if (m_textured) { if (m_mode == EPrimitiveMode::Lines && (m_nextVert & 1)) { } else { - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor, m_lastUV}); - g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor, m_lastUV}); +// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor, m_lastUV}); } } else { if (m_mode == EPrimitiveMode::Lines && (m_nextVert & 1)) { } else { - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor}); - g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor}); +// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor}); } } } @@ -375,21 +343,21 @@ void CLineRenderer::Render(bool alphaWrite, const zeus::CColor& moduColor) { m_final = true; } - m_uniformBuf.access() = SDrawUniform{moduColor, CGraphics::g_Fog}; - if (m_textured) { - if (!g_StaticLineVertsTex.empty()) { - memmove(m_vertBufTex.access(), g_StaticLineVertsTex.data(), sizeof(SDrawVertTex) * g_StaticLineVertsTex.size()); - CGraphics::SetShaderDataBinding(m_shaderBind[alphaWrite]); - CGraphics::DrawArray(0, g_StaticLineVertsTex.size()); - } - } else { - if (!g_StaticLineVertsNoTex.empty()) { - memmove(m_vertBufNoTex.access(), g_StaticLineVertsNoTex.data(), - sizeof(SDrawVertNoTex) * g_StaticLineVertsNoTex.size()); - CGraphics::SetShaderDataBinding(m_shaderBind[alphaWrite]); - CGraphics::DrawArray(0, g_StaticLineVertsNoTex.size()); - } - } +// m_uniformBuf.access() = SDrawUniform{moduColor, CGraphics::g_Fog}; +// if (m_textured) { +// if (!g_StaticLineVertsTex.empty()) { +// memmove(m_vertBufTex.access(), g_StaticLineVertsTex.data(), sizeof(SDrawVertTex) * g_StaticLineVertsTex.size()); +// CGraphics::SetShaderDataBinding(m_shaderBind[alphaWrite]); +// CGraphics::DrawArray(0, g_StaticLineVertsTex.size()); +// } +// } else { +// if (!g_StaticLineVertsNoTex.empty()) { +// memmove(m_vertBufNoTex.access(), g_StaticLineVertsNoTex.data(), +// sizeof(SDrawVertNoTex) * g_StaticLineVertsNoTex.size()); +// CGraphics::SetShaderDataBinding(m_shaderBind[alphaWrite]); +// CGraphics::DrawArray(0, g_StaticLineVertsNoTex.size()); +// } +// } } } // namespace metaforce diff --git a/Runtime/Graphics/CLineRenderer.hpp b/Runtime/Graphics/CLineRenderer.hpp index 924ce30d8..4e87675e8 100644 --- a/Runtime/Graphics/CLineRenderer.hpp +++ b/Runtime/Graphics/CLineRenderer.hpp @@ -6,11 +6,6 @@ #include "Runtime/rstl.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include - -#include -#include - #include #include #include @@ -22,22 +17,6 @@ class CLineRenderer { public: enum class EPrimitiveMode { Lines, LineStrip, LineLoop }; - struct SDrawVertTex { - zeus::CVector4f pos; - zeus::CColor color; - zeus::CVector2f uv; - }; - - struct SDrawVertNoTex { - zeus::CVector4f pos; - zeus::CColor color; - }; - - struct SDrawUniform { - zeus::CColor moduColor; - CGraphics::CFogState fog; - }; - private: EPrimitiveMode m_mode; u32 m_maxVerts; @@ -59,22 +38,20 @@ private: float m_lastWidth; float m_lastW; - static rstl::reserved_vector g_StaticLineVertsTex; - static rstl::reserved_vector g_StaticLineVertsNoTex; +// static rstl::reserved_vector g_StaticLineVertsTex; +// static rstl::reserved_vector g_StaticLineVertsNoTex; - static hecl::VertexBufferPool s_vertPoolTex; - static hecl::VertexBufferPool s_vertPoolNoTex; - static hecl::UniformBufferPool s_uniformPool; +// static hecl::VertexBufferPool s_vertPoolTex; +// static hecl::VertexBufferPool s_vertPoolNoTex; +// static hecl::UniformBufferPool s_uniformPool; public: - hecl::VertexBufferPool::Token m_vertBufTex; - hecl::VertexBufferPool::Token m_vertBufNoTex; - hecl::UniformBufferPool::Token m_uniformBuf; - std::array, 2> m_shaderBind; +// hecl::VertexBufferPool::Token m_vertBufTex; +// hecl::VertexBufferPool::Token m_vertBufNoTex; +// hecl::UniformBufferPool::Token m_uniformBuf; +// std::array, 2> m_shaderBind; - CLineRenderer(boo::IGraphicsDataFactory::Context& ctx, EPrimitiveMode mode, u32 maxVerts, - const boo::ObjToken& texture, bool additive, bool zTest = false, bool zGEqual = false); - CLineRenderer(EPrimitiveMode mode, u32 maxVerts, const boo::ObjToken& texture, bool additive, + CLineRenderer(EPrimitiveMode mode, u32 maxVerts, u32 texture, bool additive, bool zTest = false, bool zGEqual = false); CLineRenderer(CLineRenderer&&) = default; @@ -83,11 +60,11 @@ public: const zeus::CVector2f& uv = zeus::skZero2f); void Render(bool alphaWrite = false, const zeus::CColor& moduColor = zeus::skWhite); - static void UpdateBuffers() { - s_vertPoolTex.updateBuffers(); - s_vertPoolNoTex.updateBuffers(); - s_uniformPool.updateBuffers(); - } +// static void UpdateBuffers() { +// s_vertPoolTex.updateBuffers(); +// s_vertPoolNoTex.updateBuffers(); +// s_uniformPool.updateBuffers(); +// } static void Initialize(); static void Shutdown(); diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 7938a5f3e..a176c948f 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -1,27 +1,31 @@ set(GRAPHICS_SOURCES IRenderer.hpp IWeaponRenderer.hpp IWeaponRenderer.cpp - CBooRenderer.hpp CBooRenderer.cpp + CCubeMaterial.cpp CCubeMaterial.hpp + CCubeModel.cpp CCubeModel.hpp + CCubeRenderer.cpp CCubeRenderer.hpp + CCubeSurface.cpp CCubeSurface.hpp CDrawable.hpp CDrawablePlaneObject.hpp CLineRenderer.hpp CLineRenderer.cpp - CMetroidModelInstance.hpp + CMetroidModelInstance.cpp CMetroidModelInstance.hpp CLight.hpp CLight.cpp - CTexture.hpp CTextureBoo.cpp - CModel.hpp CModelBoo.cpp + CTevCombiners.cpp CTevCombiners.hpp + CTexture.hpp CTexture.cpp + CModel.cpp CModel.hpp CSkinnedModel.hpp CSkinnedModel.cpp CVertexMorphEffect.hpp CVertexMorphEffect.cpp CMoviePlayer.hpp CMoviePlayer.cpp - CGraphicsPalette.hpp + CGraphicsPalette.hpp CGraphicsPalette.cpp + CGX.hpp CGX.cpp CPVSVisSet.hpp CPVSVisSet.cpp CPVSVisOctree.hpp CPVSVisOctree.cpp CPVSAreaSet.hpp CPVSAreaSet.cpp CGraphics.hpp CGraphics.cpp CSimpleShadow.hpp CSimpleShadow.cpp CRainSplashGenerator.hpp CRainSplashGenerator.cpp + CFont.hpp CFont.cpp Shaders/CLineRendererShaders.hpp Shaders/CLineRendererShaders.cpp - Shaders/CTexturedQuadFilter.hpp Shaders/CTexturedQuadFilter.cpp - Shaders/CColoredQuadFilter.hpp Shaders/CColoredQuadFilter.cpp Shaders/CColoredStripShader.hpp Shaders/CColoredStripShader.cpp Shaders/CModelShaders.hpp Shaders/CModelShaders.cpp Shaders/CThermalColdFilter.hpp Shaders/CThermalColdFilter.cpp diff --git a/Runtime/Graphics/CMetroidModelInstance.cpp b/Runtime/Graphics/CMetroidModelInstance.cpp new file mode 100644 index 000000000..db2b0e123 --- /dev/null +++ b/Runtime/Graphics/CMetroidModelInstance.cpp @@ -0,0 +1,63 @@ +#include "CMetroidModelInstance.hpp" + +#include "Graphics/CCubeSurface.hpp" +#include "Streams/IOStreams.hpp" + +#include + +namespace metaforce { +CMetroidModelInstance::CMetroidModelInstance(std::pair modelHeader, const u8* materialData, + std::pair positions, std::pair normals, + std::pair colors, std::pair texCoords, + std::pair packedTexCoords, + std::vector&& surfaces) +: x4c_materialData(materialData), x50_surfaces(std::move(surfaces)) { + { + CMemoryInStream stream{modelHeader.first, modelHeader.second}; + x0_visorFlags = stream.ReadUint32(); + x4_worldXf = stream.Get(); + x34_worldAABB = stream.Get(); + } + { + u32 numVertices = positions.second / 12; + CMemoryInStream stream{positions.first, positions.second}; + for (u32 i = 0; i < numVertices; ++i) { + x60_positions.emplace_back(stream.Get()); + } + } + { + // Always short normals in MREA + u32 numNormals = normals.second / 6; + CMemoryInStream stream{normals.first, normals.second}; + for (u32 i = 0; i < numNormals; ++i) { + const auto x = static_cast(stream.ReadInt16()) / 16384.f; + const auto y = static_cast(stream.ReadInt16()) / 16384.f; + const auto z = static_cast(stream.ReadInt16()) / 16384.f; + x64_normals.emplace_back(x, y, z); + } + } + { + u32 numColors = colors.second / 4; + CMemoryInStream stream{colors.first, colors.second}; + for (u32 i = 0; i < numColors; ++i) { + x68_colors.emplace_back(stream.ReadUint32()); + } + } + { + u32 numTexCoords = texCoords.second / 8; + CMemoryInStream stream{texCoords.first, texCoords.second}; + for (u32 i = 0; i < numTexCoords; ++i) { + x6c_texCoords.emplace_back(stream.Get>()); + } + } + { + u32 numPackedTexCoords = packedTexCoords.second / 4; + CMemoryInStream stream{packedTexCoords.first, packedTexCoords.second}; + for (u32 i = 0; i < numPackedTexCoords; ++i) { + const auto u = static_cast(stream.ReadInt16()) / 32768.f; + const auto v = static_cast(stream.ReadInt16()) / 32768.f; + x70_packedTexCoords.emplace_back(u, v); + } + } +} +} // namespace metaforce diff --git a/Runtime/Graphics/CMetroidModelInstance.hpp b/Runtime/Graphics/CMetroidModelInstance.hpp index 9bedb439d..a698bf82e 100644 --- a/Runtime/Graphics/CMetroidModelInstance.hpp +++ b/Runtime/Graphics/CMetroidModelInstance.hpp @@ -4,43 +4,46 @@ #include #include +#include "Graphics/CCubeModel.hpp" #include "Runtime/RetroTypes.hpp" -#include "Shaders/CModelShaders.hpp" - -#include - #include #include +#include namespace metaforce { -class CBooModel; -struct CBooSurface; +class CCubeSurface; class CMetroidModelInstance { - friend class CBooRenderer; - friend class CGameArea; - - int x0_visorFlags; - zeus::CTransform x4_xf; - zeus::CAABox x34_aabb; - std::vector m_surfaces; - std::unique_ptr m_instance; - hecl::HMDLMeta m_hmdlMeta; - std::unordered_map m_shaders; + u32 x0_visorFlags = 0; + zeus::CTransform x4_worldXf; + zeus::CAABox x34_worldAABB; + const u8* x4c_materialData = nullptr; + std::vector x50_surfaces; // was rstl::vector* + std::vector x60_positions; // was void* + std::vector x64_normals; // was void* + std::vector x68_colors; // was void* + std::vector> x6c_texCoords; // was void* + std::vector> x70_packedTexCoords; // was void* public: CMetroidModelInstance() = default; - CMetroidModelInstance(CMetroidModelInstance&&) = default; - void Clear() { - x0_visorFlags = 0; - x4_xf = {}; - x34_aabb = {}; - m_surfaces.clear(); - m_instance.reset(); - m_hmdlMeta = {}; - m_shaders.clear(); - } -}; + CMetroidModelInstance(std::pair modelHeader, const u8* materialData, + std::pair positions, std::pair normals, + std::pair colors, std::pair texCoords, + std::pair packedTexCoords, std::vector&& surfaces); + [[nodiscard]] u32 GetFlags() const { return x0_visorFlags; } + [[nodiscard]] const zeus::CAABox& GetBoundingBox() const { return x34_worldAABB; } + [[nodiscard]] std::vector* GetSurfaces() { return &x50_surfaces; } + [[nodiscard]] const std::vector* GetSurfaces() const { return &x50_surfaces; } + [[nodiscard]] const u8* GetMaterialPointer() const { return x4c_materialData; } + [[nodiscard]] TVectorRef GetVertexPointer() { return &x60_positions; } + [[nodiscard]] TConstVectorRef GetVertexPointer() const { return &x60_positions; } + [[nodiscard]] TVectorRef GetNormalPointer() { return &x64_normals; } + [[nodiscard]] TConstVectorRef GetNormalPointer() const { return &x64_normals; } + [[nodiscard]] const std::vector* GetColorPointer() const { return &x68_colors; } + [[nodiscard]] const std::vector>* GetTCPointer() const { return &x6c_texCoords; } + [[nodiscard]] const std::vector>* GetPackedTCPointer() const { return &x70_packedTexCoords; } +}; } // namespace metaforce diff --git a/Runtime/Graphics/CModel.cpp b/Runtime/Graphics/CModel.cpp new file mode 100644 index 000000000..91a58b65a --- /dev/null +++ b/Runtime/Graphics/CModel.cpp @@ -0,0 +1,309 @@ +#include "CModel.hpp" + +#include "CBasics.hpp" +#include "Graphics/CCubeMaterial.hpp" +#include "Graphics/CCubeModel.hpp" +#include "Graphics/CCubeSurface.hpp" +#include "Streams/IOStreams.hpp" + +namespace metaforce { +void CModel::SShader::UnlockTextures() { + for (auto& token : x0_textures) { + token.Unlock(); + } +} + +u32 CModel::sTotalMemory = 0; +u32 CModel::sFrameCounter = 0; +bool CModel::sIsTextureTimeoutEnabled = true; +CModel* CModel::sThisFrameList = nullptr; +CModel* CModel::sOneFrameList = nullptr; +CModel* CModel::sTwoFrameList = nullptr; + +static u8* MemoryFromPartData(u8*& dataCur, const u32*& secSizeCur) { + u8* ret = nullptr; + if (*secSizeCur != 0) { + ret = dataCur; + } + dataCur += CBasics::SwapBytes(*secSizeCur); + ++secSizeCur; + return ret; +} + +// For ease of reading byte swapped data +static CMemoryInStream StreamFromPartData(u8*& dataCur, const u32*& secSizeCur) { + const auto secSize = CBasics::SwapBytes(*secSizeCur); + return {MemoryFromPartData(dataCur, secSizeCur), secSize}; +} + +CModel::CModel(std::unique_ptr in, u32 dataLen, IObjectStore* store) +: x0_data(std::move(in)) +, x4_dataLen(dataLen) +, x34_next(sThisFrameList) +, x38_lastFrame(CGraphics::GetFrameCounter() - 2) { + u8* data = x0_data.get(); + u32 flags = CBasics::SwapBytes(*reinterpret_cast(data + 8)); + u32 sectionSizeStart = 0x2c; + if (CBasics::SwapBytes(*reinterpret_cast(data + 4)) == 1) { + sectionSizeStart = 0x28; + } + const u32* secSizeCur = reinterpret_cast(data + sectionSizeStart); + s32 numMatSets = 1; + if (CBasics::SwapBytes(*reinterpret_cast(data + 4)) > 1) { + numMatSets = CBasics::SwapBytes(*reinterpret_cast(data + 0x28)); + } + u8* dataCur = data + ROUND_UP_32(sectionSizeStart + CBasics::SwapBytes(*reinterpret_cast(data + 0x24)) * 4); + x18_matSets.reserve(numMatSets); + for (s32 i = 0; i < numMatSets; ++i) { + x18_matSets.emplace_back(MemoryFromPartData(dataCur, secSizeCur)); + auto& shader = x18_matSets.back(); + CCubeModel::MakeTexturesFromMats(shader.x10_data, shader.x0_textures, store, true); + x4_dataLen += shader.x0_textures.size() * sizeof(TCachedToken); + } + + /* Metaforce note: Due to padding in zeus types we need to convert these and store locally */ + u32 numVertices = CBasics::SwapBytes(*secSizeCur) / 12; + auto positions = StreamFromPartData(dataCur, secSizeCur); + for (u32 i = 0; i < numVertices; ++i) { + m_positions.emplace_back(positions.Get()); + } + + u32 numNormals = CBasics::SwapBytes(*secSizeCur); + numNormals /= (flags & 2) == 0 ? 12 : 6; + auto normals = StreamFromPartData(dataCur, secSizeCur); + for (u32 i = 0; i < numNormals; ++i) { + if ((flags & 2) == 0) { + m_normals.emplace_back(normals.Get()); + } else { + const auto x = static_cast(normals.ReadShort()) / 16384.f; + const auto y = static_cast(normals.ReadShort()) / 16384.f; + const auto z = static_cast(normals.ReadShort()) / 16384.f; + m_normals.emplace_back(x, y, z); + } + } + + u32 numColors = CBasics::SwapBytes(*secSizeCur) / 4; + auto vtxColors = StreamFromPartData(dataCur, secSizeCur); + for (u32 i = 0; i < numColors; ++i) { + m_colors.emplace_back(zeus::CColor(vtxColors.ReadUint32())); + } + + u32 numFloatUVs = CBasics::SwapBytes(*secSizeCur) / 8; + auto floatUVs = StreamFromPartData(dataCur, secSizeCur); + for (u32 i = 0; i < numFloatUVs; ++i) { + m_floatUVs.emplace_back(floatUVs.Get>()); + } + + if ((flags & 4) != 0) { + u32 numShortUVs = CBasics::SwapBytes(*secSizeCur) / 4; + auto shortUVs = StreamFromPartData(dataCur, secSizeCur); + for (u32 i = 0; i < numShortUVs; ++i) { + const auto u = static_cast(shortUVs.ReadShort()) / 32768.f; + const auto v = static_cast(shortUVs.ReadShort()) / 32768.f; + m_shortUVs.emplace_back(u, v); + } + } + + auto surfaceInfo = StreamFromPartData(dataCur, secSizeCur); + auto surfaceCount = surfaceInfo.ReadUint32(); + x8_surfaces.reserve(surfaceCount); + for (u32 i = 0; i < surfaceCount; ++i) { + if (x8_surfaces.capacity() <= x8_surfaces.size()) { + x8_surfaces.reserve(x8_surfaces.capacity() * 2); + } + const auto secSize = CBasics::SwapBytes(*secSizeCur); + x8_surfaces.emplace_back(MemoryFromPartData(dataCur, secSizeCur), secSize); + } + + const float* bounds = reinterpret_cast(data + 12); + const zeus::CAABox aabb{ + {CBasics::SwapBytes(bounds[0]), CBasics::SwapBytes(bounds[1]), CBasics::SwapBytes(bounds[2])}, + {CBasics::SwapBytes(bounds[3]), CBasics::SwapBytes(bounds[4]), CBasics::SwapBytes(bounds[5])}, + }; + + /* This constructor has been changed from the original to take into account platform differences */ + x28_modelInst = + std::make_unique(&x8_surfaces, &x18_matSets[0].x0_textures, x18_matSets[0].x10_data, &m_positions, + &m_colors, &m_normals, &m_floatUVs, &m_shortUVs, aabb, flags, true, -1); + + sThisFrameList = this; + if (x34_next != nullptr) { + x34_next->x30_prev = this; + } + x4_dataLen += x8_surfaces.size() * 4; + sTotalMemory += x4_dataLen; + // DCFlushRange(x0_data, dataLen); +} + +CModel::~CModel() { + RemoveFromList(); + sTotalMemory -= x4_dataLen; +} + +void CModel::UpdateLastFrame() { x38_lastFrame = CGraphics::GetFrameCounter(); } + +void CModel::MoveToThisFrameList() { + UpdateLastFrame(); + if (sThisFrameList == this) { + return; + } + + RemoveFromList(); + if (sThisFrameList != nullptr) { + x34_next = sThisFrameList; + x34_next->x30_prev = this; + } + + sThisFrameList = this; +} + +void CModel::RemoveFromList() { + if (x30_prev == nullptr) { + if (sThisFrameList == this) { + sThisFrameList = x34_next; + } else if (sOneFrameList == this) { + sOneFrameList = x34_next; + } else if (sTwoFrameList == this) { + sTwoFrameList = x34_next; + } + } else { + x30_prev->x34_next = x34_next; + } + if (x34_next != nullptr) { + x34_next->x30_prev = x30_prev; + } + x30_prev = nullptr; + x34_next = nullptr; +} + +void CModel::FrameDone() { + ++sFrameCounter; + if (sIsTextureTimeoutEnabled) { + auto* iter = sTwoFrameList; + while (iter != nullptr) { + auto* next = iter->x34_next; + iter->VerifyCurrentShader(0); + for (auto& shader : iter->x18_matSets) { + shader.UnlockTextures(); + } + + iter->x28_modelInst->UnlockTextures(); + iter->x34_next = nullptr; + iter->x30_prev = nullptr; + iter = next; + } + + sTwoFrameList = sOneFrameList; + sOneFrameList = sThisFrameList; + sThisFrameList = nullptr; + } +} + +void CModel::EnableTextureTimeout() { sIsTextureTimeoutEnabled = true; } + +void CModel::DisableTextureTimeout() { sIsTextureTimeoutEnabled = false; } + +TVectorRef CModel::GetPositions() { return x28_modelInst->GetPositions(); } + +TConstVectorRef CModel::GetPositions() const { return x28_modelInst->GetPositions(); } + +TVectorRef CModel::GetNormals() { return x28_modelInst->GetNormals(); } + +TConstVectorRef CModel::GetNormals() const { return x28_modelInst->GetNormals(); } + +void CModel::VerifyCurrentShader(u32 matIdx) { + if (matIdx > x18_matSets.size()) { + matIdx = 0; + } + if (matIdx == x2c_currentMatIdx) { + if (x2e_lastFrame != 0 && x2e_lastFrame < sFrameCounter) { + for (size_t idx = 0; auto& mat : x18_matSets) { + if (idx != matIdx) { + mat.UnlockTextures(); + } + idx++; + } + } + } else { + x2c_currentMatIdx = matIdx; + auto& mat = x18_matSets[matIdx]; + x28_modelInst->RemapMaterialData(mat.x10_data, mat.x0_textures); + if (x18_matSets.size() > 1) { + x2e_lastFrame = sFrameCounter + 2; + } + } +} + +bool CModel::IsLoaded(u32 matIdx) { + VerifyCurrentShader(matIdx); + const auto& textures = *x28_modelInst->x1c_textures; + if (textures.empty()) { + return true; + } + for (const auto& token : textures) { + if (token.IsNull() && !token.IsLoaded()) { + return false; + } + } + return true; +} + +void CModel::Touch(u32 matIdx) { + MoveToThisFrameList(); + VerifyCurrentShader(matIdx); + if (x28_modelInst->TryLockTextures()) { + for (auto& texture : *x28_modelInst->x1c_textures) { + if (!texture.IsNull()) { + // texture->LoadToMRAM(); + } + } + } +} + +void CModel::Draw(CModelFlags flags) { + if (flags.x2_flags & CModelFlagBits::DrawNormal) { + x28_modelInst->DrawNormal(nullptr, nullptr, ESurfaceSelection::All); + } + CCubeMaterial::ResetCachedMaterials(); + MoveToThisFrameList(); + VerifyCurrentShader(flags.x1_matSetIdx); + x28_modelInst->Draw(flags); +} + +void CModel::Draw(TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) { + if (flags.x2_flags & CModelFlagBits::DrawNormal) { + x28_modelInst->DrawNormal(positions, normals, ESurfaceSelection::All); + } + CCubeMaterial::ResetCachedMaterials(); + MoveToThisFrameList(); + VerifyCurrentShader(flags.x1_matSetIdx); + x28_modelInst->Draw(positions, normals, flags); +} + +void CModel::DrawSortedParts(CModelFlags flags) { + if (flags.x2_flags & CModelFlagBits::DrawNormal) { + x28_modelInst->DrawNormal(nullptr, nullptr, ESurfaceSelection::Sorted); + } + CCubeMaterial::ResetCachedMaterials(); + MoveToThisFrameList(); + VerifyCurrentShader(flags.x1_matSetIdx); + x28_modelInst->DrawAlpha(flags); +} + +void CModel::DrawUnsortedParts(CModelFlags flags) { + if (flags.x2_flags & CModelFlagBits::DrawNormal) { + x28_modelInst->DrawNormal(nullptr, nullptr, ESurfaceSelection::Unsorted); + } + CCubeMaterial::ResetCachedMaterials(); + MoveToThisFrameList(); + VerifyCurrentShader(flags.x1_matSetIdx); + x28_modelInst->DrawNormal(flags); +} + +CFactoryFnReturn FModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, + const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef) { + IObjectStore* store = vparms.GetOwnedObj(); + CFactoryFnReturn ret = TToken::GetIObjObjectFor(std::make_unique(std::move(in), len, store)); + return ret; +} +} // namespace metaforce diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index 40f808ae3..a770d0c5d 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -1,58 +1,50 @@ #pragma once #include -#include -#include #include -#include "DataSpec/DNACommon/CMDL.hpp" -#include "DataSpec/DNAMP1/CMDLMaterials.hpp" -#include "Runtime/CFactoryMgr.hpp" -#include "Runtime/CToken.hpp" -#include "Runtime/RetroTypes.hpp" -#include "Runtime/Graphics/CTexture.hpp" -#include "Runtime/Graphics/Shaders/CModelShaders.hpp" - -#include -#include -#include -#include +#include "CToken.hpp" +#include "GCNTypes.hpp" +#include "Graphics/CCubeModel.hpp" +#include "Graphics/CCubeSurface.hpp" +#include "Graphics/CTexture.hpp" +#include "IObjectStore.hpp" +#include "Flags.hpp" namespace metaforce { -class CLight; -class CModel; -class CPoseAsTransforms; -class CSkinRules; -class IObjectStore; +class CCubeMaterial; + +enum class CModelFlagBits : u16 { + DepthTest = 0x1, + DepthUpdate = 0x2, + NoTextureLock = 0x4, + DepthGreater = 0x8, + DepthNonInclusive = 0x10, + DrawNormal = 0x20, + ThermalUnsortedOnly = 0x40, +}; +using CModelFlagsFlags = Flags; struct CModelFlags { - u8 x0_blendMode = 0; /* 2: add color, >6: additive, >4: blend, else opaque */ + /** + * 2: add color + * >6: additive + * >4: blend + * else opaque + */ + u8 x0_blendMode = 0; u8 x1_matSetIdx = 0; - EExtendedShader m_extendedShader = EExtendedShader::Lighting; - bool m_noCull = false; - bool m_noZTest = false; - bool m_noZWrite = false; - bool m_depthGreater = false; - u16 x2_flags = 0; /* Flags */ - zeus::CColor x4_color; /* Set into kcolor slot specified by material */ - zeus::CColor addColor = zeus::skClear; - zeus::CAABox mbShadowBox; + CModelFlagsFlags x2_flags{}; + /** + * Set into kcolor slot specified by material + */ + zeus::CColor x4_color; constexpr CModelFlags() = default; constexpr CModelFlags(u8 blendMode, u8 shadIdx, u16 flags, const zeus::CColor& col) - : x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) { - /* Blend mode will override this if the surface's original material is opaque */ - m_noZWrite = (x2_flags & 0x2) == 0; - m_depthGreater = (x2_flags & 0x8) != 0; - } - - /* Flags - 0x1: depth lequal - 0x2: depth update - 0x4: render without texture lock - 0x8: depth greater - 0x10: depth non-inclusive - */ + : x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) {} + constexpr CModelFlags(u8 blendMode, u8 shadIdx, CModelFlagsFlags flags, const zeus::CColor& col) + : x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) {} bool operator==(const CModelFlags& other) const { return x0_blendMode == other.x0_blendMode && x1_matSetIdx == other.x1_matSetIdx && x2_flags == other.x2_flags && @@ -62,255 +54,73 @@ struct CModelFlags { bool operator!=(const CModelFlags& other) const { return !operator==(other); } }; -/* metaforce addition: doesn't require hacky stashing of - * pointers within loaded CMDL buffer */ -struct CBooSurface { - DataSpec::DNACMDL::SurfaceHeader_2 m_data; - size_t selfIdx; - class CBooModel* m_parent = nullptr; - CBooSurface* m_next = nullptr; - - zeus::CAABox GetBounds() const { - if (!m_data.aabbSz) - return zeus::CAABox(m_data.centroid, m_data.centroid); - else - return zeus::CAABox(m_data.aabb[0], m_data.aabb[1]); - } -}; - -using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; - -struct GeometryUniformLayout { - mutable std::vector> m_sharedBuffer; - size_t m_geomBufferSize = 0; - size_t m_skinBankCount = 0; - size_t m_weightVecCount = 0; - - std::vector m_skinOffs; - std::vector m_skinSizes; - - std::vector m_uvOffs; - std::vector m_uvSizes; - - GeometryUniformLayout(const CModel* model, const MaterialSet* matSet); - void Update(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose, - const MaterialSet* matSet, const boo::ObjToken& buf, - const CBooModel* parent) const; - - void ReserveSharedBuffers(boo::IGraphicsDataFactory::Context& ctx, int size); - boo::ObjToken GetSharedBuffer(int idx) const; -}; - -struct SShader { - std::unordered_map> x0_textures; - std::unordered_map m_shaders; - MaterialSet m_matSet; - std::optional m_geomLayout; - int m_matSetIdx; - explicit SShader(int idx) : m_matSetIdx(idx) { - x0_textures.clear(); - m_shaders.clear(); - } - void InitializeLayout(const CModel* model) { m_geomLayout.emplace(model, &m_matSet); } - void UnlockTextures(); - CModelShaders::ShaderPipelines BuildShader(const hecl::HMDLMeta& meta, const MaterialSet::Material& mat); - void BuildShaders(const hecl::HMDLMeta& meta, std::unordered_map& shaders); - void BuildShaders(const hecl::HMDLMeta& meta) { BuildShaders(meta, m_shaders); } -}; - -class CBooModel { - friend class CBooRenderer; - friend class CGameArea; - friend class CMetroidModelInstance; - friend class CModel; - friend class CSkinnedModel; - friend struct GeometryUniformLayout; - +class CModel { public: - enum class ESurfaceSelection { UnsortedOnly, SortedOnly, All }; + struct SShader { + std::vector> x0_textures; + u8* x10_data; + + explicit SShader(u8* data) : x10_data(data) {} + + void UnlockTextures(); + }; private: - CBooModel* m_next = nullptr; - CBooModel* m_prev = nullptr; - size_t m_uniUpdateCount = 0; - TToken m_modelTok; - CModel* m_model; - std::vector* x0_surfaces; - const MaterialSet* x4_matSet; - const GeometryUniformLayout* m_geomLayout; - int m_matSetIdx = -1; - const std::unordered_map* m_pipelines; - std::unordered_map> x1c_textures; - zeus::CAABox x20_aabb; - CBooSurface* x38_firstUnsortedSurface = nullptr; - CBooSurface* x3c_firstSortedSurface = nullptr; - bool x40_24_texturesLoaded : 1 = false; - bool x40_25_modelVisible : 1 = false; - u8 x41_mask; - u32 x44_areaInstanceIdx = UINT32_MAX; + static u32 sTotalMemory; + static u32 sFrameCounter; + static bool sIsTextureTimeoutEnabled; + static CModel* sThisFrameList; + static CModel* sOneFrameList; + static CModel* sTwoFrameList; - struct UVAnimationBuffer { - static void ProcessAnimation(u8*& bufOut, const MaterialSet::Material::PASS& anim); - static void PadOutBuffer(u8*& bufStart, u8*& bufOut); - static void Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, const CBooModel* parent); - }; - - CModelShaders::LightingUniform m_lightingData; - - /* metaforce addition: boo! */ - size_t m_uniformDataSize = 0; - struct ModelInstance { - boo::ObjToken m_geomUniformBuffer; - boo::ObjToken m_uniformBuffer; - std::vector>> m_shaderDataBindings; - boo::ObjToken m_dynamicVbo; - - boo::ObjToken GetBooVBO(const CBooModel& model, boo::IGraphicsDataFactory::Context& ctx); - }; - std::vector m_instances; - ModelInstance m_ballShadowInstance; - - boo::ObjToken m_staticVbo; - boo::ObjToken m_staticIbo; - - boo::ObjToken m_lastDrawnShadowMap; - boo::ObjToken m_lastDrawnOneTexture; - boo::ObjToken m_lastDrawnReflectionCube; - - ModelInstance* PushNewModelInstance(int sharedLayoutBuf = -1, boo::IGraphicsDataFactory::Context* ctx = nullptr); - void DrawAlphaSurfaces(const CModelFlags& flags) const; - void DrawNormalSurfaces(const CModelFlags& flags) const; - void DrawSurfaces(const CModelFlags& flags) const; - void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const; - void WarmupDrawSurfaces() const; - void WarmupDrawSurface(const CBooSurface& surf) const; - - static inline zeus::CVector3f g_PlayerPosition; - static inline float g_ModSeconds = 0.0f; - static inline float g_TransformedTime = 0.0f; - static inline float g_TransformedTime2 = 0.0f; - static inline CBooModel* g_LastModelCached = nullptr; - - static inline bool g_DummyTextures = false; - static inline bool g_RenderModelBlack = false; - -public: - ~CBooModel(); - CBooModel(TToken& token, CModel* parent, std::vector* surfaces, SShader& shader, - const boo::ObjToken& vbo, const boo::ObjToken& ibo, - const zeus::CAABox& aabb, u8 renderMask, int numInsts); - - static void MakeTexturesFromMats(const MaterialSet& matSet, - std::unordered_map>& toksOut, IObjectStore& store); - void MakeTexturesFromMats(std::unordered_map>& toksOut, IObjectStore& store); - - bool IsOpaque() const { return x3c_firstSortedSurface == nullptr; } - void ActivateLights(const std::vector& lights); - void SetAmbientColor(const zeus::CColor& color) { m_lightingData.ambient = color; } - void DisableAllLights(); - void RemapMaterialData(SShader& shader); - void RemapMaterialData(SShader& shader, const std::unordered_map& pipelines); - bool TryLockTextures(); - void UnlockTextures(); - void SyncLoadTextures(); - void Touch(int shaderIdx); - void VerifyCurrentShader(int shaderIdx); - boo::ObjToken UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr, - const CPoseAsTransforms* pose, int sharedLayoutBuf = -1, - boo::IGraphicsDataFactory::Context* ctx = nullptr); - void DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); - void DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); - void Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); - void DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const; - - void LockParent() { m_modelTok.Lock(); } - void UnlockParent() { m_modelTok.Unlock(); } - - const MaterialSet::Material& GetMaterialByIndex(int idx) const { return x4_matSet->materials.at(idx); } - - void ClearUniformCounter() { m_uniUpdateCount = 0; } - static void ClearModelUniformCounters(); - - static inline bool g_DrawingOccluders = false; - static void SetDrawingOccluders(bool occ) { g_DrawingOccluders = occ; } - - static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos); - - static inline zeus::CVector3f g_ReflectViewPos; - static void KillCachedViewDepState(); - static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, zeus::CMatrix4f* mtxsOut, - float& alphaOut); - - static inline boo::ObjToken g_shadowMap; - static inline zeus::CTransform g_shadowTexXf; - static void EnableShadowMaps(const boo::ObjToken& map, const zeus::CTransform& texXf); - static void DisableShadowMaps(); - - static inline boo::ObjToken g_disintegrateTexture; - static void SetDisintegrateTexture(const boo::ObjToken& map) { g_disintegrateTexture = map; } - - static inline boo::ObjToken g_reflectionCube; - static void SetReflectionCube(const boo::ObjToken& map) { g_reflectionCube = map; } - - static void SetDummyTextures(bool b) { g_DummyTextures = b; } - static void SetRenderModelBlack(bool b) { g_RenderModelBlack = b; } - - static void Shutdown(); - - const zeus::CAABox& GetAABB() const { return x20_aabb; } -}; - -class CModel { - friend class CBooModel; - friend struct GeometryUniformLayout; - // std::unique_ptr x0_data; - // u32 x4_dataLen; - TToken m_selfToken; /* DO NOT LOCK! */ - zeus::CAABox m_aabb; - u32 m_flags; - std::vector x8_surfaces; + std::unique_ptr x0_data; + u32 x4_dataLen; + std::vector x8_surfaces; // was rstl::vector std::vector x18_matSets; - std::unique_ptr x28_modelInst; - // CModel* x30_next = nullptr; - // CModel* x34_prev = nullptr; - int x38_lastFrame; + std::unique_ptr x28_modelInst = nullptr; + u16 x2c_currentMatIdx = 0; + u16 x2e_lastFrame = 0; // Last frame that the model switched materials + CModel* x30_prev = nullptr; + CModel* x34_next; + u32 x38_lastFrame; - /* metaforce addition: boo! */ - boo::ObjToken m_staticVbo; - hecl::HMDLMeta m_hmdlMeta; - std::unique_ptr m_dynamicVertexData; - boo::ObjToken m_ibo; + /* Resident copies of maintained data */ + std::vector m_positions; + std::vector m_normals; + std::vector m_colors; + std::vector> m_floatUVs; + std::vector> m_shortUVs; public: - using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; + CModel(std::unique_ptr in, u32 dataLen, IObjectStore* store); + ~CModel(); - CModel(std::unique_ptr&& in, u32 dataLen, IObjectStore* store, CObjectReference* selfRef); - void DrawSortedParts(const CModelFlags& flags) const; - void DrawUnsortedParts(const CModelFlags& flags) const; - void Draw(const CModelFlags& flags) const; - bool IsLoaded(int shaderIdx) const; - void Touch(int shaderIdx) { x28_modelInst->Touch(shaderIdx); } + void UpdateLastFrame(); + void MoveToThisFrameList(); + void RemoveFromList(); + void VerifyCurrentShader(u32 matIdx); + void Touch(u32 matIdx); + void Draw(CModelFlags flags); + void Draw(TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags); + void DrawSortedParts(CModelFlags flags); + void DrawUnsortedParts(CModelFlags flags); + bool IsLoaded(u32 matIdx); - const zeus::CAABox& GetAABB() const { return m_aabb; } - CBooModel& GetInstance() { return *x28_modelInst; } - const CBooModel& GetInstance() const { return *x28_modelInst; } - std::unique_ptr MakeNewInstance(int shaderIdx, int subInsts, bool lockParent = true); - void UpdateLastFrame() const { const_cast(*this).x38_lastFrame = CGraphics::GetFrameCounter(); } - u32 GetNumMaterialSets() const { return x18_matSets.size(); } + [[nodiscard]] TVectorRef GetPositions(); + [[nodiscard]] TConstVectorRef GetPositions() const; + [[nodiscard]] TVectorRef GetNormals(); + [[nodiscard]] TConstVectorRef GetNormals() const; + [[nodiscard]] u32 GetNumMaterialSets() const { return x18_matSets.size(); } + [[nodiscard]] bool IsOpaque() const { return x28_modelInst->x3c_firstSortedSurf == nullptr; } + [[nodiscard]] const zeus::CAABox& GetAABB() const { return x28_modelInst->x20_worldAABB; } + [[nodiscard]] auto& GetInstance() { return *x28_modelInst; } + [[nodiscard]] const auto& GetInstance() const { return *x28_modelInst; } - size_t GetPoolVertexOffset(size_t idx) const; - zeus::CVector3f GetPoolVertex(size_t idx) const; - size_t GetPoolNormalOffset(size_t idx) const; - zeus::CVector3f GetPoolNormal(size_t idx) const; - void ApplyVerticesCPU(const boo::ObjToken& vertBuf, - const std::vector>& vn) const; - void RestoreVerticesCPU(const boo::ObjToken& vertBuf) const; - - void _WarmupShaders(); - static void WarmupShaders(const SObjectTag& cmdlTag); + static void FrameDone(); + static void EnableTextureTimeout(); + static void DisableTextureTimeout(); }; CFactoryFnReturn FModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); - } // namespace metaforce diff --git a/Runtime/Graphics/CModel.hpp.old b/Runtime/Graphics/CModel.hpp.old new file mode 100644 index 000000000..1e3255d23 --- /dev/null +++ b/Runtime/Graphics/CModel.hpp.old @@ -0,0 +1,312 @@ +#pragma once + +#include +#include +#include +#include + +//#include "DataSpec/DNACommon/CMDL.hpp" +//#include "DataSpec/DNAMP1/CMDLMaterials.hpp" +#include "Runtime/CFactoryMgr.hpp" +#include "Runtime/CToken.hpp" +#include "Runtime/Graphics/CTexture.hpp" +#include "Runtime/Graphics/Shaders/CModelShaders.hpp" +#include "Runtime/RetroTypes.hpp" + +//#include +#include +#include + +namespace metaforce { +class CLight; +class CModel; +class CPoseAsTransforms; +class CSkinRules; +class IObjectStore; + +struct CModelFlags { + u8 x0_blendMode = 0; /* 2: add color, >6: additive, >4: blend, else opaque */ + u8 x1_matSetIdx = 0; + EExtendedShader m_extendedShader = EExtendedShader::Lighting; + bool m_noCull = false; + bool m_noZTest = false; + bool m_noZWrite = false; + bool m_depthGreater = false; + u16 x2_flags = 0; /* Flags */ + zeus::CColor x4_color; /* Set into kcolor slot specified by material */ + zeus::CColor addColor = zeus::skClear; + zeus::CAABox mbShadowBox; + + constexpr CModelFlags() = default; + constexpr CModelFlags(u8 blendMode, u8 shadIdx, u16 flags, const zeus::CColor& col) + : x0_blendMode(blendMode), x1_matSetIdx(shadIdx), x2_flags(flags), x4_color(col) { + /* Blend mode will override this if the surface's original material is opaque */ + m_noZWrite = (x2_flags & 0x2) == 0; + m_depthGreater = (x2_flags & 0x8) != 0; + } + + /* Flags + 0x1: depth lequal + 0x2: depth update + 0x4: render without texture lock + 0x8: depth greater + 0x10: depth non-inclusive + */ + + bool operator==(const CModelFlags& other) const { + return x0_blendMode == other.x0_blendMode && x1_matSetIdx == other.x1_matSetIdx && x2_flags == other.x2_flags && + x4_color == other.x4_color; + } + + bool operator!=(const CModelFlags& other) const { return !operator==(other); } +}; + +/* metaforce addition: doesn't require hacky stashing of + * pointers within loaded CMDL buffer */ +struct CBooSurface { +// DataSpec::DNACMDL::SurfaceHeader_2 m_data; + size_t selfIdx; + class CBooModel* m_parent = nullptr; + CBooSurface* m_next = nullptr; + + zeus::CAABox GetBounds() const { +// if (!m_data.aabbSz) +// return zeus::CAABox(m_data.centroid, m_data.centroid); +// else +// return zeus::CAABox(m_data.aabb[0], m_data.aabb[1]); + return {}; + } +}; + +//using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; + +//struct GeometryUniformLayout { +// mutable std::vector> m_sharedBuffer; +// size_t m_geomBufferSize = 0; +// size_t m_skinBankCount = 0; +// size_t m_weightVecCount = 0; +// +// std::vector m_skinOffs; +// std::vector m_skinSizes; +// +// std::vector m_uvOffs; +// std::vector m_uvSizes; +// +// GeometryUniformLayout(const CModel* model, const MaterialSet* matSet); +// void Update(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose, +// const MaterialSet* matSet, const boo::ObjToken& buf, +// const CBooModel* parent) const; +// +// void ReserveSharedBuffers(boo::IGraphicsDataFactory::Context& ctx, int size); +// boo::ObjToken GetSharedBuffer(int idx) const; +//}; + +struct SShader { + std::unordered_map> x0_textures; +// std::unordered_map m_shaders; +// MaterialSet m_matSet; +// std::optional m_geomLayout; + int m_matSetIdx; + explicit SShader(int idx) : m_matSetIdx(idx) { + x0_textures.clear(); +// m_shaders.clear(); + } +// void InitializeLayout(const CModel* model) { m_geomLayout.emplace(model, &m_matSet); } + void UnlockTextures(); +// CModelShaders::ShaderPipelines BuildShader(const hecl::HMDLMeta& meta, const MaterialSet::Material& mat); +// void BuildShaders(const hecl::HMDLMeta& meta, std::unordered_map& shaders); +// void BuildShaders(const hecl::HMDLMeta& meta) { BuildShaders(meta, m_shaders); } +}; + +class CBooModel { + friend class CBooRenderer; + friend class CGameArea; + friend class CMetroidModelInstance; + friend class CModel; + friend class CSkinnedModel; + friend struct GeometryUniformLayout; + +public: + enum class ESurfaceSelection { UnsortedOnly, SortedOnly, All }; + +private: + CBooModel* m_next = nullptr; + CBooModel* m_prev = nullptr; + size_t m_uniUpdateCount = 0; + TToken m_modelTok; + CModel* m_model; + std::vector* x0_surfaces; +// const MaterialSet* x4_matSet; +// const GeometryUniformLayout* m_geomLayout; + int m_matSetIdx = -1; +// const std::unordered_map* m_pipelines; + std::unordered_map> x1c_textures; + zeus::CAABox x20_aabb; + CBooSurface* x38_firstUnsortedSurface = nullptr; + CBooSurface* x3c_firstSortedSurface = nullptr; + bool x40_24_texturesLoaded : 1 = false; + bool x40_25_modelVisible : 1 = false; + u8 x41_mask; + u32 x44_areaInstanceIdx = UINT32_MAX; + +// struct UVAnimationBuffer { +// static void ProcessAnimation(u8*& bufOut, const MaterialSet::Material::PASS& anim); +// static void PadOutBuffer(u8*& bufStart, u8*& bufOut); +// static void Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, const CBooModel* parent); +// }; + + CModelShaders::LightingUniform m_lightingData; + + /* metaforce addition: boo! */ +// size_t m_uniformDataSize = 0; +// struct ModelInstance { +// boo::ObjToken m_geomUniformBuffer; +// boo::ObjToken m_uniformBuffer; +// std::vector>> m_shaderDataBindings; +// boo::ObjToken m_dynamicVbo; +// +// boo::ObjToken GetBooVBO(const CBooModel& model, boo::IGraphicsDataFactory::Context& ctx); +// }; +// std::vector m_instances; +// ModelInstance m_ballShadowInstance; + +// boo::ObjToken m_staticVbo; +// boo::ObjToken m_staticIbo; +// +// boo::ObjToken m_lastDrawnShadowMap; +// boo::ObjToken m_lastDrawnOneTexture; +// boo::ObjToken m_lastDrawnReflectionCube; + +// ModelInstance* PushNewModelInstance(int sharedLayoutBuf = -1, boo::IGraphicsDataFactory::Context* ctx = nullptr); + void DrawAlphaSurfaces(const CModelFlags& flags) const; + void DrawNormalSurfaces(const CModelFlags& flags) const; + void DrawSurfaces(const CModelFlags& flags) const; + void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const; + void WarmupDrawSurfaces() const; + void WarmupDrawSurface(const CBooSurface& surf) const; + + static inline zeus::CVector3f g_PlayerPosition; + static inline float g_ModSeconds = 0.0f; + static inline float g_TransformedTime = 0.0f; + static inline float g_TransformedTime2 = 0.0f; + static inline CBooModel* g_LastModelCached = nullptr; + + static inline bool g_DummyTextures = false; + static inline bool g_RenderModelBlack = false; + +public: + ~CBooModel(); + CBooModel(TToken& token, CModel* parent, std::vector* surfaces, SShader& shader, + // TODO +// boo::ObjToken vbo, boo::ObjToken ibo, + const zeus::CAABox& aabb, u8 renderMask); + +// static void MakeTexturesFromMats(const MaterialSet& matSet, +// std::unordered_map>& toksOut, IObjectStore& store); + void MakeTexturesFromMats(std::unordered_map>& toksOut, IObjectStore& store); + + bool IsOpaque() const { return x3c_firstSortedSurface == nullptr; } + void ActivateLights(const std::vector& lights); + void SetAmbientColor(const zeus::CColor& color) { m_lightingData.ambient = color; } + void DisableAllLights(); + void RemapMaterialData(SShader& shader); + bool TryLockTextures(); + void UnlockTextures(); + void SyncLoadTextures(); + void Touch(int shaderIdx); + void VerifyCurrentShader(int shaderIdx); +// boo::ObjToken UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr, +// const CPoseAsTransforms* pose, int sharedLayoutBuf = -1); + void DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); + void DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); + void Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose); + void DrawFlat(ESurfaceSelection sel, EExtendedShader extendedIdx) const; + + void LockParent() { m_modelTok.Lock(); } + void UnlockParent() { m_modelTok.Unlock(); } + +// const MaterialSet::Material& GetMaterialByIndex(int idx) const { return x4_matSet->materials.at(idx); } + + void ClearUniformCounter() { m_uniUpdateCount = 0; } + static void ClearModelUniformCounters(); + + static inline bool g_DrawingOccluders = false; + static void SetDrawingOccluders(bool occ) { g_DrawingOccluders = occ; } + + static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos); + + static inline zeus::CVector3f g_ReflectViewPos; + static void KillCachedViewDepState(); + static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf, zeus::CMatrix4f* mtxsOut, + float& alphaOut); + + static inline aurora::gfx::TextureHandle g_shadowMap; + static inline zeus::CTransform g_shadowTexXf; + static void EnableShadowMaps(const aurora::gfx::TextureHandle& map, const zeus::CTransform& texXf); + static void DisableShadowMaps(); + + static inline aurora::gfx::TextureHandle g_disintegrateTexture; + static void SetDisintegrateTexture(const aurora::gfx::TextureHandle& map) { g_disintegrateTexture = map; } + + static inline aurora::gfx::TextureHandle g_reflectionCube; + static void SetReflectionCube(const aurora::gfx::TextureHandle& map) { g_reflectionCube = map; } + + static void SetDummyTextures(bool b) { g_DummyTextures = b; } + static void SetRenderModelBlack(bool b) { g_RenderModelBlack = b; } + + static void Shutdown(); + + const zeus::CAABox& GetAABB() const { return x20_aabb; } +}; + +class CModel { + friend class CBooModel; + friend struct GeometryUniformLayout; + // std::unique_ptr x0_data; + // u32 x4_dataLen; + TToken m_selfToken; /* DO NOT LOCK! */ + zeus::CAABox m_aabb; + u32 m_flags; + std::vector x8_surfaces; + std::vector x18_matSets; + std::unique_ptr x28_modelInst; + // CModel* x30_next = nullptr; + // CModel* x34_prev = nullptr; + int x38_lastFrame; + + /* metaforce addition: boo! */ +// boo::ObjToken m_staticVbo; +// hecl::HMDLMeta m_hmdlMeta; + std::unique_ptr m_dynamicVertexData; +// boo::ObjToken m_ibo; + +public: +// using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet; + + CModel(std::unique_ptr&& in, u32 dataLen, IObjectStore* store, CObjectReference* selfRef); + void DrawSortedParts(const CModelFlags& flags) const; + void DrawUnsortedParts(const CModelFlags& flags) const; + void Draw(const CModelFlags& flags) const; + bool IsLoaded(int shaderIdx) const; + void Touch(int shaderIdx) { x28_modelInst->Touch(shaderIdx); } + + const zeus::CAABox& GetAABB() const { return m_aabb; } + CBooModel& GetInstance() { return *x28_modelInst; } + const CBooModel& GetInstance() const { return *x28_modelInst; } + std::unique_ptr MakeNewInstance(int shaderIdx, bool lockParent = true); + void UpdateLastFrame() const { const_cast(*this).x38_lastFrame = CGraphics::GetFrameCounter(); } + u32 GetNumMaterialSets() const { return x18_matSets.size(); } + + size_t GetPoolVertexOffset(size_t idx) const; + zeus::CVector3f GetPoolVertex(size_t idx) const; + size_t GetPoolNormalOffset(size_t idx) const; + zeus::CVector3f GetPoolNormal(size_t idx) const; +// void ApplyVerticesCPU(const boo::ObjToken& vertBuf, +// const std::vector>& vn) const; +// void RestoreVerticesCPU(const boo::ObjToken& vertBuf) const; +}; + +CFactoryFnReturn FPCModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, + const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); + +} // namespace metaforce diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index 46b6039df..32ad5ea45 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -1,9 +1,10 @@ #include "Runtime/Graphics/CModel.hpp" +#include "Runtime/CBasics.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Character/CSkinRules.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CLight.hpp" #include "Runtime/Graphics/CTexture.hpp" @@ -11,11 +12,10 @@ #include -#include -#include -#include -#include +#include "ConsoleVariables/CVarManager.hpp" +//#include #include +#include namespace metaforce { namespace { @@ -78,10 +78,10 @@ void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurfa zeus::CVector3f surfPos; float surfSize = 0.f; if (surf) { - zeus::CVector3f surfCenter(surf->m_data.centroid); - zeus::CVector3f surfNormal(surf->m_data.reflectionNormal); - float dotDelta = surfNormal.dot(modelToPlayerLocal) - surfCenter.dot(surfNormal); - surfPos = modelToPlayerLocal - surfNormal * dotDelta; +// zeus::CVector3f surfCenter(surf->m_data.centroid); +// zeus::CVector3f surfNormal(surf->m_data.reflectionNormal); +// float dotDelta = surfNormal.dot(modelToPlayerLocal) - surfCenter.dot(surfNormal); +// surfPos = modelToPlayerLocal - surfNormal * dotDelta; } else { surfPos = model.x20_aabb.center(); surfSize = @@ -125,21 +125,21 @@ void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurfa mtxsOut[1][3][0] = -surfPos.dot(v2) * f1 + 0.5f; mtxsOut[1][2][1] = f2; mtxsOut[1][3][1] = -modelToPlayerLocal.z() * f2; - switch (CGraphics::g_BooPlatform) { - case boo::IGraphicsDataFactory::Platform::OpenGL: - mtxsOut[1] = ReflectPostGL * mtxsOut[1]; - break; - default: - break; - } +// switch (CGraphics::g_BooPlatform) { +// case boo::IGraphicsDataFactory::Platform::OpenGL: +// mtxsOut[1] = ReflectPostGL * mtxsOut[1]; +// break; +// default: +// break; +// } } } -void CBooModel::EnableShadowMaps(const boo::ObjToken& map, const zeus::CTransform& texXf) { +void CBooModel::EnableShadowMaps(const aurora::gfx::TextureHandle& map, const zeus::CTransform& texXf) { g_shadowMap = map; g_shadowTexXf = texXf; } -void CBooModel::DisableShadowMaps() { g_shadowMap = nullptr; } +void CBooModel::DisableShadowMaps() { g_shadowMap.reset(); } CBooModel::~CBooModel() { if (m_prev) @@ -151,20 +151,21 @@ CBooModel::~CBooModel() { } CBooModel::CBooModel(TToken& token, CModel* parent, std::vector* surfaces, SShader& shader, - const boo::ObjToken& vbo, const boo::ObjToken& ibo, - const zeus::CAABox& aabb, u8 renderMask, int numInsts) +// boo::ObjToken vbo, boo::ObjToken ibo, + const zeus::CAABox& aabb, u8 renderMask) : m_modelTok(token) , m_model(parent) , x0_surfaces(surfaces) -, x4_matSet(&shader.m_matSet) -, m_geomLayout(&*shader.m_geomLayout) +//, x4_matSet(&shader.m_matSet) +//, m_geomLayout(&*shader.m_geomLayout) , m_matSetIdx(shader.m_matSetIdx) -, m_pipelines(&shader.m_shaders) +//, m_pipelines(&shader.m_shaders) , x1c_textures(shader.x0_textures) , x20_aabb(aabb) , x41_mask(renderMask) -, m_staticVbo(vbo) -, m_staticIbo(ibo) { +//, m_staticVbo(std::move(vbo)) +//, m_staticIbo(std::move(ibo)) +{ if (!g_FirstModel) g_FirstModel = this; else { @@ -177,256 +178,248 @@ CBooModel::CBooModel(TToken& token, CModel* parent, std::vectorrbegin(); it != x0_surfaces->rend(); ++it) { - u32 matId = it->m_data.matIdx; - const MaterialSet::Material& matData = GetMaterialByIndex(matId); - if (matData.flags.depthSorting()) { - it->m_next = x3c_firstSortedSurface; - x3c_firstSortedSurface = &*it; - } else { - it->m_next = x38_firstUnsortedSurface; - x38_firstUnsortedSurface = &*it; - } +// u32 matId = it->m_data.matIdx; +// const MaterialSet::Material& matData = GetMaterialByIndex(matId); +// if (matData.flags.depthSorting()) { +// it->m_next = x3c_firstSortedSurface; +// x3c_firstSortedSurface = &*it; +// } else { +// it->m_next = x38_firstUnsortedSurface; +// x38_firstUnsortedSurface = &*it; +// } } - m_instances.reserve(numInsts); - for (int i = 0; i < numInsts; ++i) - PushNewModelInstance(); +// m_instances.reserve(numInsts); +// for (int i = 0; i < numInsts; ++i) +// PushNewModelInstance(); } -boo::ObjToken CBooModel::ModelInstance::GetBooVBO(const CBooModel& model, - boo::IGraphicsDataFactory::Context& ctx) { - if (model.m_staticVbo) - return model.m_staticVbo.get(); - if (!m_dynamicVbo && model.m_model) { - const CModel& parent = *model.m_model; - m_dynamicVbo = - ctx.newDynamicBuffer(boo::BufferUse::Vertex, parent.m_hmdlMeta.vertStride, parent.m_hmdlMeta.vertCount); - m_dynamicVbo->load(parent.m_dynamicVertexData.get(), parent.m_hmdlMeta.vertStride * parent.m_hmdlMeta.vertCount); - } - return m_dynamicVbo.get(); -} +//boo::ObjToken CBooModel::ModelInstance::GetBooVBO(const CBooModel& model, +// boo::IGraphicsDataFactory::Context& ctx) { +// if (model.m_staticVbo) +// return model.m_staticVbo.get(); +// if (!m_dynamicVbo && model.m_model) { +// const CModel& parent = *model.m_model; +// m_dynamicVbo = +// ctx.newDynamicBuffer(boo::BufferUse::Vertex, parent.m_hmdlMeta.vertStride, parent.m_hmdlMeta.vertCount); +// m_dynamicVbo->load(parent.m_dynamicVertexData.get(), parent.m_hmdlMeta.vertStride * parent.m_hmdlMeta.vertCount); +// } +// return m_dynamicVbo.get(); +//} -GeometryUniformLayout::GeometryUniformLayout(const CModel* model, const MaterialSet* matSet) { - if (model) { - m_skinBankCount = model->m_hmdlMeta.bankCount; - m_weightVecCount = model->m_hmdlMeta.weightCount; - } +//GeometryUniformLayout::GeometryUniformLayout(const CModel* model, const MaterialSet* matSet) { +// if (model) { +// m_skinBankCount = model->m_hmdlMeta.bankCount; +// m_weightVecCount = model->m_hmdlMeta.weightCount; +// } +// +// m_skinOffs.reserve(std::max(size_t(1), m_skinBankCount)); +// m_skinSizes.reserve(std::max(size_t(1), m_skinBankCount)); +// +// m_uvOffs.reserve(matSet->materials.size()); +// m_uvSizes.reserve(matSet->materials.size()); +// +// if (m_skinBankCount) { +// /* Skinned */ +// for (size_t i = 0; i < m_skinBankCount; ++i) { +// size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * (2 * m_weightVecCount * 4 + 3)); +// m_skinOffs.push_back(m_geomBufferSize); +// m_skinSizes.push_back(thisSz); +// m_geomBufferSize += thisSz; +// } +// } else { +// /* Non-Skinned */ +// size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * 3); +// m_skinOffs.push_back(m_geomBufferSize); +// m_skinSizes.push_back(thisSz); +// m_geomBufferSize += thisSz; +// } +// +// /* Animated UV transform matrices */ +// for (const MaterialSet::Material& mat : matSet->materials) { +// (void)mat; +// size_t thisSz = ROUND_UP_256(/*mat.uvAnims.size()*/ 8 * (sizeof(zeus::CMatrix4f) * 2)); +// m_uvOffs.push_back(m_geomBufferSize); +// m_uvSizes.push_back(thisSz); +// m_geomBufferSize += thisSz; +// } +//} - m_skinOffs.reserve(std::max(size_t(1), m_skinBankCount)); - m_skinSizes.reserve(std::max(size_t(1), m_skinBankCount)); +//CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf, +// boo::IGraphicsDataFactory::Context* ctx) { +// OPTICK_EVENT(); +// if (!x40_24_texturesLoaded && !g_DummyTextures) { +// return nullptr; +// } +// +// if (m_instances.size() >= 512) { +// Log.report(logvisor::Fatal, FMT_STRING("Model buffer overflow")); +// } +// +// ModelInstance& newInst = m_instances.emplace_back(); +// +// /* Build geometry uniform buffer if shared not available */ +// boo::ObjToken geomUniformBuf; +// if (sharedLayoutBuf >= 0) { +// geomUniformBuf = m_geomLayout->GetSharedBuffer(sharedLayoutBuf); +// } else { +// geomUniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomLayout->m_geomBufferSize, 1); +// newInst.m_geomUniformBuffer = geomUniformBuf; +// } +// +// /* Lighting and reflection uniforms */ +// size_t uniBufSize = 0; +// +// /* Lighting uniform */ +// size_t lightOff = 0; +// size_t lightSz = 0; +// { +// size_t thisSz = ROUND_UP_256(sizeof(CModelShaders::LightingUniform)); +// lightOff = uniBufSize; +// lightSz = thisSz; +// uniBufSize += thisSz; +// } +// +// /* Surface reflection texmatrix uniform with first identity slot */ +// size_t reflectOff = uniBufSize; +// uniBufSize += 256; +// for (const CBooSurface& surf : *x0_surfaces) { +// const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); +// if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) +// uniBufSize += 256; +// } +// +// /* Allocate resident buffer */ +// m_uniformDataSize = uniBufSize; +// newInst.m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1); +// +// const std::array, 4> bufs{ +// geomUniformBuf.get(), +// geomUniformBuf.get(), +// newInst.m_uniformBuffer.get(), +// newInst.m_uniformBuffer.get(), +// }; +// +// /* Binding for each surface */ +// newInst.m_shaderDataBindings.reserve(x0_surfaces->size()); +// +// std::array thisOffs; +// std::array thisSizes; +// +// static constexpr std::array stages{ +// boo::PipelineStage::Vertex, +// boo::PipelineStage::Vertex, +// boo::PipelineStage::Fragment, +// boo::PipelineStage::Vertex, +// }; +// +// /* Enumerate surfaces and build data bindings */ +// size_t curReflect = reflectOff + 256; +// for (const CBooSurface& surf : *x0_surfaces) { +// const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); +// +// std::array, 12> texs{ +// g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), +// g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), +// g_Renderer->m_whiteTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->x220_sphereRamp.get(), +// g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(), +// }; +// if (!g_DummyTextures) { +// for (const auto& ch : mat.chunks) { +// if (const auto* const pass = ch.get_if()) { +// auto search = x1c_textures.find(pass->texId.toUint32()); +// boo::ObjToken btex; +// if (search != x1c_textures.cend() && (btex = search->second.GetObj()->GetBooTexture())) { +// texs[MaterialSet::Material::TexMapIdx(pass->type)] = btex; +// } +// } else if (const auto* const pass = ch.get_if()) { +// boo::ObjToken btex = g_Renderer->GetColorTexture(zeus::CColor(pass->color)); +// texs[MaterialSet::Material::TexMapIdx(pass->type)] = btex; +// } +// } +// } +// +// if (m_geomLayout->m_skinBankCount) { +// thisOffs[0] = m_geomLayout->m_skinOffs[surf.m_data.skinMtxBankIdx]; +// thisSizes[0] = m_geomLayout->m_skinSizes[surf.m_data.skinMtxBankIdx]; +// } else { +// thisOffs[0] = 0; +// thisSizes[0] = 256; +// } +// +// thisOffs[1] = m_geomLayout->m_uvOffs[surf.m_data.matIdx]; +// thisSizes[1] = m_geomLayout->m_uvSizes[surf.m_data.matIdx]; +// +// thisOffs[2] = lightOff; +// thisSizes[2] = lightSz; +// +// bool useReflection = mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye(); +// if (useReflection) { +// if (g_Renderer->x14c_reflectionTex) +// texs[11] = g_Renderer->x14c_reflectionTex.get(); +// thisOffs[3] = curReflect; +// curReflect += 256; +// } else { +// thisOffs[3] = reflectOff; +// } +// thisSizes[3] = 256; +// +// const CModelShaders::ShaderPipelines& pipelines = m_pipelines->at(surf.m_data.matIdx); +// +// std::vector>& extendeds = newInst.m_shaderDataBindings.emplace_back(); +// extendeds.reserve(pipelines->size()); +// +// EExtendedShader idx{}; +// for (const auto& pipeline : *pipelines) { +// if (idx == EExtendedShader::ThermalModel || idx == EExtendedShader::ThermalModelNoZTestNoZWrite || +// idx == EExtendedShader::ThermalStatic || idx == EExtendedShader::ThermalStaticNoZWrite) { +// texs[8] = g_Renderer->x220_sphereRamp.get(); +// } else if (idx == EExtendedShader::MorphBallShadow) { +// texs[8] = g_Renderer->m_ballShadowId.get(); +// texs[9] = g_Renderer->x220_sphereRamp.get(); +// texs[10] = g_Renderer->m_ballFade.get(); +// } else if (idx == EExtendedShader::WorldShadow || idx == EExtendedShader::LightingCubeReflectionWorldShadow) { +// if (g_shadowMap) +// texs[8] = g_shadowMap; +// else +// texs[8] = g_Renderer->x220_sphereRamp.get(); +// } else if (idx == EExtendedShader::Disintegrate) { +// if (g_disintegrateTexture) +// texs[8] = g_disintegrateTexture; +// else +// texs[8] = g_Renderer->x220_sphereRamp.get(); +// } else if (hecl::com_cubemaps->toBoolean() && (idx == EExtendedShader::LightingCubeReflection || +// idx == EExtendedShader::LightingCubeReflectionWorldShadow)) { +// if (m_lastDrawnReflectionCube) +// texs[11] = m_lastDrawnReflectionCube.get(); +// else +// texs[11] = g_Renderer->x220_sphereRamp.get(); +// } +// extendeds.push_back(ctx.newShaderDataBinding( +// pipeline, newInst.GetBooVBO(*this, ctx), nullptr, m_staticIbo.get(), bufs.size(), bufs.data(), +// stages.data(), thisOffs.data(), thisSizes.data(), texs.size(), texs.data(), nullptr, nullptr)); +// idx = EExtendedShader(size_t(idx) + 1); +// } +// } +// +// return &newInst; +//} - m_uvOffs.reserve(matSet->materials.size()); - m_uvSizes.reserve(matSet->materials.size()); - - if (m_skinBankCount) { - /* Skinned */ - for (size_t i = 0; i < m_skinBankCount; ++i) { - size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * (2 * m_weightVecCount * 4 + 3)); - m_skinOffs.push_back(m_geomBufferSize); - m_skinSizes.push_back(thisSz); - m_geomBufferSize += thisSz; - } - } else { - /* Non-Skinned */ - size_t thisSz = ROUND_UP_256(sizeof(zeus::CMatrix4f) * 3); - m_skinOffs.push_back(m_geomBufferSize); - m_skinSizes.push_back(thisSz); - m_geomBufferSize += thisSz; - } - - /* Animated UV transform matrices */ - for (const MaterialSet::Material& mat : matSet->materials) { - (void)mat; - size_t thisSz = ROUND_UP_256(/*mat.uvAnims.size()*/ 8 * (sizeof(zeus::CMatrix4f) * 2)); - m_uvOffs.push_back(m_geomBufferSize); - m_uvSizes.push_back(thisSz); - m_geomBufferSize += thisSz; - } -} - -CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf, - boo::IGraphicsDataFactory::Context* ctx) { - OPTICK_EVENT(); - if (!x40_24_texturesLoaded && !g_DummyTextures) { - return nullptr; - } - - if (m_instances.size() >= 512) { - Log.report(logvisor::Fatal, FMT_STRING("Model buffer overflow")); - } - - ModelInstance& newInst = m_instances.emplace_back(); - - auto withContext = [&](boo::IGraphicsDataFactory::Context& ctx) { - /* Build geometry uniform buffer if shared not available */ - boo::ObjToken geomUniformBuf; - if (sharedLayoutBuf >= 0) { - geomUniformBuf = m_geomLayout->GetSharedBuffer(sharedLayoutBuf); - } else { - geomUniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomLayout->m_geomBufferSize, 1); - newInst.m_geomUniformBuffer = geomUniformBuf; - } - - /* Lighting and reflection uniforms */ - size_t uniBufSize = 0; - - /* Lighting uniform */ - size_t lightOff = 0; - size_t lightSz = 0; - { - size_t thisSz = ROUND_UP_256(sizeof(CModelShaders::LightingUniform)); - lightOff = uniBufSize; - lightSz = thisSz; - uniBufSize += thisSz; - } - - /* Surface reflection texmatrix uniform with first identity slot */ - size_t reflectOff = uniBufSize; - uniBufSize += 256; - for (const CBooSurface& surf : *x0_surfaces) { - const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); - if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) - uniBufSize += 256; - } - - /* Allocate resident buffer */ - m_uniformDataSize = uniBufSize; - newInst.m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1); - - const std::array, 4> bufs{ - geomUniformBuf.get(), - geomUniformBuf.get(), - newInst.m_uniformBuffer.get(), - newInst.m_uniformBuffer.get(), - }; - - /* Binding for each surface */ - newInst.m_shaderDataBindings.reserve(x0_surfaces->size()); - - std::array thisOffs; - std::array thisSizes; - - static constexpr std::array stages{ - boo::PipelineStage::Vertex, - boo::PipelineStage::Vertex, - boo::PipelineStage::Fragment, - boo::PipelineStage::Vertex, - }; - - /* Enumerate surfaces and build data bindings */ - size_t curReflect = reflectOff + 256; - for (const CBooSurface& surf : *x0_surfaces) { - const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); - - std::array, 12> texs{ - g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), - g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->m_clearTexture.get(), - g_Renderer->m_whiteTexture.get(), g_Renderer->m_clearTexture.get(), g_Renderer->x220_sphereRamp.get(), - g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(), g_Renderer->x220_sphereRamp.get(), - }; - if (!g_DummyTextures) { - for (const auto& ch : mat.chunks) { - if (const auto* const pass = ch.get_if()) { - auto search = x1c_textures.find(pass->texId.toUint32()); - boo::ObjToken btex; - if (search != x1c_textures.cend() && (btex = search->second.GetObj()->GetBooTexture())) { - texs[MaterialSet::Material::TexMapIdx(pass->type)] = btex; - } - } else if (const auto* const pass = ch.get_if()) { - boo::ObjToken btex = g_Renderer->GetColorTexture(zeus::CColor(pass->color)); - texs[MaterialSet::Material::TexMapIdx(pass->type)] = btex; - } - } - } - - if (m_geomLayout->m_skinBankCount) { - thisOffs[0] = m_geomLayout->m_skinOffs[surf.m_data.skinMtxBankIdx]; - thisSizes[0] = m_geomLayout->m_skinSizes[surf.m_data.skinMtxBankIdx]; - } else { - thisOffs[0] = 0; - thisSizes[0] = 256; - } - - thisOffs[1] = m_geomLayout->m_uvOffs[surf.m_data.matIdx]; - thisSizes[1] = m_geomLayout->m_uvSizes[surf.m_data.matIdx]; - - thisOffs[2] = lightOff; - thisSizes[2] = lightSz; - - bool useReflection = mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye(); - if (useReflection) { - if (g_Renderer->x14c_reflectionTex) - texs[11] = g_Renderer->x14c_reflectionTex.get(); - thisOffs[3] = curReflect; - curReflect += 256; - } else { - thisOffs[3] = reflectOff; - } - thisSizes[3] = 256; - - const CModelShaders::ShaderPipelines& pipelines = m_pipelines->at(surf.m_data.matIdx); - - std::vector>& extendeds = newInst.m_shaderDataBindings.emplace_back(); - extendeds.reserve(pipelines->size()); - - EExtendedShader idx{}; - for (const auto& pipeline : *pipelines) { - if (idx == EExtendedShader::ThermalModel || idx == EExtendedShader::ThermalModelNoZTestNoZWrite || - idx == EExtendedShader::ThermalStatic || idx == EExtendedShader::ThermalStaticNoZWrite) { - texs[8] = g_Renderer->x220_sphereRamp.get(); - } else if (idx == EExtendedShader::MorphBallShadow) { - texs[8] = g_Renderer->m_ballShadowId.get(); - texs[9] = g_Renderer->x220_sphereRamp.get(); - texs[10] = g_Renderer->m_ballFade.get(); - } else if (idx == EExtendedShader::WorldShadow || idx == EExtendedShader::LightingCubeReflectionWorldShadow) { - if (g_shadowMap) - texs[8] = g_shadowMap; - else - texs[8] = g_Renderer->x220_sphereRamp.get(); - } else if (idx == EExtendedShader::Disintegrate) { - if (g_disintegrateTexture) - texs[8] = g_disintegrateTexture; - else - texs[8] = g_Renderer->x220_sphereRamp.get(); - } else if (hecl::com_cubemaps->toBoolean() && (idx == EExtendedShader::LightingCubeReflection || - idx == EExtendedShader::LightingCubeReflectionWorldShadow)) { - if (m_lastDrawnReflectionCube) - texs[11] = m_lastDrawnReflectionCube.get(); - else - texs[11] = g_Renderer->x220_sphereRamp.get(); - } - extendeds.push_back(ctx.newShaderDataBinding( - pipeline, newInst.GetBooVBO(*this, ctx), nullptr, m_staticIbo.get(), bufs.size(), bufs.data(), - stages.data(), thisOffs.data(), thisSizes.data(), texs.size(), texs.data(), nullptr, nullptr)); - idx = EExtendedShader(size_t(idx) + 1); - } - } - return true; - }; - - if (ctx) { - withContext(*ctx); - } else { - CGraphics::CommitResources(withContext BooTrace); - } - return &newInst; -} - -void CBooModel::MakeTexturesFromMats(const MaterialSet& matSet, - std::unordered_map>& toksOut, - IObjectStore& store) { - for (const auto& mat : matSet.materials) { - for (const auto& chunk : mat.chunks) { - if (const auto* const pass = chunk.get_if()) { - toksOut.emplace(std::make_pair(pass->texId.toUint32(), store.GetObj({SBIG('TXTR'), pass->texId.toUint32()}))); - } - } - } -} +//void CBooModel::MakeTexturesFromMats(const MaterialSet& matSet, +// std::unordered_map>& toksOut, +// IObjectStore& store) { +// for (const auto& mat : matSet.materials) { +// for (const auto& chunk : mat.chunks) { +// if (const auto* const pass = chunk.get_if()) { +// toksOut.emplace(std::make_pair(pass->texId.toUint32(), store.GetObj({SBIG('TXTR'), pass->texId.toUint32()}))); +// } +// } +// } +//} void CBooModel::MakeTexturesFromMats(std::unordered_map>& toksOut, IObjectStore& store) { - MakeTexturesFromMats(*x4_matSet, toksOut, store); +// MakeTexturesFromMats(*x4_matSet, toksOut, store); } void CBooModel::ActivateLights(const std::vector& lights) { m_lightingData.ActivateLights(lights); } @@ -443,28 +436,12 @@ void CBooModel::DisableAllLights() { } void CBooModel::RemapMaterialData(SShader& shader) { - if (!shader.m_geomLayout) - return; - x4_matSet = &shader.m_matSet; - m_geomLayout = &*shader.m_geomLayout; - m_matSetIdx = shader.m_matSetIdx; + // TODO what is this checking? +// if (!shader.m_geomLayout) +// return; +// x4_matSet = &shader.m_matSet; x1c_textures = shader.x0_textures; - m_pipelines = &shader.m_shaders; x40_24_texturesLoaded = false; - m_instances.clear(); -} - -void CBooModel::RemapMaterialData(SShader& shader, - const std::unordered_map& pipelines) { - if (!shader.m_geomLayout) - return; - x4_matSet = &shader.m_matSet; - m_geomLayout = &*shader.m_geomLayout; - m_matSetIdx = shader.m_matSetIdx; - x1c_textures = shader.x0_textures; - m_pipelines = &pipelines; - x40_24_texturesLoaded = false; - m_instances.clear(); } bool CBooModel::TryLockTextures() { @@ -477,19 +454,20 @@ bool CBooModel::TryLockTextures() { } } - if (allLoad) { - for (const auto& pipeline : *m_pipelines) { - for (const auto& subpipeline : *pipeline.second) { - if (!subpipeline->isReady()) { - allLoad = false; - break; - } - } - if (!allLoad) { - break; - } - } - } + // TODO +// if (allLoad) { +// for (const auto& pipeline : *m_pipelines) { +// for (const auto& subpipeline : *pipeline.second) { +// if (!subpipeline->isReady()) { +// allLoad = false; +// break; +// } +// } +// if (!allLoad) { +// break; +// } +// } +// } x40_24_texturesLoaded = allLoad; } @@ -498,7 +476,7 @@ bool CBooModel::TryLockTextures() { } void CBooModel::UnlockTextures() { - m_instances.clear(); +// m_instances.clear(); for (auto& tex : x1c_textures) { tex.second.Unlock(); @@ -571,92 +549,90 @@ void CBooModel::DrawSurfaces(const CModelFlags& flags) const { } } -static EExtendedShader ResolveExtendedShader(const MaterialSet::Material& data, const CModelFlags& flags) { - bool noZWrite = flags.m_noZWrite || !data.flags.depthWrite(); - - /* Ensure cubemap extension shaders fall back to non-cubemap equivalents if necessary */ - EExtendedShader intermediateExtended = flags.m_extendedShader; - if (!hecl::com_cubemaps->toBoolean() || g_Renderer->IsThermalVisorHotPass() || g_Renderer->IsThermalVisorActive()) { - if (intermediateExtended == EExtendedShader::LightingCubeReflection) - intermediateExtended = EExtendedShader::Lighting; - else if (intermediateExtended == EExtendedShader::LightingCubeReflectionWorldShadow) - intermediateExtended = EExtendedShader::WorldShadow; - } - - EExtendedShader extended = EExtendedShader::Flat; - if (intermediateExtended == EExtendedShader::Lighting) { - /* Transform lighting into thermal if the thermal visor is active */ - if (g_Renderer->IsThermalVisorHotPass()) - return flags.m_noZTest ? EExtendedShader::LightingAlphaWriteNoZTestNoZWrite - : (noZWrite ? EExtendedShader::ThermalStaticNoZWrite : EExtendedShader::ThermalStatic); - else if (g_Renderer->IsThermalVisorActive()) - return EExtendedShader::ThermalCold; - if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Opaque) { - /* Override shader if originally opaque (typical for FRME models) */ - if (flags.x0_blendMode > 6) { - if (flags.m_depthGreater) - extended = EExtendedShader::ForcedAdditiveNoZWriteDepthGreater; - else - extended = - flags.m_noCull - ? (noZWrite ? EExtendedShader::ForcedAdditiveNoCullNoZWrite : EExtendedShader::ForcedAdditiveNoCull) - : (noZWrite ? EExtendedShader::ForcedAdditiveNoZWrite : EExtendedShader::ForcedAdditive); - } else if (flags.x0_blendMode > 4) { - extended = flags.m_noCull - ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) - : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::ForcedAlpha); - } else { - extended = flags.m_noCull - ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) - : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::Lighting); - } - } else if (flags.m_noCull && noZWrite) { - /* Substitute no-cull,no-zwrite pipeline if available */ - if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive) - extended = EExtendedShader::ForcedAdditiveNoCullNoZWrite; - else - extended = EExtendedShader::ForcedAlphaNoCullNoZWrite; - } else if (flags.m_noCull) { - /* Substitute no-cull pipeline if available */ - if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive) - extended = EExtendedShader::ForcedAdditiveNoCull; - else - extended = EExtendedShader::ForcedAlphaNoCull; - } else if (noZWrite) { - /* Substitute no-zwrite pipeline if available */ - if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive) - extended = EExtendedShader::ForcedAdditiveNoZWrite; - else - extended = EExtendedShader::ForcedAlphaNoZWrite; - } else { - extended = EExtendedShader::Lighting; - } - } else if (intermediateExtended == EExtendedShader::ThermalModel) { - extended = flags.m_noZTest ? EExtendedShader::ThermalModelNoZTestNoZWrite : EExtendedShader::ThermalModel; - } else if (intermediateExtended < EExtendedShader::MAX) { - extended = intermediateExtended; - } - - return extended; -} +//static EExtendedShader ResolveExtendedShader(const MaterialSet::Material& data, const CModelFlags& flags) { +// bool noZWrite = flags.m_noZWrite || !data.flags.depthWrite(); +// +// /* Ensure cubemap extension shaders fall back to non-cubemap equivalents if necessary */ +// EExtendedShader intermediateExtended = flags.m_extendedShader; +// if (!com_cubemaps->toBoolean() || g_Renderer->IsThermalVisorHotPass() || g_Renderer->IsThermalVisorActive()) { +// if (intermediateExtended == EExtendedShader::LightingCubeReflection) +// intermediateExtended = EExtendedShader::Lighting; +// else if (intermediateExtended == EExtendedShader::LightingCubeReflectionWorldShadow) +// intermediateExtended = EExtendedShader::WorldShadow; +// } +// +// EExtendedShader extended = EExtendedShader::Flat; +// if (intermediateExtended == EExtendedShader::Lighting) { +// /* Transform lighting into thermal if the thermal visor is active */ +// if (g_Renderer->IsThermalVisorHotPass()) +// return flags.m_noZTest ? EExtendedShader::LightingAlphaWriteNoZTestNoZWrite +// : (noZWrite ? EExtendedShader::ThermalStaticNoZWrite : EExtendedShader::ThermalStatic); +// else if (g_Renderer->IsThermalVisorActive()) +// return EExtendedShader::ThermalCold; +// if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Opaque) { +// /* Override shader if originally opaque (typical for FRME models) */ +// if (flags.x0_blendMode > 6) { +// if (flags.m_depthGreater) +// extended = EExtendedShader::ForcedAdditiveNoZWriteDepthGreater; +// else +// extended = +// flags.m_noCull +// ? (noZWrite ? EExtendedShader::ForcedAdditiveNoCullNoZWrite : EExtendedShader::ForcedAdditiveNoCull) +// : (noZWrite ? EExtendedShader::ForcedAdditiveNoZWrite : EExtendedShader::ForcedAdditive); +// } else if (flags.x0_blendMode > 4) { +// extended = flags.m_noCull +// ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) +// : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::ForcedAlpha); +// } else { +// extended = flags.m_noCull +// ? (noZWrite ? EExtendedShader::ForcedAlphaNoCullNoZWrite : EExtendedShader::ForcedAlphaNoCull) +// : (noZWrite ? EExtendedShader::ForcedAlphaNoZWrite : EExtendedShader::Lighting); +// } +// } else if (flags.m_noCull && noZWrite) { +// /* Substitute no-cull,no-zwrite pipeline if available */ +// if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive) +// extended = EExtendedShader::ForcedAdditiveNoCullNoZWrite; +// else +// extended = EExtendedShader::ForcedAlphaNoCullNoZWrite; +// } else if (flags.m_noCull) { +// /* Substitute no-cull pipeline if available */ +// if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive) +// extended = EExtendedShader::ForcedAdditiveNoCull; +// else +// extended = EExtendedShader::ForcedAlphaNoCull; +// } else if (noZWrite) { +// /* Substitute no-zwrite pipeline if available */ +// if (data.blendMode == MaterialSet::Material::BlendMaterial::BlendMode::Additive) +// extended = EExtendedShader::ForcedAdditiveNoZWrite; +// else +// extended = EExtendedShader::ForcedAlphaNoZWrite; +// } else { +// extended = EExtendedShader::Lighting; +// } +// } else if (intermediateExtended == EExtendedShader::ThermalModel) { +// extended = flags.m_noZTest ? EExtendedShader::ThermalModelNoZTestNoZWrite : EExtendedShader::ThermalModel; +// } else if (intermediateExtended < EExtendedShader::MAX) { +// extended = intermediateExtended; +// } +// +// return extended; +//} void CBooModel::DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const { - // if (m_uniUpdateCount == 0) - // Log.report(logvisor::Fatal, FMT_STRING("UpdateUniformData() not called")); - if (m_uniUpdateCount == 0 || m_uniUpdateCount > m_instances.size()) - return; - const ModelInstance& inst = m_instances[m_uniUpdateCount - 1]; - - const MaterialSet::Material& data = GetMaterialByIndex(surf.m_data.matIdx); - if (data.flags.shadowOccluderMesh() && !g_DrawingOccluders) - return; - - const std::vector>& extendeds = inst.m_shaderDataBindings[surf.selfIdx]; - EExtendedShader extended = ResolveExtendedShader(data, flags); - - boo::ObjToken binding = extendeds[size_t(extended)]; - CGraphics::SetShaderDataBinding(binding); - CGraphics::DrawArrayIndexed(surf.m_data.idxStart, surf.m_data.idxCount); +// if (m_uniUpdateCount == 0 || m_uniUpdateCount > m_instances.size()) +// return; +// const ModelInstance& inst = m_instances[m_uniUpdateCount - 1]; +// +// const MaterialSet::Material& data = GetMaterialByIndex(surf.m_data.matIdx); +// if (data.flags.shadowOccluderMesh() && !g_DrawingOccluders) +// return; +// +// const std::vector>& extendeds = inst.m_shaderDataBindings[surf.selfIdx]; +// EExtendedShader extended = ResolveExtendedShader(data, flags); +// +// boo::ObjToken binding = extendeds[size_t(extended)]; +// CGraphics::SetShaderDataBinding(binding); +// CGraphics::DrawArrayIndexed(surf.m_data.idxStart, surf.m_data.idxCount); } void CBooModel::WarmupDrawSurfaces() const { @@ -674,423 +650,422 @@ void CBooModel::WarmupDrawSurfaces() const { } void CBooModel::WarmupDrawSurface(const CBooSurface& surf) const { - if (m_uniUpdateCount > m_instances.size()) - return; - const ModelInstance& inst = m_instances[m_uniUpdateCount - 1]; - - for (const auto& binding : inst.m_shaderDataBindings[surf.selfIdx]) { - CGraphics::SetShaderDataBinding(binding); - CGraphics::DrawArrayIndexed(surf.m_data.idxStart, std::min(u32(3), surf.m_data.idxCount)); - } +// if (m_uniUpdateCount > m_instances.size()) +// return; +// const ModelInstance& inst = m_instances[m_uniUpdateCount - 1]; +// +// for (const auto& binding : inst.m_shaderDataBindings[surf.selfIdx]) { +// CGraphics::SetShaderDataBinding(binding); +// CGraphics::DrawArrayIndexed(surf.m_data.idxStart, std::min(u32(3), surf.m_data.idxCount)); +// } } -void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const MaterialSet::Material::PASS& anim) { - using UVAnimType = MaterialSet::Material::BlendMaterial::UVAnimType; - if (anim.uvAnimType == UVAnimType::Invalid) - return; - zeus::CMatrix4f& texMtxOut = reinterpret_cast(*bufOut); - zeus::CMatrix4f& postMtxOut = reinterpret_cast(*(bufOut + sizeof(zeus::CMatrix4f))); - texMtxOut = zeus::CMatrix4f(); - postMtxOut = zeus::CMatrix4f(); - switch (anim.uvAnimType) { - case UVAnimType::MvInvNoTranslation: { - texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); - texMtxOut[3].w() = 1.f; - postMtxOut[0].x() = 0.5f; - postMtxOut[1].y() = 0.5f; - postMtxOut[3].x() = 0.5f; - postMtxOut[3].y() = 0.5f; - break; - } - case UVAnimType::MvInv: { - texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); - texMtxOut[3] = CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix.origin; - texMtxOut[3].w() = 1.f; - postMtxOut[0].x() = 0.5f; - postMtxOut[1].y() = 0.5f; - postMtxOut[3].x() = 0.5f; - postMtxOut[3].y() = 0.5f; - break; - } - case UVAnimType::Scroll: { - texMtxOut[3].x() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[2] + anim.uvAnimParms[0]; - texMtxOut[3].y() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[3] + anim.uvAnimParms[1]; - break; - } - case UVAnimType::Rotation: { - float angle = CGraphics::GetSecondsMod900() * anim.uvAnimParms[1] + anim.uvAnimParms[0]; - float acos = std::cos(angle); - float asin = std::sin(angle); - texMtxOut[0].x() = acos; - texMtxOut[0].y() = asin; - texMtxOut[1].x() = -asin; - texMtxOut[1].y() = acos; - texMtxOut[3].x() = (1.0f - (acos - asin)) * 0.5f; - texMtxOut[3].y() = (1.0f - (asin + acos)) * 0.5f; - break; - } - case UVAnimType::HStrip: { - float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900()); - texMtxOut[3].x() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2]; - break; - } - case UVAnimType::VStrip: { - float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900()); - texMtxOut[3].y() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2]; - break; - } - case UVAnimType::Model: { - texMtxOut = CGraphics::g_GXModelMatrix.toMatrix4f(); - texMtxOut[3] = zeus::CVector4f(0.f, 0.f, 0.f, 1.f); - postMtxOut[0].x() = 0.5f; - postMtxOut[1].y() = 0.f; - postMtxOut[2].y() = 0.5f; - postMtxOut[3].x() = CGraphics::g_GXModelMatrix.origin.x() * 0.05f; - postMtxOut[3].y() = CGraphics::g_GXModelMatrix.origin.y() * 0.05f; - break; - } - case UVAnimType::CylinderEnvironment: { - texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); +//void CBooModel::UVAnimationBuffer::ProcessAnimation(u8*& bufOut, const MaterialSet::Material::PASS& anim) { +// using UVAnimType = MaterialSet::Material::BlendMaterial::UVAnimType; +// if (anim.uvAnimType == UVAnimType::Invalid) +// return; +// zeus::CMatrix4f& texMtxOut = reinterpret_cast(*bufOut); +// zeus::CMatrix4f& postMtxOut = reinterpret_cast(*(bufOut + sizeof(zeus::CMatrix4f))); +// texMtxOut = zeus::CMatrix4f(); +// postMtxOut = zeus::CMatrix4f(); +// switch (anim.uvAnimType) { +// case UVAnimType::MvInvNoTranslation: { +// texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); +// texMtxOut[3].w() = 1.f; +// postMtxOut[0].x() = 0.5f; +// postMtxOut[1].y() = 0.5f; +// postMtxOut[3].x() = 0.5f; +// postMtxOut[3].y() = 0.5f; +// break; +// } +// case UVAnimType::MvInv: { +// texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); +// texMtxOut[3] = CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix.origin; +// texMtxOut[3].w() = 1.f; +// postMtxOut[0].x() = 0.5f; +// postMtxOut[1].y() = 0.5f; +// postMtxOut[3].x() = 0.5f; +// postMtxOut[3].y() = 0.5f; +// break; +// } +// case UVAnimType::Scroll: { +// texMtxOut[3].x() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[2] + anim.uvAnimParms[0]; +// texMtxOut[3].y() = CGraphics::GetSecondsMod900() * anim.uvAnimParms[3] + anim.uvAnimParms[1]; +// break; +// } +// case UVAnimType::Rotation: { +// float angle = CGraphics::GetSecondsMod900() * anim.uvAnimParms[1] + anim.uvAnimParms[0]; +// float acos = std::cos(angle); +// float asin = std::sin(angle); +// texMtxOut[0].x() = acos; +// texMtxOut[0].y() = asin; +// texMtxOut[1].x() = -asin; +// texMtxOut[1].y() = acos; +// texMtxOut[3].x() = (1.0f - (acos - asin)) * 0.5f; +// texMtxOut[3].y() = (1.0f - (asin + acos)) * 0.5f; +// break; +// } +// case UVAnimType::HStrip: { +// float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900()); +// texMtxOut[3].x() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2]; +// break; +// } +// case UVAnimType::VStrip: { +// float value = anim.uvAnimParms[0] * anim.uvAnimParms[2] * (anim.uvAnimParms[3] + CGraphics::GetSecondsMod900()); +// texMtxOut[3].y() = std::trunc(anim.uvAnimParms[1] * fmod(value, 1.0f)) * anim.uvAnimParms[2]; +// break; +// } +// case UVAnimType::Model: { +// texMtxOut = CGraphics::g_GXModelMatrix.toMatrix4f(); +// texMtxOut[3] = zeus::CVector4f(0.f, 0.f, 0.f, 1.f); +// postMtxOut[0].x() = 0.5f; +// postMtxOut[1].y() = 0.f; +// postMtxOut[2].y() = 0.5f; +// postMtxOut[3].x() = CGraphics::g_GXModelMatrix.origin.x() * 0.05f; +// postMtxOut[3].y() = CGraphics::g_GXModelMatrix.origin.y() * 0.05f; +// break; +// } +// case UVAnimType::CylinderEnvironment: { +// texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); +// +// const zeus::CVector3f& viewOrigin = CGraphics::g_ViewMatrix.origin; +// float xy = (viewOrigin.x() + viewOrigin.y()) * 0.025f * anim.uvAnimParms[1]; +// xy = (xy - std::trunc(xy)); +// float z = (viewOrigin.z()) * 0.05f * anim.uvAnimParms[1]; +// z = (z - std::trunc(z)); +// +// float halfA = anim.uvAnimParms[0] * 0.5f; +// +// postMtxOut = +// zeus::CTransform(zeus::CMatrix3f(halfA, 0.0, 0.0, 0.0, 0.0, halfA, 0.0, 0.0, 0.0), zeus::CVector3f(xy, z, 1.0)) +// .toMatrix4f(); +// break; +// } +// default: +// break; +// } +// bufOut += sizeof(zeus::CMatrix4f) * 2; +//} +// +//void CBooModel::UVAnimationBuffer::PadOutBuffer(u8*& bufStart, u8*& bufOut) { +// bufOut = bufStart + ROUND_UP_256(bufOut - bufStart); +//} +// +//void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, +// const CBooModel* parent) { +// u8* start = bufOut; +// +// if (flags.m_extendedShader == EExtendedShader::MorphBallShadow) { +// /* Special matrices for MorphBall shadow rendering */ +// zeus::CMatrix4f texMtx = (zeus::CTransform::Scale(1.f / (flags.mbShadowBox.max - flags.mbShadowBox.min)) * +// zeus::CTransform::Translate(-flags.mbShadowBox.min) * CGraphics::g_GXModelMatrix) +// .toMatrix4f(); +// for (const MaterialSet::Material& mat : matSet->materials) { +// (void)mat; +// std::array* mtxs = reinterpret_cast*>(bufOut); +// mtxs[0][0] = texMtx; +// mtxs[0][1] = MBShadowPost0; +// mtxs[1][0] = texMtx; +// mtxs[1][1] = MBShadowPost1; +// bufOut += sizeof(zeus::CMatrix4f) * 2 * 8; +// PadOutBuffer(start, bufOut); +// } +// return; +// } else if (flags.m_extendedShader == EExtendedShader::Disintegrate) { +// assert(parent != nullptr && "Parent CBooModel not set"); +// zeus::CTransform xf = zeus::CTransform::RotateX(-zeus::degToRad(45.f)); +// zeus::CAABox aabb = parent->GetAABB().getTransformedAABox(xf); +// xf = zeus::CTransform::Scale(5.f / (aabb.max - aabb.min)) * zeus::CTransform::Translate(-aabb.min) * xf; +// zeus::CMatrix4f texMtx = xf.toMatrix4f(); +// zeus::CMatrix4f post0 = DisintegratePost; +// post0[3].x() = flags.addColor.a(); +// post0[3].y() = 6.f * -(1.f - flags.addColor.a()) + 1.f; +// zeus::CMatrix4f post1 = DisintegratePost; +// post1[3].x() = -0.85f * flags.addColor.a() - 0.15f; +// post1[3].y() = float(post0[3].y()); +// /* Special matrices for disintegration rendering */ +// for (const MaterialSet::Material& mat : matSet->materials) { +// (void)mat; +// std::array* mtxs = reinterpret_cast*>(bufOut); +// mtxs[0][0] = texMtx; +// mtxs[0][1] = post0; +// mtxs[1][0] = texMtx; +// mtxs[1][1] = post1; +// bufOut += sizeof(zeus::CMatrix4f) * 2 * 8; +// PadOutBuffer(start, bufOut); +// } +// return; +// } +// +// std::optional> specialMtxOut; +// if (flags.m_extendedShader == EExtendedShader::ThermalModel || +// flags.m_extendedShader == EExtendedShader::ThermalModelNoZTestNoZWrite || +// flags.m_extendedShader == EExtendedShader::ThermalStatic || +// flags.m_extendedShader == EExtendedShader::ThermalStaticNoZWrite) { +// /* Special Mode0 matrix for exclusive Thermal Visor use */ +// specialMtxOut.emplace(); +// +// zeus::CMatrix4f& texMtxOut = (*specialMtxOut)[0]; +// texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); +// texMtxOut[3].zeroOut(); +// texMtxOut[3].w() = 1.f; +// +// zeus::CMatrix4f& postMtxOut = (*specialMtxOut)[1]; +// postMtxOut[0].x() = 0.5f; +// postMtxOut[1].y() = 0.5f; +// postMtxOut[3].x() = 0.5f; +// postMtxOut[3].y() = 0.5f; +// } else if (flags.m_extendedShader == EExtendedShader::WorldShadow || +// flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) { +// /* Special matrix for mapping world shadow */ +// specialMtxOut.emplace(); +// +// zeus::CMatrix4f mat = g_shadowTexXf.toMatrix4f(); +// zeus::CMatrix4f& texMtxOut = (*specialMtxOut)[0]; +// texMtxOut[0][0] = float(mat[0][0]); +// texMtxOut[1][0] = float(mat[1][0]); +// texMtxOut[2][0] = float(mat[2][0]); +// texMtxOut[3][0] = float(mat[3][0]); +// texMtxOut[0][1] = float(mat[0][2]); +// texMtxOut[1][1] = float(mat[1][2]); +// texMtxOut[2][1] = float(mat[2][2]); +// texMtxOut[3][1] = float(mat[3][2]); +// } +// +// for (const MaterialSet::Material& mat : matSet->materials) { +// if (specialMtxOut) { +// std::array* mtxs = reinterpret_cast*>(bufOut); +// mtxs[7][0] = (*specialMtxOut)[0]; +// mtxs[7][1] = (*specialMtxOut)[1]; +// } +// u8* bufOrig = bufOut; +// for (const auto& chunk : mat.chunks) { +// if (const auto* const pass = chunk.get_if()) { +// ProcessAnimation(bufOut, *pass); +// } +// } +// bufOut = bufOrig + sizeof(zeus::CMatrix4f) * 2 * 8; +// PadOutBuffer(start, bufOut); +// } +//} - const zeus::CVector3f& viewOrigin = CGraphics::g_ViewMatrix.origin; - float xy = (viewOrigin.x() + viewOrigin.y()) * 0.025f * anim.uvAnimParms[1]; - xy = (xy - std::trunc(xy)); - float z = (viewOrigin.z()) * 0.05f * anim.uvAnimParms[1]; - z = (z - std::trunc(z)); +//void GeometryUniformLayout::Update(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose, +// const MaterialSet* matSet, const boo::ObjToken& buf, +// const CBooModel* parent) const { +// u8* dataOut = reinterpret_cast(buf->map(m_geomBufferSize)); +// u8* dataCur = dataOut; +// +// if (m_skinBankCount) { +// /* Skinned */ +// std::vector bankTransforms; +// size_t weightCount = m_weightVecCount * 4; +// bankTransforms.reserve(weightCount); +// for (size_t i = 0; i < m_skinBankCount; ++i) { +// if (cskr && pose) { +// cskr->GetBankTransforms(bankTransforms, *pose, i); +// +// for (size_t w = 0; w < weightCount; ++w) { +// zeus::CMatrix4f& obj = reinterpret_cast(*dataCur); +// if (w >= bankTransforms.size()) +// obj = zeus::CMatrix4f(); +// else +// obj = bankTransforms[w]->toMatrix4f(); +// dataCur += sizeof(zeus::CMatrix4f); +// } +// for (size_t w = 0; w < weightCount; ++w) { +// zeus::CMatrix4f& objInv = reinterpret_cast(*dataCur); +// if (w >= bankTransforms.size()) +// objInv = zeus::CMatrix4f(); +// else +// objInv = bankTransforms[w]->basis; +// dataCur += sizeof(zeus::CMatrix4f); +// } +// +// bankTransforms.clear(); +// } else { +// for (size_t w = 0; w < weightCount; ++w) { +// zeus::CMatrix4f& mv = reinterpret_cast(*dataCur); +// mv = zeus::CMatrix4f(); +// dataCur += sizeof(zeus::CMatrix4f); +// } +// for (size_t w = 0; w < weightCount; ++w) { +// zeus::CMatrix4f& mvinv = reinterpret_cast(*dataCur); +// mvinv = zeus::CMatrix4f(); +// dataCur += sizeof(zeus::CMatrix4f); +// } +// } +// zeus::CMatrix4f& mv = reinterpret_cast(*dataCur); +// mv = CGraphics::g_GXModelView.toMatrix4f(); +// dataCur += sizeof(zeus::CMatrix4f); +// +// zeus::CMatrix4f& mvinv = reinterpret_cast(*dataCur); +// mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); +// dataCur += sizeof(zeus::CMatrix4f); +// +// zeus::CMatrix4f& proj = reinterpret_cast(*dataCur); +// proj = CGraphics::GetPerspectiveProjectionMatrix(true); +// dataCur += sizeof(zeus::CMatrix4f); +// +// dataCur = dataOut + ROUND_UP_256(dataCur - dataOut); +// } +// } else { +// /* Non-Skinned */ +// zeus::CMatrix4f& mv = reinterpret_cast(*dataCur); +// mv = CGraphics::g_GXModelView.toMatrix4f(); +// dataCur += sizeof(zeus::CMatrix4f); +// +// zeus::CMatrix4f& mvinv = reinterpret_cast(*dataCur); +// mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); +// dataCur += sizeof(zeus::CMatrix4f); +// +// zeus::CMatrix4f& proj = reinterpret_cast(*dataCur); +// proj = CGraphics::GetPerspectiveProjectionMatrix(true); +// dataCur += sizeof(zeus::CMatrix4f); +// +// dataCur = dataOut + ROUND_UP_256(dataCur - dataOut); +// } +// +// CBooModel::UVAnimationBuffer::Update(dataCur, matSet, flags, parent); +// buf->unmap(); +//} - float halfA = anim.uvAnimParms[0] * 0.5f; +//void GeometryUniformLayout::ReserveSharedBuffers(boo::IGraphicsDataFactory::Context& ctx, int size) { +// if (m_sharedBuffer.size() < size) +// m_sharedBuffer.resize(size); +// for (int i = 0; i < size; ++i) { +// auto& buf = m_sharedBuffer[i]; +// if (!buf) +// buf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomBufferSize, 1); +// } +//} +// +//boo::ObjToken GeometryUniformLayout::GetSharedBuffer(int idx) const { +// if (idx >= m_sharedBuffer.size()) +// m_sharedBuffer.resize(idx + 1); +// +// auto& buf = m_sharedBuffer[idx]; +// if (!buf) { +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// buf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomBufferSize, 1); +// return true; +// } BooTrace); +// } +// +// return buf; +//} - postMtxOut = - zeus::CTransform(zeus::CMatrix3f(halfA, 0.0, 0.0, 0.0, 0.0, halfA, 0.0, 0.0, 0.0), zeus::CVector3f(xy, z, 1.0)) - .toMatrix4f(); - break; - } - default: - break; - } - bufOut += sizeof(zeus::CMatrix4f) * 2; -} - -void CBooModel::UVAnimationBuffer::PadOutBuffer(u8*& bufStart, u8*& bufOut) { - bufOut = bufStart + ROUND_UP_256(bufOut - bufStart); -} - -void CBooModel::UVAnimationBuffer::Update(u8*& bufOut, const MaterialSet* matSet, const CModelFlags& flags, - const CBooModel* parent) { - u8* start = bufOut; - - if (flags.m_extendedShader == EExtendedShader::MorphBallShadow) { - /* Special matrices for MorphBall shadow rendering */ - zeus::CMatrix4f texMtx = (zeus::CTransform::Scale(1.f / (flags.mbShadowBox.max - flags.mbShadowBox.min)) * - zeus::CTransform::Translate(-flags.mbShadowBox.min) * CGraphics::g_GXModelMatrix) - .toMatrix4f(); - for (const MaterialSet::Material& mat : matSet->materials) { - (void)mat; - std::array* mtxs = reinterpret_cast*>(bufOut); - mtxs[0][0] = texMtx; - mtxs[0][1] = MBShadowPost0; - mtxs[1][0] = texMtx; - mtxs[1][1] = MBShadowPost1; - bufOut += sizeof(zeus::CMatrix4f) * 2 * 8; - PadOutBuffer(start, bufOut); - } - return; - } else if (flags.m_extendedShader == EExtendedShader::Disintegrate) { - assert(parent != nullptr && "Parent CBooModel not set"); - zeus::CTransform xf = zeus::CTransform::RotateX(-zeus::degToRad(45.f)); - zeus::CAABox aabb = parent->GetAABB().getTransformedAABox(xf); - xf = zeus::CTransform::Scale(5.f / (aabb.max - aabb.min)) * zeus::CTransform::Translate(-aabb.min) * xf; - zeus::CMatrix4f texMtx = xf.toMatrix4f(); - zeus::CMatrix4f post0 = DisintegratePost; - post0[3].x() = flags.addColor.a(); - post0[3].y() = 6.f * -(1.f - flags.addColor.a()) + 1.f; - zeus::CMatrix4f post1 = DisintegratePost; - post1[3].x() = -0.85f * flags.addColor.a() - 0.15f; - post1[3].y() = float(post0[3].y()); - /* Special matrices for disintegration rendering */ - for (const MaterialSet::Material& mat : matSet->materials) { - (void)mat; - std::array* mtxs = reinterpret_cast*>(bufOut); - mtxs[0][0] = texMtx; - mtxs[0][1] = post0; - mtxs[1][0] = texMtx; - mtxs[1][1] = post1; - bufOut += sizeof(zeus::CMatrix4f) * 2 * 8; - PadOutBuffer(start, bufOut); - } - return; - } - - std::optional> specialMtxOut; - if (flags.m_extendedShader == EExtendedShader::ThermalModel || - flags.m_extendedShader == EExtendedShader::ThermalModelNoZTestNoZWrite || - flags.m_extendedShader == EExtendedShader::ThermalStatic || - flags.m_extendedShader == EExtendedShader::ThermalStaticNoZWrite) { - /* Special Mode0 matrix for exclusive Thermal Visor use */ - specialMtxOut.emplace(); - - zeus::CMatrix4f& texMtxOut = (*specialMtxOut)[0]; - texMtxOut = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); - texMtxOut[3].zeroOut(); - texMtxOut[3].w() = 1.f; - - zeus::CMatrix4f& postMtxOut = (*specialMtxOut)[1]; - postMtxOut[0].x() = 0.5f; - postMtxOut[1].y() = 0.5f; - postMtxOut[3].x() = 0.5f; - postMtxOut[3].y() = 0.5f; - } else if (flags.m_extendedShader == EExtendedShader::WorldShadow || - flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) { - /* Special matrix for mapping world shadow */ - specialMtxOut.emplace(); - - zeus::CMatrix4f mat = g_shadowTexXf.toMatrix4f(); - zeus::CMatrix4f& texMtxOut = (*specialMtxOut)[0]; - texMtxOut[0][0] = float(mat[0][0]); - texMtxOut[1][0] = float(mat[1][0]); - texMtxOut[2][0] = float(mat[2][0]); - texMtxOut[3][0] = float(mat[3][0]); - texMtxOut[0][1] = float(mat[0][2]); - texMtxOut[1][1] = float(mat[1][2]); - texMtxOut[2][1] = float(mat[2][2]); - texMtxOut[3][1] = float(mat[3][2]); - } - - for (const MaterialSet::Material& mat : matSet->materials) { - if (specialMtxOut) { - std::array* mtxs = reinterpret_cast*>(bufOut); - mtxs[7][0] = (*specialMtxOut)[0]; - mtxs[7][1] = (*specialMtxOut)[1]; - } - u8* bufOrig = bufOut; - for (const auto& chunk : mat.chunks) { - if (const auto* const pass = chunk.get_if()) { - ProcessAnimation(bufOut, *pass); - } - } - bufOut = bufOrig + sizeof(zeus::CMatrix4f) * 2 * 8; - PadOutBuffer(start, bufOut); - } -} - -void GeometryUniformLayout::Update(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose, - const MaterialSet* matSet, const boo::ObjToken& buf, - const CBooModel* parent) const { - u8* dataOut = reinterpret_cast(buf->map(m_geomBufferSize)); - u8* dataCur = dataOut; - - if (m_skinBankCount) { - /* Skinned */ - std::vector bankTransforms; - size_t weightCount = m_weightVecCount * 4; - bankTransforms.reserve(weightCount); - for (size_t i = 0; i < m_skinBankCount; ++i) { - if (cskr && pose) { - cskr->GetBankTransforms(bankTransforms, *pose, i); - - for (size_t w = 0; w < weightCount; ++w) { - zeus::CMatrix4f& obj = reinterpret_cast(*dataCur); - if (w >= bankTransforms.size()) - obj = zeus::CMatrix4f(); - else - obj = bankTransforms[w]->toMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); - } - for (size_t w = 0; w < weightCount; ++w) { - zeus::CMatrix4f& objInv = reinterpret_cast(*dataCur); - if (w >= bankTransforms.size()) - objInv = zeus::CMatrix4f(); - else - objInv = bankTransforms[w]->basis; - dataCur += sizeof(zeus::CMatrix4f); - } - - bankTransforms.clear(); - } else { - for (size_t w = 0; w < weightCount; ++w) { - zeus::CMatrix4f& mv = reinterpret_cast(*dataCur); - mv = zeus::CMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); - } - for (size_t w = 0; w < weightCount; ++w) { - zeus::CMatrix4f& mvinv = reinterpret_cast(*dataCur); - mvinv = zeus::CMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); - } - } - zeus::CMatrix4f& mv = reinterpret_cast(*dataCur); - mv = CGraphics::g_GXModelView.toMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); - - zeus::CMatrix4f& mvinv = reinterpret_cast(*dataCur); - mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); - - zeus::CMatrix4f& proj = reinterpret_cast(*dataCur); - proj = CGraphics::GetPerspectiveProjectionMatrix(true); - dataCur += sizeof(zeus::CMatrix4f); - - dataCur = dataOut + ROUND_UP_256(dataCur - dataOut); - } - } else { - /* Non-Skinned */ - zeus::CMatrix4f& mv = reinterpret_cast(*dataCur); - mv = CGraphics::g_GXModelView.toMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); - - zeus::CMatrix4f& mvinv = reinterpret_cast(*dataCur); - mvinv = CGraphics::g_GXModelViewInvXpose.toMatrix4f(); - dataCur += sizeof(zeus::CMatrix4f); - - zeus::CMatrix4f& proj = reinterpret_cast(*dataCur); - proj = CGraphics::GetPerspectiveProjectionMatrix(true); - dataCur += sizeof(zeus::CMatrix4f); - - dataCur = dataOut + ROUND_UP_256(dataCur - dataOut); - } - - CBooModel::UVAnimationBuffer::Update(dataCur, matSet, flags, parent); - buf->unmap(); -} - -void GeometryUniformLayout::ReserveSharedBuffers(boo::IGraphicsDataFactory::Context& ctx, int size) { - if (m_sharedBuffer.size() < size) - m_sharedBuffer.resize(size); - for (int i = 0; i < size; ++i) { - auto& buf = m_sharedBuffer[i]; - if (!buf) - buf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomBufferSize, 1); - } -} - -boo::ObjToken GeometryUniformLayout::GetSharedBuffer(int idx) const { - if (idx >= m_sharedBuffer.size()) - m_sharedBuffer.resize(idx + 1); - - auto& buf = m_sharedBuffer[idx]; - if (!buf) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - buf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, m_geomBufferSize, 1); - return true; - } BooTrace); - } - - return buf; -} - -boo::ObjToken CBooModel::UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr, - const CPoseAsTransforms* pose, int sharedLayoutBuf, - boo::IGraphicsDataFactory::Context* ctx) { - OPTICK_EVENT(); - if (!g_DummyTextures && !TryLockTextures()) - return {}; - - /* Invalidate instances if new shadow being drawn */ - if ((flags.m_extendedShader == EExtendedShader::WorldShadow || - flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) && - m_lastDrawnShadowMap != g_shadowMap) { - m_lastDrawnShadowMap = g_shadowMap; - m_instances.clear(); - } - - /* Invalidate instances if new one-texture being drawn */ - if (flags.m_extendedShader == EExtendedShader::Disintegrate && m_lastDrawnOneTexture != g_disintegrateTexture) { - m_lastDrawnOneTexture = g_disintegrateTexture; - m_instances.clear(); - } - - /* Invalidate instances if new reflection cube being drawn */ - if (hecl::com_cubemaps->toBoolean() && - (flags.m_extendedShader == EExtendedShader::LightingCubeReflection || - flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) && - m_lastDrawnReflectionCube != g_reflectionCube) { - m_lastDrawnReflectionCube = g_reflectionCube; - m_instances.clear(); - } - - const ModelInstance* inst; - if (sharedLayoutBuf >= 0) { - if (m_instances.size() <= sharedLayoutBuf) { - do { - inst = PushNewModelInstance(m_instances.size(), ctx); - if (!inst) { - return {}; - } - } while (m_instances.size() <= sharedLayoutBuf); - } else { - inst = &m_instances[sharedLayoutBuf]; - } - m_uniUpdateCount = sharedLayoutBuf + 1; - } else { - if (m_instances.size() <= m_uniUpdateCount) { - inst = PushNewModelInstance(sharedLayoutBuf, ctx); - if (!inst) { - return {}; - } - } else { - inst = &m_instances[m_uniUpdateCount]; - } - ++m_uniUpdateCount; - } - - if (inst->m_geomUniformBuffer) { - m_geomLayout->Update(flags, cskr, pose, x4_matSet, inst->m_geomUniformBuffer, this); - } - - u8* dataOut = reinterpret_cast(inst->m_uniformBuffer->map(m_uniformDataSize)); - u8* dataCur = dataOut; - - if (flags.m_extendedShader == EExtendedShader::ThermalModel || - flags.m_extendedShader == EExtendedShader::ThermalModelNoZTestNoZWrite) /* Thermal Model (same as UV Mode 0) */ - { - CModelShaders::ThermalUniform& thermalOut = *reinterpret_cast(dataCur); - thermalOut.mulColor = flags.x4_color; - thermalOut.addColor = flags.addColor; - } else if (flags.m_extendedShader >= EExtendedShader::SolidColor && - flags.m_extendedShader <= EExtendedShader::SolidColorBackfaceCullGreaterAlphaOnly) /* Solid color render */ - { - CModelShaders::SolidUniform& solidOut = *reinterpret_cast(dataCur); - solidOut.solidColor = flags.x4_color; - } else if (flags.m_extendedShader == EExtendedShader::MorphBallShadow) /* MorphBall shadow render */ - { - CModelShaders::MBShadowUniform& shadowOut = *reinterpret_cast(dataCur); - shadowOut.shadowUp = CGraphics::g_GXModelView.rotate(zeus::skUp); - shadowOut.shadowUp.w() = flags.x4_color.a(); - shadowOut.shadowId = flags.x4_color.r(); - } else if (flags.m_extendedShader == EExtendedShader::Disintegrate) { - CModelShaders::OneTextureUniform& oneTexOut = *reinterpret_cast(dataCur); - oneTexOut.addColor = flags.addColor; - oneTexOut.fog = CGraphics::g_Fog; - } else { - CModelShaders::LightingUniform& lightingOut = *reinterpret_cast(dataCur); - lightingOut = m_lightingData; - lightingOut.colorRegs = CGraphics::g_ColorRegs; - lightingOut.mulColor = flags.x4_color; - lightingOut.addColor = flags.addColor; - lightingOut.fog = CGraphics::g_Fog; - } - - dataCur += sizeof(CModelShaders::LightingUniform); - dataCur = dataOut + ROUND_UP_256(dataCur - dataOut); - - /* Reflection texmtx uniform */ - zeus::CMatrix4f* identMtxs = reinterpret_cast(dataCur); - identMtxs[0] = zeus::CMatrix4f(); - identMtxs[1] = zeus::CMatrix4f(); - u8* curReflect = dataCur + 256; - for (const CBooSurface& surf : *x0_surfaces) { - const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); - if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) { - zeus::CMatrix4f* mtxs = reinterpret_cast(curReflect); - float& alpha = reinterpret_cast(mtxs[2]); - curReflect += 256; - EnsureViewDepStateCached(*this, mat.flags.samusReflectionSurfaceEye() ? &surf : nullptr, mtxs, alpha); - } - } - - inst->m_uniformBuffer->unmap(); - return inst->m_dynamicVbo; -} +//boo::ObjToken CBooModel::UpdateUniformData(const CModelFlags& flags, const CSkinRules* cskr, +// const CPoseAsTransforms* pose, int sharedLayoutBuf) { +// OPTICK_EVENT(); +//// if (!g_DummyTextures && !TryLockTextures()) +// return {}; +// +//// /* Invalidate instances if new shadow being drawn */ +//// if ((flags.m_extendedShader == EExtendedShader::WorldShadow || +//// flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) && +//// m_lastDrawnShadowMap != g_shadowMap) { +//// m_lastDrawnShadowMap = g_shadowMap; +//// m_instances.clear(); +//// } +//// +//// /* Invalidate instances if new one-texture being drawn */ +//// if (flags.m_extendedShader == EExtendedShader::Disintegrate && m_lastDrawnOneTexture != g_disintegrateTexture) { +//// m_lastDrawnOneTexture = g_disintegrateTexture; +//// m_instances.clear(); +//// } +//// +//// /* Invalidate instances if new reflection cube being drawn */ +//// if (hecl::com_cubemaps->toBoolean() && +//// (flags.m_extendedShader == EExtendedShader::LightingCubeReflection || +//// flags.m_extendedShader == EExtendedShader::LightingCubeReflectionWorldShadow) && +//// m_lastDrawnReflectionCube != g_reflectionCube) { +//// m_lastDrawnReflectionCube = g_reflectionCube; +//// m_instances.clear(); +//// } +// +//// const ModelInstance* inst; +//// if (sharedLayoutBuf >= 0) { +//// if (m_instances.size() <= sharedLayoutBuf) { +//// do { +//// inst = PushNewModelInstance(m_instances.size(), ctx); +//// if (!inst) { +//// return {}; +//// } +//// } while (m_instances.size() <= sharedLayoutBuf); +//// } else { +//// inst = &m_instances[sharedLayoutBuf]; +//// } +//// m_uniUpdateCount = sharedLayoutBuf + 1; +//// } else { +//// if (m_instances.size() <= m_uniUpdateCount) { +//// inst = PushNewModelInstance(sharedLayoutBuf, ctx); +//// if (!inst) { +//// return {}; +//// } +//// } else { +//// inst = &m_instances[m_uniUpdateCount]; +//// } +//// ++m_uniUpdateCount; +//// } +//// +//// if (inst->m_geomUniformBuffer) { +//// m_geomLayout->Update(flags, cskr, pose, x4_matSet, inst->m_geomUniformBuffer, this); +//// } +//// +//// u8* dataOut = reinterpret_cast(inst->m_uniformBuffer->map(m_uniformDataSize)); +//// u8* dataCur = dataOut; +//// +//// if (flags.m_extendedShader == EExtendedShader::ThermalModel || +//// flags.m_extendedShader == EExtendedShader::ThermalModelNoZTestNoZWrite) /* Thermal Model (same as UV Mode 0) */ +//// { +//// CModelShaders::ThermalUniform& thermalOut = *reinterpret_cast(dataCur); +//// thermalOut.mulColor = flags.x4_color; +//// thermalOut.addColor = flags.addColor; +//// } else if (flags.m_extendedShader >= EExtendedShader::SolidColor && +//// flags.m_extendedShader <= EExtendedShader::SolidColorBackfaceCullGreaterAlphaOnly) /* Solid color render */ +//// { +//// CModelShaders::SolidUniform& solidOut = *reinterpret_cast(dataCur); +//// solidOut.solidColor = flags.x4_color; +//// } else if (flags.m_extendedShader == EExtendedShader::MorphBallShadow) /* MorphBall shadow render */ +//// { +//// CModelShaders::MBShadowUniform& shadowOut = *reinterpret_cast(dataCur); +//// shadowOut.shadowUp = CGraphics::g_GXModelView.rotate(zeus::skUp); +//// shadowOut.shadowUp.w() = flags.x4_color.a(); +//// shadowOut.shadowId = flags.x4_color.r(); +//// } else if (flags.m_extendedShader == EExtendedShader::Disintegrate) { +//// CModelShaders::OneTextureUniform& oneTexOut = *reinterpret_cast(dataCur); +//// oneTexOut.addColor = flags.addColor; +//// oneTexOut.fog = CGraphics::g_Fog; +//// } else { +//// CModelShaders::LightingUniform& lightingOut = *reinterpret_cast(dataCur); +//// lightingOut = m_lightingData; +//// lightingOut.colorRegs = CGraphics::g_ColorRegs; +//// lightingOut.mulColor = flags.x4_color; +//// lightingOut.addColor = flags.addColor; +//// lightingOut.fog = CGraphics::g_Fog; +//// } +//// +//// dataCur += sizeof(CModelShaders::LightingUniform); +//// dataCur = dataOut + ROUND_UP_256(dataCur - dataOut); +//// +//// /* Reflection texmtx uniform */ +//// zeus::CMatrix4f* identMtxs = reinterpret_cast(dataCur); +//// identMtxs[0] = zeus::CMatrix4f(); +//// identMtxs[1] = zeus::CMatrix4f(); +//// u8* curReflect = dataCur + 256; +//// for (const CBooSurface& surf : *x0_surfaces) { +//// const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx); +//// if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) { +//// zeus::CMatrix4f* mtxs = reinterpret_cast(curReflect); +//// float& alpha = reinterpret_cast(mtxs[2]); +//// curReflect += 256; +//// EnsureViewDepStateCached(*this, mat.flags.samusReflectionSurfaceEye() ? &surf : nullptr, mtxs, alpha); +//// } +//// } +//// +//// inst->m_uniformBuffer->unmap(); +//// return inst->m_dynamicVbo; +//} void CBooModel::DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, const CPoseAsTransforms* pose) { CModelFlags rFlags = flags; @@ -1101,7 +1076,8 @@ void CBooModel::DrawAlpha(const CModelFlags& flags, const CSkinRules* cskr, cons } if (TryLockTextures()) { - UpdateUniformData(rFlags, cskr, pose); + // TODO? +// UpdateUniformData(rFlags, cskr, pose); DrawAlphaSurfaces(rFlags); } } @@ -1114,7 +1090,8 @@ void CBooModel::DrawNormal(const CModelFlags& flags, const CSkinRules* cskr, con rFlags.x4_color = zeus::skBlack; } if (TryLockTextures()) { - UpdateUniformData(rFlags, cskr, pose); + // TODO? +// UpdateUniformData(rFlags, cskr, pose); DrawNormalSurfaces(rFlags); } } @@ -1128,7 +1105,8 @@ void CBooModel::Draw(const CModelFlags& flags, const CSkinRules* cskr, const CPo } if (TryLockTextures()) { - UpdateUniformData(rFlags, cskr, pose); + // TODO? +// UpdateUniformData(rFlags, cskr, pose); DrawSurfaces(rFlags); } } @@ -1140,119 +1118,121 @@ static const u8* MemoryFromPartData(const u8*& dataCur, const u32*& secSizeCur) else ret = nullptr; - dataCur += hecl::SBig(*secSizeCur); + dataCur += CBasics::SwapBytes(*secSizeCur); ++secSizeCur; return ret; } -std::unique_ptr CModel::MakeNewInstance(int shaderIdx, int subInsts, bool lockParent) { +std::unique_ptr CModel::MakeNewInstance(int shaderIdx, bool lockParent) { if (shaderIdx >= x18_matSets.size()) shaderIdx = 0; - auto ret = std::make_unique(m_selfToken, this, &x8_surfaces, x18_matSets[shaderIdx], m_staticVbo, m_ibo, - m_aabb, (m_flags & 0x2) != 0, subInsts); + auto ret = std::make_unique(m_selfToken, this, &x8_surfaces, x18_matSets[shaderIdx], //m_staticVbo, m_ibo, + m_aabb, (m_flags & 0x2) != 0); if (lockParent) ret->LockParent(); return ret; } -CModelShaders::ShaderPipelines SShader::BuildShader(const hecl::HMDLMeta& meta, const MaterialSet::Material& mat) { - OPTICK_EVENT(); - hecl::Backend::ReflectionType reflectionType; - if (mat.flags.samusReflectionIndirectTexture()) - reflectionType = hecl::Backend::ReflectionType::Indirect; - else if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) - reflectionType = hecl::Backend::ReflectionType::Simple; - else - reflectionType = hecl::Backend::ReflectionType::None; - hecl::Backend::ShaderTag tag(mat.hash, meta.colorCount, meta.uvCount, meta.weightCount, meta.weightCount * 4, - boo::Primitive(meta.topology), reflectionType, true, true, true, mat.flags.alphaTest()); - return CModelShaders::BuildExtendedShader(tag, mat); -} - -void SShader::BuildShaders(const hecl::HMDLMeta& meta, - std::unordered_map& shaders) { - shaders.reserve(m_matSet.materials.size()); - int idx = 0; - for (const MaterialSet::Material& mat : m_matSet.materials) - shaders[idx++] = BuildShader(meta, mat); -} +//CModelShaders::ShaderPipelines SShader::BuildShader(const hecl::HMDLMeta& meta, const MaterialSet::Material& mat) { +// OPTICK_EVENT(); +// hecl::Backend::ReflectionType reflectionType; +// if (mat.flags.samusReflectionIndirectTexture()) +// reflectionType = hecl::Backend::ReflectionType::Indirect; +// else if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye()) +// reflectionType = hecl::Backend::ReflectionType::Simple; +// else +// reflectionType = hecl::Backend::ReflectionType::None; +// hecl::Backend::ShaderTag tag(mat.hash, meta.colorCount, meta.uvCount, meta.weightCount, meta.weightCount * 4, +// boo::Primitive(meta.topology), reflectionType, true, true, true, mat.flags.alphaTest()); +// return CModelShaders::BuildExtendedShader(tag, mat); +//} +// +//void SShader::BuildShaders(const hecl::HMDLMeta& meta, +// std::unordered_map& shaders) { +// shaders.reserve(m_matSet.materials.size()); +// int idx = 0; +// for (const MaterialSet::Material& mat : m_matSet.materials) +// shaders[idx++] = BuildShader(meta, mat); +//} CModel::CModel(std::unique_ptr&& in, u32 /* dataLen */, IObjectStore* store, CObjectReference* selfRef) : m_selfToken(selfRef) { x38_lastFrame = CGraphics::GetFrameCounter() - 2; std::unique_ptr data = std::move(in); - u32 version = hecl::SBig(*reinterpret_cast(data.get() + 0x4)); - m_flags = hecl::SBig(*reinterpret_cast(data.get() + 0x8)); - if (version != 0x10002) - Log.report(logvisor::Fatal, FMT_STRING("invalid CMDL for loading with boo")); + u32 version = CBasics::SwapBytes(*reinterpret_cast(data.get() + 0x4)); + m_flags = CBasics::SwapBytes(*reinterpret_cast(data.get() + 0x8)); + if (version != 0x10002) { + Log.report(logvisor::Error, FMT_STRING("invalid CMDL for loading with boo")); + return; + } - u32 secCount = hecl::SBig(*reinterpret_cast(data.get() + 0x24)); - u32 matSetCount = hecl::SBig(*reinterpret_cast(data.get() + 0x28)); + u32 secCount = CBasics::SwapBytes(*reinterpret_cast(data.get() + 0x24)); + u32 matSetCount = CBasics::SwapBytes(*reinterpret_cast(data.get() + 0x28)); x18_matSets.reserve(matSetCount); const u8* dataCur = data.get() + ROUND_UP_32(0x2c + secCount * 4); const u32* secSizeCur = reinterpret_cast(data.get() + 0x2c); for (u32 i = 0; i < matSetCount; ++i) { - const u32 matSetSz = hecl::SBig(*secSizeCur); + const u32 matSetSz = CBasics::SwapBytes(*secSizeCur); const u8* sec = MemoryFromPartData(dataCur, secSizeCur); SShader& shader = x18_matSets.emplace_back(i); - athena::io::MemoryReader r(sec, matSetSz); - shader.m_matSet.read(r); - CBooModel::MakeTexturesFromMats(shader.m_matSet, shader.x0_textures, *store); +// athena::io::MemoryReader r(sec, matSetSz); +// shader.m_matSet.read(r); +// CBooModel::MakeTexturesFromMats(shader.m_matSet, shader.x0_textures, *store); } { - u32 hmdlSz = hecl::SBig(*secSizeCur); + u32 hmdlSz = CBasics::SwapBytes(*secSizeCur); const u8* hmdlMetadata = MemoryFromPartData(dataCur, secSizeCur); - athena::io::MemoryReader r(hmdlMetadata, hmdlSz); - m_hmdlMeta.read(r); +// athena::io::MemoryReader r(hmdlMetadata, hmdlSz); +// m_hmdlMeta.read(r); } const u8* vboData = MemoryFromPartData(dataCur, secSizeCur); const u8* iboData = MemoryFromPartData(dataCur, secSizeCur); const u8* surfInfo = MemoryFromPartData(dataCur, secSizeCur); - for (SShader& matSet : x18_matSets) { - matSet.InitializeLayout(this); - matSet.BuildShaders(m_hmdlMeta); - } +// for (SShader& matSet : x18_matSets) { +// matSet.InitializeLayout(this); +// matSet.BuildShaders(m_hmdlMeta); +// } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - /* Index buffer is always static */ - if (m_hmdlMeta.indexCount) - m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, iboData, 4, m_hmdlMeta.indexCount); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// /* Index buffer is always static */ +// if (m_hmdlMeta.indexCount) +// m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, iboData, 4, m_hmdlMeta.indexCount); +// +// if (!m_hmdlMeta.bankCount) { +// /* Non-skinned models use static vertex buffers shared with CBooModel instances */ +// if (m_hmdlMeta.vertCount) +// m_staticVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vboData, m_hmdlMeta.vertStride, m_hmdlMeta.vertCount); +// } else { +// /* Skinned models use per-instance dynamic buffers for vertex manipulation effects */ +// size_t vboSz = m_hmdlMeta.vertStride * m_hmdlMeta.vertCount; +// if (vboSz) { +// m_dynamicVertexData.reset(new uint8_t[vboSz]); +// memmove(m_dynamicVertexData.get(), vboData, vboSz); +// } +// } +// +// return true; +// } BooTrace); - if (!m_hmdlMeta.bankCount) { - /* Non-skinned models use static vertex buffers shared with CBooModel instances */ - if (m_hmdlMeta.vertCount) - m_staticVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, vboData, m_hmdlMeta.vertStride, m_hmdlMeta.vertCount); - } else { - /* Skinned models use per-instance dynamic buffers for vertex manipulation effects */ - size_t vboSz = m_hmdlMeta.vertStride * m_hmdlMeta.vertCount; - if (vboSz) { - m_dynamicVertexData.reset(new uint8_t[vboSz]); - memmove(m_dynamicVertexData.get(), vboData, vboSz); - } - } - - return true; - } BooTrace); - - const u32 surfCount = hecl::SBig(*reinterpret_cast(surfInfo)); + const u32 surfCount = CBasics::SwapBytes(*reinterpret_cast(surfInfo)); x8_surfaces.reserve(surfCount); for (u32 i = 0; i < surfCount; ++i) { - const u32 surfSz = hecl::SBig(*secSizeCur); + const u32 surfSz = CBasics::SwapBytes(*secSizeCur); const u8* sec = MemoryFromPartData(dataCur, secSizeCur); CBooSurface& surf = x8_surfaces.emplace_back(); surf.selfIdx = i; - athena::io::MemoryReader r(sec, surfSz); - surf.m_data.read(r); +// athena::io::MemoryReader r(sec, surfSz); +// surf.m_data.read(r); } const float* aabbPtr = reinterpret_cast(data.get() + 0xc); - m_aabb = zeus::CAABox(hecl::SBig(aabbPtr[0]), hecl::SBig(aabbPtr[1]), hecl::SBig(aabbPtr[2]), hecl::SBig(aabbPtr[3]), - hecl::SBig(aabbPtr[4]), hecl::SBig(aabbPtr[5])); - x28_modelInst = MakeNewInstance(0, 1, false); + m_aabb = zeus::CAABox(CBasics::SwapBytes(aabbPtr[0]), CBasics::SwapBytes(aabbPtr[1]), CBasics::SwapBytes(aabbPtr[2]), CBasics::SwapBytes(aabbPtr[3]), + CBasics::SwapBytes(aabbPtr[4]), CBasics::SwapBytes(aabbPtr[5])); + x28_modelInst = MakeNewInstance(0, false); } void SShader::UnlockTextures() { @@ -1290,72 +1270,50 @@ bool CModel::IsLoaded(int shaderIdx) const { return x28_modelInst->TryLockTextures(); } -size_t CModel::GetPoolVertexOffset(size_t idx) const { return m_hmdlMeta.vertStride * idx; } +size_t CModel::GetPoolVertexOffset(size_t idx) const { +// return m_hmdlMeta.vertStride * idx; + return 0; +} zeus::CVector3f CModel::GetPoolVertex(size_t idx) const { const auto* floats = reinterpret_cast(m_dynamicVertexData.get() + GetPoolVertexOffset(idx)); return {floats}; } -size_t CModel::GetPoolNormalOffset(size_t idx) const { return m_hmdlMeta.vertStride * idx + 12; } +size_t CModel::GetPoolNormalOffset(size_t idx) const { +// return m_hmdlMeta.vertStride * idx + 12; + return 0; +} zeus::CVector3f CModel::GetPoolNormal(size_t idx) const { const auto* floats = reinterpret_cast(m_dynamicVertexData.get() + GetPoolNormalOffset(idx)); return {floats}; } -void CModel::ApplyVerticesCPU(const boo::ObjToken& vertBuf, - const std::vector>& vn) const { - u8* data = reinterpret_cast(vertBuf->map(m_hmdlMeta.vertStride * m_hmdlMeta.vertCount)); - for (u32 i = 0; i < std::min(u32(vn.size()), m_hmdlMeta.vertCount); ++i) { - const std::pair& avn = vn[i]; - float* floats = reinterpret_cast(data + GetPoolVertexOffset(i)); - floats[0] = avn.first.x(); - floats[1] = avn.first.y(); - floats[2] = avn.first.z(); - floats[3] = avn.second.x(); - floats[4] = avn.second.y(); - floats[5] = avn.second.z(); - } - vertBuf->unmap(); -} +//void CModel::ApplyVerticesCPU(const boo::ObjToken& vertBuf, +// const std::vector>& vn) const { +// u8* data = reinterpret_cast(vertBuf->map(m_hmdlMeta.vertStride * m_hmdlMeta.vertCount)); +// for (u32 i = 0; i < std::min(u32(vn.size()), m_hmdlMeta.vertCount); ++i) { +// const std::pair& avn = vn[i]; +// float* floats = reinterpret_cast(data + GetPoolVertexOffset(i)); +// floats[0] = avn.first.x(); +// floats[1] = avn.first.y(); +// floats[2] = avn.first.z(); +// floats[3] = avn.second.x(); +// floats[4] = avn.second.y(); +// floats[5] = avn.second.z(); +// } +// vertBuf->unmap(); +//} +// +//void CModel::RestoreVerticesCPU(const boo::ObjToken& vertBuf) const { +// size_t size = m_hmdlMeta.vertStride * m_hmdlMeta.vertCount; +// u8* data = reinterpret_cast(vertBuf->map(size)); +// memcpy(data, m_dynamicVertexData.get(), size); +// vertBuf->unmap(); +//} -void CModel::RestoreVerticesCPU(const boo::ObjToken& vertBuf) const { - size_t size = m_hmdlMeta.vertStride * m_hmdlMeta.vertCount; - u8* data = reinterpret_cast(vertBuf->map(size)); - memcpy(data, m_dynamicVertexData.get(), size); - vertBuf->unmap(); -} - -void CModel::_WarmupShaders() { - CBooModel::SetDummyTextures(true); - CBooModel::EnableShadowMaps(g_Renderer->x220_sphereRamp.get(), zeus::CTransform()); - CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState(); - zeus::CTransform backupViewPoint = CGraphics::g_ViewMatrix; - zeus::CTransform backupModel = CGraphics::g_GXModelMatrix; - CGraphics::SetModelMatrix(zeus::CTransform::Translate(-m_aabb.center())); - CGraphics::SetViewPointMatrix(zeus::CTransform::Translate(0.f, -2048.f, 0.f)); - CGraphics::SetOrtho(-2048.f, 2048.f, 2048.f, -2048.f, 0.f, 4096.f); - CModelFlags defaultFlags; - for (SShader& shader : x18_matSets) { - GetInstance().RemapMaterialData(shader); - GetInstance().UpdateUniformData(defaultFlags, nullptr, nullptr); - GetInstance().WarmupDrawSurfaces(); - } - CGraphics::SetProjectionState(backupProj); - CGraphics::SetViewPointMatrix(backupViewPoint); - CGraphics::SetModelMatrix(backupModel); - CBooModel::DisableShadowMaps(); - CBooModel::SetDummyTextures(false); -} - -void CModel::WarmupShaders(const SObjectTag& cmdlTag) { - TToken model = g_SimplePool->GetObj(cmdlTag); - CModel* modelObj = model.GetObj(); - modelObj->_WarmupShaders(); -} - -CFactoryFnReturn FModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, +CFactoryFnReturn FPCModelFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef) { CSimplePool* sp = vparms.GetOwnedObj(); CFactoryFnReturn ret = TToken::GetIObjObjectFor(std::make_unique(std::move(in), len, sp, selfRef)); diff --git a/Runtime/Graphics/CMoviePlayer.cpp b/Runtime/Graphics/CMoviePlayer.cpp index 37aab6c64..a5b6e24ce 100644 --- a/Runtime/Graphics/CMoviePlayer.cpp +++ b/Runtime/Graphics/CMoviePlayer.cpp @@ -1,20 +1,132 @@ -#include "Runtime/Graphics/CMoviePlayer.hpp" +#include "Graphics/CMoviePlayer.hpp" -#include "Runtime/Audio/g721.h" -#include "Runtime/CDvdRequest.hpp" -#include "Runtime/Graphics/CGraphics.hpp" +#include "Audio/g721.h" +#include "CDvdRequest.hpp" +#include "Graphics/CGraphics.hpp" +#include "Graphics/CCubeRenderer.hpp" +#include "Graphics/CGX.hpp" +#include "GameGlobalObjects.hpp" -#include -#include +//#include #include namespace metaforce { -zeus::CMatrix4f g_PlatformMatrix; +static void MyTHPYuv2RgbTextureSetup(void* dataY, void* dataU, void* dataV, u16 width, u16 height) { + GXTexObj texV; + GXTexObj texU; + GXTexObj texY; + GXInitTexObj(&texY, dataY, width, height, GX_TF_R8_PC, GX_CLAMP, GX_CLAMP, false); + GXInitTexObjLOD(&texY, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1); + GXLoadTexObj(&texY, GX_TEXMAP0); + GXInitTexObj(&texU, dataU, width / 2, height / 2, GX_TF_R8_PC, GX_CLAMP, GX_CLAMP, false); + GXInitTexObjLOD(&texU, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1); + GXLoadTexObj(&texU, GX_TEXMAP1); + GXInitTexObj(&texV, dataV, width / 2, height / 2, GX_TF_R8_PC, GX_CLAMP, GX_CLAMP, false); + GXInitTexObjLOD(&texV, GX_NEAR, GX_NEAR, 0.0, 0.0, 0.0, false, false, GX_ANISO_1); + GXLoadTexObj(&texV, GX_TEXMAP2); + CTexture::InvalidateTexMap(GX_TEXMAP0); + CTexture::InvalidateTexMap(GX_TEXMAP1); + CTexture::InvalidateTexMap(GX_TEXMAP2); +#ifdef AURORA + GXDestroyTexObj(&texV); + GXDestroyTexObj(&texU); + GXDestroyTexObj(&texY); +#endif +} + +const std::array InterlaceTex{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, +}; +static void MyTHPGXYuv2RgbSetup(bool interlaced2ndFrame, bool fieldFlip) { + CGX::SetZMode(true, GX_ALWAYS, false); + CGX::SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); + CGX::SetNumChans(0); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + if (!fieldFlip) { + CGX::SetNumTexGens(3); + CGX::SetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_POS, GX_TEXMTX0, false, GX_PTIDENTITY); + aurora::Mat4x2 mtx; + mtx.m0.x = 0.125f; + mtx.m2.y = 0.25f; + if (interlaced2ndFrame) { + mtx.m3.y = 0.25f; + } + GXLoadTexMtxImm(&mtx, GX_TEXMTX0, GX_MTX2x4); + GXTexObj texObj; + GXInitTexObj(&texObj, InterlaceTex.data(), 8, 4, GX_TF_I8, GX_REPEAT, GX_REPEAT, false); + GXInitTexObjLOD(&texObj, GX_NEAR, GX_NEAR, 0.f, 0.f, 0.f, false, false, GX_ANISO_1); + GXLoadTexObj(&texObj, GX_TEXMAP3); +#ifdef AURORA + GXDestroyTexObj(&texObj); +#endif + CTexture::InvalidateTexMap(GX_TEXMAP3); + CGX::SetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD2, GX_TEXMAP3, GX_COLOR_NULL); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE4); + CGX::SetTevColorIn(GX_TEVSTAGE4, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV); + CGX::SetTevAlphaIn(GX_TEVSTAGE4, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA); + CGX::SetAlphaCompare(GX_LESS, 128, GX_AOP_AND, GX_ALWAYS, 0); + CGX::SetNumTevStages(5); + } else { + CGX::SetNumTexGens(2); + CGX::SetNumTevStages(4); + } + constexpr std::array vtxDescList{ + GXVtxDescList{GX_VA_POS, GX_DIRECT}, + GXVtxDescList{GX_VA_TEX0, GX_DIRECT}, + GXVtxDescList{GX_VA_NULL, GX_NONE}, + }; + CGX::SetVtxDescv(vtxDescList.data()); + GXSetColorUpdate(true); + GXSetAlphaUpdate(false); + GXInvalidateTexAll(); + GXSetVtxAttrFmt(GX_VTXFMT7, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GXSetVtxAttrFmt(GX_VTXFMT7, GX_VA_TEX0, GX_TEX_ST, GX_U16, 0); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_C0); + CGX::SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, false, GX_TEVPREV); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_A0); + CGX::SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, false, GX_TEVPREV); + CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP2, GX_COLOR_NULL); + CGX::SetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_CPREV); + CGX::SetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_2, false, GX_TEVPREV); + CGX::SetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_APREV); + CGX::SetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_SUB, GX_TB_ZERO, GX_CS_SCALE_1, false, GX_TEVPREV); + CGX::SetTevKColorSel(GX_TEVSTAGE1, GX_TEV_KCSEL_K1); + CGX::SetTevKAlphaSel(GX_TEVSTAGE1, GX_TEV_KASEL_K1_A); + CGX::SetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_ONE, GX_CC_CPREV); + CGX::SetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTevAlphaIn(GX_TEVSTAGE2, GX_CA_TEXA, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV); + CGX::SetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + CGX::SetTevColorIn(GX_TEVSTAGE3, GX_CC_APREV, GX_CC_CPREV, GX_CC_KONST, GX_CC_ZERO); + CGX::SetTevColorOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTevAlphaIn(GX_TEVSTAGE3, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO); + CGX::SetTevAlphaOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTevKColorSel(GX_TEVSTAGE3, GX_TEV_KCSEL_K2); + GXSetTevColorS10(GX_TEVREG0, GXColorS10{-90, 0, -114, 135}); + CGX::SetTevKColor(GX_KCOLOR0, GXColor{0x00, 0x00, 0xe2, 0x58}); + CGX::SetTevKColor(GX_KCOLOR1, GXColor{0xb3, 0x00, 0x00, 0xb6}); + CGX::SetTevKColor(GX_KCOLOR2, GXColor{0xff, 0x00, 0xff, 0x80}); +} +static void MyTHPGXRestore() { + CGX::SetZMode(true, GX_ALWAYS, false); + CGX::SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_SET); + CGX::SetNumTexGens(1); + CGX::SetNumChans(0); + CGX::SetNumTevStages(1); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); +} /* used in the original to look up fixed-point dividends on a * MIDI-style volume scale (0-127) -> (n/0x8000) */ -static const u16 StaticVolumeLookup[] = { +static const std::array StaticVolumeLookup = { 0x0000, 0x0002, 0x0008, 0x0012, 0x0020, 0x0032, 0x0049, 0x0063, 0x0082, 0x00A4, 0x00CB, 0x00F5, 0x0124, 0x0157, 0x018E, 0x01C9, 0x0208, 0x024B, 0x0292, 0x02DD, 0x032C, 0x037F, 0x03D7, 0x0432, 0x0492, 0x04F5, 0x055D, 0x05C9, 0x0638, 0x06AC, 0x0724, 0x07A0, 0x0820, 0x08A4, 0x092C, 0x09B8, 0x0A48, 0x0ADD, 0x0B75, @@ -26,8 +138,7 @@ static const u16 StaticVolumeLookup[] = { 0x55D6, 0x577E, 0x592B, 0x5ADC, 0x5C90, 0x5E49, 0x6006, 0x61C7, 0x638C, 0x6555, 0x6722, 0x68F4, 0x6AC9, 0x6CA2, 0x6E80, 0x7061, 0x7247, 0x7430, 0x761E, 0x7810, 0x7A06, 0x7C00, 0x7DFE, 0x8000}; -/* shared boo resources */ -static boo::ObjToken YUVShaderPipeline; +/* shared resources */ static tjhandle TjHandle = nullptr; /* RSF audio state */ @@ -43,105 +154,92 @@ static g72x_state StaticStateRight = {}; /* THP SFX audio */ static float SfxVolume = 1.f; -static const char* BlockNames[] = {"SpecterViewBlock"}; -static const char* TexNames[] = {"texY", "texU", "texV"}; - -void CMoviePlayer::Initialize(boo::IGraphicsDataFactory* factory) { - switch (factory->platform()) { - case boo::IGraphicsDataFactory::Platform::Vulkan: - g_PlatformMatrix.m[1][1] = -1.f; - break; - default: - break; - } - YUVShaderPipeline = hecl::conv->convert(Shader_CMoviePlayerShader{}); - TjHandle = tjInitDecompress(); -} +void CMoviePlayer::Initialize() { TjHandle = tjInitDecompress(); } void CMoviePlayer::Shutdown() { - YUVShaderPipeline.reset(); tjDestroy(TjHandle); + TjHandle = nullptr; } void CMoviePlayer::THPHeader::swapBig() { - magic = hecl::SBig(magic); - version = hecl::SBig(version); - maxBufferSize = hecl::SBig(maxBufferSize); - maxAudioSamples = hecl::SBig(maxAudioSamples); - fps = hecl::SBig(fps); - numFrames = hecl::SBig(numFrames); - firstFrameSize = hecl::SBig(firstFrameSize); - dataSize = hecl::SBig(dataSize); - componentDataOffset = hecl::SBig(componentDataOffset); - offsetsDataOffset = hecl::SBig(offsetsDataOffset); - firstFrameOffset = hecl::SBig(firstFrameOffset); - lastFrameOffset = hecl::SBig(lastFrameOffset); + magic = SBig(magic); + version = SBig(version); + maxBufferSize = SBig(maxBufferSize); + maxAudioSamples = SBig(maxAudioSamples); + fps = SBig(fps); + numFrames = SBig(numFrames); + firstFrameSize = SBig(firstFrameSize); + dataSize = SBig(dataSize); + componentDataOffset = SBig(componentDataOffset); + offsetsDataOffset = SBig(offsetsDataOffset); + firstFrameOffset = SBig(firstFrameOffset); + lastFrameOffset = SBig(lastFrameOffset); } -void CMoviePlayer::THPComponents::swapBig() { numComponents = hecl::SBig(numComponents); } +void CMoviePlayer::THPComponents::swapBig() { numComponents = SBig(numComponents); } void CMoviePlayer::THPVideoInfo::swapBig() { - width = hecl::SBig(width); - height = hecl::SBig(height); + width = SBig(width); + height = SBig(height); } void CMoviePlayer::THPAudioInfo::swapBig() { - numChannels = hecl::SBig(numChannels); - sampleRate = hecl::SBig(sampleRate); - numSamples = hecl::SBig(numSamples); + numChannels = SBig(numChannels); + sampleRate = SBig(sampleRate); + numSamples = SBig(numSamples); } void CMoviePlayer::THPFrameHeader::swapBig() { - nextSize = hecl::SBig(nextSize); - prevSize = hecl::SBig(prevSize); - imageSize = hecl::SBig(imageSize); - audioSize = hecl::SBig(audioSize); + nextSize = SBig(nextSize); + prevSize = SBig(prevSize); + imageSize = SBig(imageSize); + audioSize = SBig(audioSize); } void CMoviePlayer::THPAudioFrameHeader::swapBig() { - channelSize = hecl::SBig(channelSize); - numSamples = hecl::SBig(numSamples); + channelSize = SBig(channelSize); + numSamples = SBig(numSamples); for (int i = 0; i < 2; ++i) { for (int j = 0; j < 8; ++j) { - channelCoefs[i][j][0] = hecl::SBig(channelCoefs[i][j][0]); - channelCoefs[i][j][1] = hecl::SBig(channelCoefs[i][j][1]); + channelCoefs[i][j][0] = SBig(channelCoefs[i][j][0]); + channelCoefs[i][j][1] = SBig(channelCoefs[i][j][1]); } - channelPrevs[i][0] = hecl::SBig(channelPrevs[i][0]); - channelPrevs[i][1] = hecl::SBig(channelPrevs[i][1]); + channelPrevs[i][0] = SBig(channelPrevs[i][0]); + channelPrevs[i][1] = SBig(channelPrevs[i][1]); } } /* Slightly modified from THPAudioDecode present in SDK; always interleaves */ u32 CMoviePlayer::THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo) { THPAudioFrameHeader header = *((const THPAudioFrameHeader*)audioFrame); - header.swapBig(); - audioFrame += sizeof(THPAudioFrameHeader); - - if (stereo) { - for (int i = 0; i < 2; ++i) { - unsigned samples = header.numSamples; - s16* bufferCur = buffer + i; - int16_t prev1 = header.channelPrevs[i][0]; - int16_t prev2 = header.channelPrevs[i][1]; - for (u32 f = 0; f < (header.numSamples + 13) / 14; ++f) { - DSPDecompressFrameStereoStride(bufferCur, audioFrame, header.channelCoefs[i], &prev1, &prev2, samples); - samples -= 14; - bufferCur += 28; - audioFrame += 8; - } - } - } else { - unsigned samples = header.numSamples; - s16* bufferCur = buffer; - int16_t prev1 = header.channelPrevs[0][0]; - int16_t prev2 = header.channelPrevs[0][1]; - for (u32 f = 0; f < (header.numSamples + 13) / 14; ++f) { - DSPDecompressFrameStereoDupe(bufferCur, audioFrame, header.channelCoefs[0], &prev1, &prev2, samples); - samples -= 14; - bufferCur += 28; - audioFrame += 8; - } - } +// header.swapBig(); +// audioFrame += sizeof(THPAudioFrameHeader); +// +// if (stereo) { +// for (int i = 0; i < 2; ++i) { +// unsigned samples = header.numSamples; +// s16* bufferCur = buffer + i; +// int16_t prev1 = header.channelPrevs[i][0]; +// int16_t prev2 = header.channelPrevs[i][1]; +// for (u32 f = 0; f < (header.numSamples + 13) / 14; ++f) { +// DSPDecompressFrameStereoStride(bufferCur, audioFrame, header.channelCoefs[i], &prev1, &prev2, samples); +// samples -= 14; +// bufferCur += 28; +// audioFrame += 8; +// } +// } +// } else { +// unsigned samples = header.numSamples; +// s16* bufferCur = buffer; +// int16_t prev1 = header.channelPrevs[0][0]; +// int16_t prev2 = header.channelPrevs[0][1]; +// for (u32 f = 0; f < (header.numSamples + 13) / 14; ++f) { +// DSPDecompressFrameStereoDupe(bufferCur, audioFrame, header.channelCoefs[0], &prev1, &prev2, samples); +// samples -= 14; +// bufferCur += 28; +// audioFrame += 8; +// } +// } return header.numSamples; } @@ -201,51 +299,35 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo if (xf0_preLoadFrames > 0) xa0_bufferQueue.reserve(xf0_preLoadFrames); - /* All set for GPU resources */ - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_blockBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(m_viewVertBlock), 1); - m_vertBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(TexShaderVert), 4); - - /* Allocate textures here (rather than at decode time) */ - x80_textures.reserve(3); - for (int i = 0; i < 3; ++i) { - CTHPTextureSet& set = x80_textures.emplace_back(); - if (deinterlace) { - /* metaforce addition: this way interlaced THPs don't look horrible */ - set.Y[0] = ctx.newDynamicTexture(x6c_videoInfo.width, x6c_videoInfo.height / 2, boo::TextureFormat::I8, - boo::TextureClampMode::Repeat); - set.Y[1] = ctx.newDynamicTexture(x6c_videoInfo.width, x6c_videoInfo.height / 2, boo::TextureFormat::I8, - boo::TextureClampMode::Repeat); - set.U = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, boo::TextureFormat::I8, - boo::TextureClampMode::Repeat); - set.V = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, boo::TextureFormat::I8, - boo::TextureClampMode::Repeat); - - boo::ObjToken bufs[] = {m_blockBuf.get()}; - for (int j = 0; j < 2; ++j) { - boo::ObjToken texs[] = {set.Y[j].get(), set.U.get(), set.V.get()}; - set.binding[j] = ctx.newShaderDataBinding(YUVShaderPipeline, m_vertBuf.get(), nullptr, nullptr, 1, bufs, - nullptr, 3, texs, nullptr, nullptr); - } - } else { - /* normal progressive presentation */ - set.Y[0] = ctx.newDynamicTexture(x6c_videoInfo.width, x6c_videoInfo.height, boo::TextureFormat::I8, - boo::TextureClampMode::Repeat); - set.U = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, boo::TextureFormat::I8, - boo::TextureClampMode::Repeat); - set.V = ctx.newDynamicTexture(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, boo::TextureFormat::I8, - boo::TextureClampMode::Repeat); - - boo::ObjToken bufs[] = {m_blockBuf.get()}; - boo::ObjToken texs[] = {set.Y[0].get(), set.U.get(), set.V.get()}; - set.binding[0] = ctx.newShaderDataBinding(YUVShaderPipeline, m_vertBuf.get(), nullptr, nullptr, 1, bufs, - nullptr, 3, texs, nullptr, nullptr); - } - if (xf4_25_hasAudio) - set.audioBuf.reset(new s16[x28_thpHead.maxAudioSamples * 2]); - } - return true; - } BooTrace); + /* Allocate textures here (rather than at decode time) */ + x80_textures.reserve(3); + for (int i = 0; i < 3; ++i) { + CTHPTextureSet& set = x80_textures.emplace_back(); + // if (deinterlace) { + // /* metaforce addition: this way interlaced THPs don't look horrible */ + // set.Y[0] = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height / 2, 1, GX_TF_I8, + // fmt::format(FMT_STRING("Movie {} Texture Set {} Y[0]"), path, + // i)); + // set.Y[1] = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height / 2, 1, GX_TF_I8, + // fmt::format(FMT_STRING("Movie {} Texture Set {} Y[1]"), path, + // i)); + // set.U = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, GX_TF_I8, + // fmt::format(FMT_STRING("Movie {} Texture Set {} U"), path, i)); + // set.V = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, GX_TF_I8, + // fmt::format(FMT_STRING("Movie {} Texture Set {} V"), path, i)); + // } else { + // /* normal progressive presentation */ + // set.Y[0] = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width, x6c_videoInfo.height, 1, GX_TF_I8, + // fmt::format(FMT_STRING("Movie {} Texture Set {} Y"), path, + // i)); + // set.U = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, GX_TF_I8, + // fmt::format(FMT_STRING("Movie {} Texture Set {} U"), path, i)); + // set.V = aurora::gfx::new_dynamic_texture_2d(x6c_videoInfo.width / 2, x6c_videoInfo.height / 2, 1, GX_TF_I8, + // fmt::format(FMT_STRING("Movie {} Texture Set {} V"), path, i)); + // } + if (xf4_25_hasAudio) + set.audioBuf.reset(new s16[x28_thpHead.maxAudioSamples * 2]); + } /* Temporary planar YUV decode buffer, resulting planes copied to Boo */ m_yuvBuf.reset(new uint8_t[tjBufSizeYUV(x6c_videoInfo.width, x6c_videoInfo.height, TJ_420)]); @@ -253,14 +335,8 @@ CMoviePlayer::CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bo /* Schedule initial read */ PostDVDReadRequestIfNeeded(); - m_frame[0].m_uv = {0.f, 0.f}; - m_frame[1].m_uv = {0.f, 1.f}; - m_frame[2].m_uv = {1.f, 0.f}; - m_frame[3].m_uv = {1.f, 1.f}; - SetFrame({-0.5f, 0.5f, 0.f}, {-0.5f, -0.5f, 0.f}, {0.5f, -0.5f, 0.f}, {0.5f, 0.5f, 0.f}); - - m_viewVertBlock.finalAssign(m_viewVertBlock); - m_blockBuf->load(&m_viewVertBlock, sizeof(m_viewVertBlock)); + m_hpad = 0.5f; + m_vpad = 0.5f; } void CMoviePlayer::SetStaticAudioVolume(int vol) { @@ -282,99 +358,99 @@ void CMoviePlayer::SetSfxVolume(u8 volume) { SfxVolume = std::min(volume, u8(127 void CMoviePlayer::MixAudio(s16* out, const s16* in, u32 samples) { /* No audio frames ready */ - if (xd4_audioSlot == UINT32_MAX) { - if (in) - memmove(out, in, samples * 4); - else - memset(out, 0, samples * 4); - return; - } - - while (samples) { - CTHPTextureSet* tex = &x80_textures[xd4_audioSlot]; - u32 thisSamples = std::min(tex->audioSamples - tex->playedSamples, samples); - if (!thisSamples) { - /* Advance frame */ - ++xd4_audioSlot; - if (xd4_audioSlot >= x80_textures.size()) - xd4_audioSlot = 0; - tex = &x80_textures[xd4_audioSlot]; - thisSamples = std::min(tex->audioSamples - tex->playedSamples, samples); - } - - if (thisSamples) { - /* mix samples with `in` or no mix */ - if (in) { - for (u32 i = 0; i < thisSamples; ++i, out += 2, in += 2) { - out[0] = DSPSampClamp(in[0] + s32(tex->audioBuf[(i + tex->playedSamples) * 2]) * 0x50F4 / 0x8000 * SfxVolume); - out[1] = - DSPSampClamp(in[1] + s32(tex->audioBuf[(i + tex->playedSamples) * 2 + 1]) * 0x50F4 / 0x8000 * SfxVolume); - } - } else { - for (u32 i = 0; i < thisSamples; ++i, out += 2) { - out[0] = DSPSampClamp(s32(tex->audioBuf[(i + tex->playedSamples) * 2]) * 0x50F4 / 0x8000 * SfxVolume); - out[1] = DSPSampClamp(s32(tex->audioBuf[(i + tex->playedSamples) * 2 + 1]) * 0x50F4 / 0x8000 * SfxVolume); - } - } - tex->playedSamples += thisSamples; - samples -= thisSamples; - } else { - /* metaforce addition: failsafe for buffer overrun */ - if (in) - memmove(out, in, samples * 4); - else - memset(out, 0, samples * 4); - // fprintf(stderr, "dropped %d samples\n", samples); - return; - } - } +// if (xd4_audioSlot == UINT32_MAX) { +// if (in) +// memmove(out, in, samples * 4); +// else +// memset(out, 0, samples * 4); +// return; +// } +// +// while (samples) { +// CTHPTextureSet* tex = &x80_textures[xd4_audioSlot]; +// u32 thisSamples = std::min(tex->audioSamples - tex->playedSamples, samples); +// if (!thisSamples) { +// /* Advance frame */ +// ++xd4_audioSlot; +// if (xd4_audioSlot >= x80_textures.size()) +// xd4_audioSlot = 0; +// tex = &x80_textures[xd4_audioSlot]; +// thisSamples = std::min(tex->audioSamples - tex->playedSamples, samples); +// } +// +// if (thisSamples) { +// /* mix samples with `in` or no mix */ +// if (in) { +// for (u32 i = 0; i < thisSamples; ++i, out += 2, in += 2) { +// out[0] = DSPSampClamp(in[0] + s32(tex->audioBuf[(i + tex->playedSamples) * 2]) * 0x50F4 / 0x8000 * SfxVolume); +// out[1] = +// DSPSampClamp(in[1] + s32(tex->audioBuf[(i + tex->playedSamples) * 2 + 1]) * 0x50F4 / 0x8000 * SfxVolume); +// } +// } else { +// for (u32 i = 0; i < thisSamples; ++i, out += 2) { +// out[0] = DSPSampClamp(s32(tex->audioBuf[(i + tex->playedSamples) * 2]) * 0x50F4 / 0x8000 * SfxVolume); +// out[1] = DSPSampClamp(s32(tex->audioBuf[(i + tex->playedSamples) * 2 + 1]) * 0x50F4 / 0x8000 * SfxVolume); +// } +// } +// tex->playedSamples += thisSamples; +// samples -= thisSamples; +// } else { +// /* metaforce addition: failsafe for buffer overrun */ +// if (in) +// memmove(out, in, samples * 4); +// else +// memset(out, 0, samples * 4); +// // fprintf(stderr, "dropped %d samples\n", samples); +// return; +// } +// } } void CMoviePlayer::MixStaticAudio(s16* out, const s16* in, u32 samples) { - if (!StaticAudio) - return; - while (samples) { - u32 thisSamples = std::min(StaticLoopEnd - StaticAudioOffset, samples); - const u8* thisOffsetLeft = &StaticAudio[StaticAudioOffset / 2]; - const u8* thisOffsetRight = &StaticAudio[StaticAudioSize / 2 + StaticAudioOffset / 2]; - - /* metaforce addition: mix samples with `in` or no mix */ - if (in) { - for (u32 i = 0; i < thisSamples; i += 2) { - out[0] = DSPSampClamp( - in[0] + s32(g721_decoder(thisOffsetLeft[0] & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); - out[1] = DSPSampClamp( - in[1] + s32(g721_decoder(thisOffsetRight[0] & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); - out[2] = DSPSampClamp( - in[2] + s32(g721_decoder(thisOffsetLeft[0] >> 4 & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); - out[3] = DSPSampClamp( - in[3] + s32(g721_decoder(thisOffsetRight[0] >> 4 & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); - thisOffsetLeft += 1; - thisOffsetRight += 1; - out += 4; - in += 4; - } - } else { - for (u32 i = 0; i < thisSamples; i += 2) { - out[0] = - DSPSampClamp(s32(g721_decoder(thisOffsetLeft[0] & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); - out[1] = - DSPSampClamp(s32(g721_decoder(thisOffsetRight[0] & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); - out[2] = DSPSampClamp( - s32(g721_decoder(thisOffsetLeft[0] >> 4 & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); - out[3] = DSPSampClamp( - s32(g721_decoder(thisOffsetRight[0] >> 4 & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); - thisOffsetLeft += 1; - thisOffsetRight += 1; - out += 4; - } - } - - StaticAudioOffset += thisSamples; - if (StaticAudioOffset == StaticLoopEnd) - StaticAudioOffset = StaticLoopBegin; - samples -= thisSamples; - } +// if (!StaticAudio) +// return; +// while (samples) { +// u32 thisSamples = std::min(StaticLoopEnd - StaticAudioOffset, samples); +// const u8* thisOffsetLeft = &StaticAudio[StaticAudioOffset / 2]; +// const u8* thisOffsetRight = &StaticAudio[StaticAudioSize / 2 + StaticAudioOffset / 2]; +// +// /* metaforce addition: mix samples with `in` or no mix */ +// if (in) { +// for (u32 i = 0; i < thisSamples; i += 2) { +// out[0] = DSPSampClamp( +// in[0] + s32(g721_decoder(thisOffsetLeft[0] & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); +// out[1] = DSPSampClamp( +// in[1] + s32(g721_decoder(thisOffsetRight[0] & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); +// out[2] = DSPSampClamp( +// in[2] + s32(g721_decoder(thisOffsetLeft[0] >> 4 & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); +// out[3] = DSPSampClamp( +// in[3] + s32(g721_decoder(thisOffsetRight[0] >> 4 & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); +// thisOffsetLeft += 1; +// thisOffsetRight += 1; +// out += 4; +// in += 4; +// } +// } else { +// for (u32 i = 0; i < thisSamples; i += 2) { +// out[0] = +// DSPSampClamp(s32(g721_decoder(thisOffsetLeft[0] & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); +// out[1] = +// DSPSampClamp(s32(g721_decoder(thisOffsetRight[0] & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); +// out[2] = DSPSampClamp( +// s32(g721_decoder(thisOffsetLeft[0] >> 4 & 0xf, &StaticStateLeft) * StaticVolumeAtten / 0x8000)); +// out[3] = DSPSampClamp( +// s32(g721_decoder(thisOffsetRight[0] >> 4 & 0xf, &StaticStateRight) * StaticVolumeAtten / 0x8000)); +// thisOffsetLeft += 1; +// thisOffsetRight += 1; +// out += 4; +// } +// } +// +// StaticAudioOffset += thisSamples; +// if (StaticAudioOffset == StaticLoopEnd) +// StaticAudioOffset = StaticLoopBegin; +// samples -= thisSamples; +// } } void CMoviePlayer::Rewind() { @@ -399,28 +475,99 @@ void CMoviePlayer::Rewind() { xe8_curSeconds = 0.f; } -void CMoviePlayer::SetFrame(const zeus::CVector3f& a, const zeus::CVector3f& b, const zeus::CVector3f& c, - const zeus::CVector3f& d) { - m_frame[0].m_pos = a; - m_frame[1].m_pos = b; - m_frame[2].m_pos = d; - m_frame[3].m_pos = c; - m_vertBuf->load(m_frame, sizeof(m_frame)); +bool CMoviePlayer::DrawVideo() { + // TODO + // if (!xa0_bufferQueue.empty()) { + // return false; + // } + + g_Renderer->SetDepthReadWrite(false, false); + g_Renderer->SetViewportOrtho(false, -4096.f, 4096.f); + + const s32 vpHeight = CGraphics::GetViewportHeight(); + const s32 vpWidth = CGraphics::GetViewportWidth(); + const s32 vpTop = CGraphics::GetViewportTop(); + const s32 vpLeft = CGraphics::GetViewportLeft(); +#ifdef AURORA + // Scale to full size, maintaining aspect ratio + float vidAspect = static_cast(x6c_videoInfo.width) / static_cast(x6c_videoInfo.height); + const s32 vidWidth = vpHeight * vidAspect; + const s32 vidHeight = vpHeight; +#else + const s32 vidWidth = x6c_videoInfo.width; + const s32 vidHeight = x6c_videoInfo.height; +#endif + const s32 centerX = (vidWidth - vpWidth) / 2; + const s32 centerY = (vidHeight - vpHeight) / 2; + const s32 vl = vpLeft - centerX; + const s32 vr = vpLeft + vpWidth + centerX; + const s32 vb = vpTop + vpHeight + centerY; + const s32 vt = vpTop - centerY; + zeus::CVector3f v1; + zeus::CVector3f v2; + zeus::CVector3f v3; + zeus::CVector3f v4; + v1.x() = vl; + v1.y() = 0.0; + v1.z() = vb; + v2.x() = vr; + v2.y() = 0.0; + v2.z() = vb; + v3.x() = vl; + v3.y() = 0.0; + v3.z() = vt; + v4.x() = vr; + v4.y() = 0.0; + v4.z() = vt; + + DrawFrame(v1, v2, v3, v4); + return true; } -void CMoviePlayer::DrawFrame() { - if (xd0_drawTexSlot == UINT32_MAX) +void CMoviePlayer::DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, + const zeus::CVector3f& v4) { + if (xd0_drawTexSlot == UINT32_MAX || !GetIsFullyCached()) { return; + } SCOPED_GRAPHICS_DEBUG_GROUP("CMoviePlayer::DrawFrame", zeus::skYellow); - /* draw appropriate field */ - CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot]; - CGraphics::SetShaderDataBinding(tex.binding[m_deinterlace ? (xfc_fieldIndex != 0) : 0]); - CGraphics::DrawArray(0, 4); + CGraphics::SetUseVideoFilter(xf4_26_fieldFlip); + + /* Correct movie aspect ratio */ + float hPad, vPad; + if (CGraphics::GetViewportAspect() >= 1.78f) { + hPad = 1.78f / CGraphics::GetViewportAspect(); + vPad = 1.78f / 1.33f; + } else { + hPad = 1.f; + vPad = CGraphics::GetViewportAspect() / 1.33f; + } + + // /* draw appropriate field */ + // CTHPTextureSet& tex = x80_textures[xd0_drawTexSlot]; + // aurora::gfx::queue_movie_player(tex.Y[m_deinterlace ? (xfc_fieldIndex != 0) : 0], tex.U, tex.V, hPad, vPad); + + MyTHPGXYuv2RgbSetup(true /*CGraphics::g_LastFrameUsedAbove*/, xf4_26_fieldFlip); + uintptr_t planeSize = x6c_videoInfo.width * x6c_videoInfo.height; + uintptr_t planeSizeQuarter = planeSize / 4; + MyTHPYuv2RgbTextureSetup(m_yuvBuf.get(), m_yuvBuf.get() + planeSize, m_yuvBuf.get() + planeSize + planeSizeQuarter, + x6c_videoInfo.width, x6c_videoInfo.height); + + CGX::Begin(GX_TRIANGLEFAN, GX_VTXFMT7, 4); + GXPosition3f32(v1); + GXTexCoord2f32(0.f, 0.f); + GXPosition3f32(v3); + GXTexCoord2f32(0.f, 1.f); + GXPosition3f32(v4); + GXTexCoord2f32(1.f, 1.f); + GXPosition3f32(v2); + GXTexCoord2f32(1.f, 0.f); + CGX::End(); + MyTHPGXRestore(); /* ensure second field is being displayed by VI to signal advance * (faked in metaforce with continuous xor) */ - if (!xfc_fieldIndex && CGraphics::g_LastFrameUsedAbove) + if (xfc_fieldIndex == 0 && CGraphics::g_LastFrameUsedAbove) xf4_26_fieldFlip = true; ++xfc_fieldIndex; @@ -530,30 +677,25 @@ void CMoviePlayer::DecodeFromRead(const void* data) { uintptr_t planeSizeHalf = planeSize / 2; uintptr_t planeSizeQuarter = planeSizeHalf / 2; - if (m_deinterlace) { - /* Deinterlace into 2 discrete 60-fps half-res textures */ - u8* mappedData = (u8*)tex.Y[0]->map(planeSizeHalf); - for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) { - memmove(mappedData + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2), - x6c_videoInfo.width); - } - tex.Y[0]->unmap(); - - mappedData = (u8*)tex.Y[1]->map(planeSizeHalf); - for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) { - memmove(mappedData + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2 + 1), - x6c_videoInfo.width); - } - tex.Y[1]->unmap(); - - tex.U->load(m_yuvBuf.get() + planeSize, planeSizeQuarter); - tex.V->load(m_yuvBuf.get() + planeSize + planeSizeQuarter, planeSizeQuarter); - } else { - /* Direct planar load */ - tex.Y[0]->load(m_yuvBuf.get(), planeSize); - tex.U->load(m_yuvBuf.get() + planeSize, planeSizeQuarter); - tex.V->load(m_yuvBuf.get() + planeSize + planeSizeQuarter, planeSizeQuarter); - } + // if (m_deinterlace) { + // /* Deinterlace into 2 discrete 60-fps half-res textures */ + // auto buffer = std::make_unique(planeSizeHalf); + // for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) { + // memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2), + // x6c_videoInfo.width); + // } + // aurora::gfx::write_texture(*tex.Y[0], {buffer.get(), planeSizeHalf}); + // for (unsigned y = 0; y < x6c_videoInfo.height / 2; ++y) { + // memcpy(buffer.get() + x6c_videoInfo.width * y, m_yuvBuf.get() + x6c_videoInfo.width * (y * 2 + 1), + // x6c_videoInfo.width); + // } + // aurora::gfx::write_texture(*tex.Y[1], {buffer.get(), planeSizeHalf}); + // } else { + // /* Direct planar load */ + // aurora::gfx::write_texture(*tex.Y[0], {m_yuvBuf.get(), planeSize}); + // } + // aurora::gfx::write_texture(*tex.U, {m_yuvBuf.get() + planeSize, planeSizeQuarter}); + // aurora::gfx::write_texture(*tex.V, {m_yuvBuf.get() + planeSize + planeSizeQuarter, planeSizeQuarter}); break; } @@ -585,7 +727,7 @@ void CMoviePlayer::ReadCompleted() { /* store params of next read operation */ xb4_nextReadOff += xb0_nextReadSize; - xb0_nextReadSize = hecl::SBig(frameHeader->nextSize); + xb0_nextReadSize = SBig(frameHeader->nextSize); ++xc0_curLoadFrame; if (xc0_curLoadFrame == xf0_preLoadFrames) { diff --git a/Runtime/Graphics/CMoviePlayer.hpp b/Runtime/Graphics/CMoviePlayer.hpp index 606d9ee11..dceebc65b 100644 --- a/Runtime/Graphics/CMoviePlayer.hpp +++ b/Runtime/Graphics/CMoviePlayer.hpp @@ -5,16 +5,13 @@ #include "Runtime/CDvdFile.hpp" #include "Runtime/RetroTypes.hpp" +#include "Runtime/Graphics/CGraphics.hpp" -#include -#include #include #include namespace metaforce { -extern zeus::CMatrix4f g_PlatformMatrix; - class CMoviePlayer : public CDvdFile { public: enum class EPlayMode { Stopped, Playing }; @@ -72,13 +69,12 @@ private: }; struct CTHPTextureSet { - boo::ObjToken Y[2]; - boo::ObjToken U; - boo::ObjToken V; + std::array Y; + GXTexObj U; + GXTexObj V; u32 playedSamples = 0; u32 audioSamples = 0; std::unique_ptr audioBuf; - boo::ObjToken binding[2]; }; std::vector x80_textures; std::unique_ptr x90_requestBuf; @@ -110,36 +106,14 @@ private: u32 xfc_fieldIndex = 0; std::unique_ptr m_yuvBuf; + float m_hpad; + float m_vpad; - struct TexShaderVert { - zeus::CVector3f m_pos; - zeus::CVector2f m_uv; - }; - struct ViewBlock { - zeus::CMatrix4f m_mv; - zeus::CColor m_color = zeus::skWhite; - void setViewRect(const boo::SWindowRect& root, const boo::SWindowRect& sub) { - m_mv[0][0] = 2.0f / root.size[0]; - m_mv[1][1] = 2.0f / root.size[1]; - m_mv[3][0] = sub.location[0] * m_mv[0][0] - 1.0f; - m_mv[3][1] = sub.location[1] * m_mv[1][1] - 1.0f; - } - void finalAssign(const ViewBlock& other) { - m_mv = g_PlatformMatrix * other.m_mv; - m_color = other.m_color; - } - }; - - ViewBlock m_viewVertBlock; - boo::ObjToken m_blockBuf; - boo::ObjToken m_vertBuf; - - TexShaderVert m_frame[4]; + void DecodeFromRead(const void* data); + void PostDVDReadRequestIfNeeded(); + void ReadCompleted(); static u32 THPAudioDecode(s16* buffer, const u8* audioFrame, bool stereo); - void DecodeFromRead(const void* data); - void ReadCompleted(); - void PostDVDReadRequestIfNeeded(); public: CMoviePlayer(const char* path, float preLoadSeconds, bool loop, bool deinterlace); @@ -162,12 +136,14 @@ public: float GetPlayedSeconds() const { return xdc_frameRem + xe8_curSeconds; } float GetTotalSeconds() const { return xe4_totalSeconds; } void SetPlayMode(EPlayMode mode) { xe0_playMode = mode; } - void SetFrame(const zeus::CVector3f& a, const zeus::CVector3f& b, const zeus::CVector3f& c, const zeus::CVector3f& d); - void DrawFrame(); + bool DrawVideo(); + void DrawFrame(const zeus::CVector3f& v1, const zeus::CVector3f& v2, const zeus::CVector3f& v3, + const zeus::CVector3f& v4); void Update(float dt); - std::pair GetVideoDimensions() const { return {x6c_videoInfo.width, x6c_videoInfo.height}; } + u32 GetWidth() const { return x6c_videoInfo.width; } + u32 GetHeight() const { return x6c_videoInfo.width; } - static void Initialize(boo::IGraphicsDataFactory* factory); + static void Initialize(); static void Shutdown(); }; diff --git a/Runtime/Graphics/CPVSAreaSet.cpp b/Runtime/Graphics/CPVSAreaSet.cpp index 450b661d9..fd5bfc4bf 100644 --- a/Runtime/Graphics/CPVSAreaSet.cpp +++ b/Runtime/Graphics/CPVSAreaSet.cpp @@ -1,19 +1,20 @@ #include "Runtime/Graphics/CPVSAreaSet.hpp" +#include "Runtime/Streams/IOStreams.hpp" namespace metaforce { CPVSAreaSet::CPVSAreaSet(const u8* data, u32 len) { CMemoryInStream r(data, len); - x0_numFeatures = r.readUint32Big(); - x4_numLights = r.readUint32Big(); - x8_num2ndLights = r.readUint32Big(); - xc_numActors = r.readUint32Big(); - x10_leafSize = r.readUint32Big(); - x14_lightIndexCount = r.readUint32Big(); + x0_numFeatures = r.ReadLong(); + x4_numLights = r.ReadLong(); + x8_num2ndLights = r.ReadLong(); + xc_numActors = r.ReadLong(); + x10_leafSize = r.ReadLong(); + x14_lightIndexCount = r.ReadLong(); x18_entityIndex.reserve(xc_numActors); for (u32 i = 0; i < xc_numActors; ++i) - x18_entityIndex.push_back(r.readUint32Big()); - x1c_lightLeaves = data + r.position(); + x18_entityIndex.push_back(r.ReadLong()); + x1c_lightLeaves = data + r.GetReadPosition(); const u8* octreeData = x1c_lightLeaves + x14_lightIndexCount * x10_leafSize; x20_octree = CPVSVisOctree::MakePVSVisOctree(octreeData); } diff --git a/Runtime/Graphics/CPVSVisOctree.cpp b/Runtime/Graphics/CPVSVisOctree.cpp index 37391418d..5f04fa6e4 100644 --- a/Runtime/Graphics/CPVSVisOctree.cpp +++ b/Runtime/Graphics/CPVSVisOctree.cpp @@ -1,4 +1,5 @@ #include "Runtime/Graphics/CPVSVisOctree.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include @@ -6,11 +7,11 @@ namespace metaforce { CPVSVisOctree CPVSVisOctree::MakePVSVisOctree(const u8* data) { CMemoryInStream r(data, 68); - const zeus::CAABox aabb = zeus::CAABox::ReadBoundingBoxBig(r); - const u32 numObjects = r.readUint32Big(); - const u32 numLights = r.readUint32Big(); - r.readUint32Big(); - return CPVSVisOctree(aabb, numObjects, numLights, data + r.position()); + const zeus::CAABox aabb = r.Get(); + const u32 numObjects = r.ReadLong(); + const u32 numLights = r.ReadLong(); + r.ReadLong(); + return CPVSVisOctree(aabb, numObjects, numLights, data + r.GetReadPosition()); } CPVSVisOctree::CPVSVisOctree(const zeus::CAABox& aabb, u32 numObjects, u32 numLights, const u8* c) diff --git a/Runtime/Graphics/CPVSVisSet.cpp b/Runtime/Graphics/CPVSVisSet.cpp index f8180a56d..674f612a4 100644 --- a/Runtime/Graphics/CPVSVisSet.cpp +++ b/Runtime/Graphics/CPVSVisSet.cpp @@ -54,7 +54,7 @@ void CPVSVisSet::SetTestPoint(const CPVSVisOctree& octree, const zeus::CVector3f if (nextNodeRel) { /* Skip node data */ if (!(curNode & 0x60)) { - octCur += hecl::SBig(reinterpret_cast(octCur)[nextNodeRel - 1]); + octCur += SBig(reinterpret_cast(octCur)[nextNodeRel - 1]); } else if (curNode & 0x20) { octCur += *(octCur + nextNodeRel - 1); } else { diff --git a/Runtime/Graphics/CPVSVisSet.hpp b/Runtime/Graphics/CPVSVisSet.hpp index ab5fbf19b..35472b406 100644 --- a/Runtime/Graphics/CPVSVisSet.hpp +++ b/Runtime/Graphics/CPVSVisSet.hpp @@ -1,6 +1,7 @@ #pragma once #include "Runtime/RetroTypes.hpp" + #include namespace metaforce { @@ -21,6 +22,7 @@ public: EPVSVisSetState GetVisible(u32 idx) const; void SetFromMemory(u32 numBits, u32 numLights, const u8* leafPtr); void SetTestPoint(const CPVSVisOctree& octree, const zeus::CVector3f&); + void SetState(EPVSVisSetState state) { x0_state = state; } }; } // namespace metaforce diff --git a/Runtime/Graphics/CRainSplashGenerator.cpp b/Runtime/Graphics/CRainSplashGenerator.cpp index 0dc3895c7..468ee4613 100644 --- a/Runtime/Graphics/CRainSplashGenerator.cpp +++ b/Runtime/Graphics/CRainSplashGenerator.cpp @@ -2,7 +2,7 @@ #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/World/CWorld.hpp" namespace metaforce { @@ -13,11 +13,8 @@ CRainSplashGenerator::CRainSplashGenerator(const zeus::CVector3f& scale, u32 max x30_alpha = std::min(1.f, alpha); x44_genRate = std::min(maxSplashes, genRate); x0_rainSplashes.reserve(maxSplashes); - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - for (u32 i = 0; i < maxSplashes; ++i) - x0_rainSplashes.emplace_back(ctx); - return true; - } BooTrace); + for (u32 i = 0; i < maxSplashes; ++i) + x0_rainSplashes.emplace_back(); } void CRainSplashGenerator::SSplashLine::Draw(float alpha, float dt, const zeus::CVector3f& pos) { @@ -33,7 +30,7 @@ void CRainSplashGenerator::SSplashLine::Draw(float alpha, float dt, const zeus:: vt += delta; m_renderer.AddVertex(vec, zeus::CColor(1.f, vertAlpha), 1); } - m_renderer.Render(g_Renderer->IsThermalVisorHotPass()); + // m_renderer.Render(g_Renderer->IsThermalVisorHotPass()); } } @@ -73,12 +70,11 @@ void CRainSplashGenerator::Draw(const zeus::CTransform& xf) { DoDraw(xf); } -CRainSplashGenerator::SSplashLine::SSplashLine(boo::IGraphicsDataFactory::Context& ctx) -: m_renderer(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 3, nullptr, false) {} +CRainSplashGenerator::SSplashLine::SSplashLine() : m_renderer(CLineRenderer::EPrimitiveMode::LineStrip, 3, {}, false) {} -CRainSplashGenerator::SRainSplash::SRainSplash(boo::IGraphicsDataFactory::Context& ctx) { +CRainSplashGenerator::SRainSplash::SRainSplash() { for (size_t i = 0; i < x0_lines.capacity(); ++i) { - x0_lines.emplace_back(ctx); + x0_lines.emplace_back(); } } @@ -149,16 +145,16 @@ void CRainSplashGenerator::Update(float dt, CStateManager& mgr) { } } -u32 CRainSplashGenerator::GetNextBestPt(u32 pt, const std::vector>& vn, - CRandom16& rand, float minZ) { - const auto& refVert = vn[pt]; +u32 CRainSplashGenerator::GetNextBestPt(u32 pt, const SSkinningWorkspace& workspace, CRandom16& rand, float minZ) { + const auto& refVert = workspace.m_vertexWorkspace[pt]; float maxDist = 0.f; u32 nextPt = pt; for (int i = 0; i < 3; ++i) { - const auto idx = u32(rand.Range(0, int(vn.size() - 1))); - const auto& vert = vn[idx]; - const float distSq = (refVert.first - vert.first).magSquared(); - if (distSq > maxDist && vert.second.dot(zeus::skUp) >= 0.f && (vert.first.z() <= 0.f || vert.first.z() > minZ)) { + const auto idx = u32(rand.Range(0, int(workspace.m_vertexWorkspace.size() - 1))); + const auto& vert = workspace.m_vertexWorkspace[idx]; + const auto& norm = workspace.m_normalWorkspace[idx]; + const float distSq = (refVert - vert).magSquared(); + if (distSq > maxDist && norm.dot(zeus::skUp) >= 0.f && (vert.z() <= 0.f || vert.z() > minZ)) { nextPt = idx; maxDist = distSq; } @@ -180,7 +176,7 @@ void CRainSplashGenerator::AddPoint(const zeus::CVector3f& pos) { x38_queueTail += 1; } -void CRainSplashGenerator::GeneratePoints(const std::vector>& vn) { +void CRainSplashGenerator::GeneratePoints(const SSkinningWorkspace& workspace) { if (!x48_25_raining) return; @@ -188,8 +184,8 @@ void CRainSplashGenerator::GeneratePoints(const std::vector= x0_rainSplashes.size()) break; - x34_curPoint = GetNextBestPt(x34_curPoint, vn, x10_random, x2c_minZ); - AddPoint(x14_scale * vn[x34_curPoint].first); + x34_curPoint = GetNextBestPt(x34_curPoint, workspace, x10_random, x2c_minZ); + AddPoint(x14_scale * workspace.m_vertexWorkspace[x34_curPoint]); } x20_generateTimer = 0.f; } diff --git a/Runtime/Graphics/CRainSplashGenerator.hpp b/Runtime/Graphics/CRainSplashGenerator.hpp index 37e9fe1f7..41e6cffa5 100644 --- a/Runtime/Graphics/CRainSplashGenerator.hpp +++ b/Runtime/Graphics/CRainSplashGenerator.hpp @@ -7,6 +7,7 @@ #include "Runtime/RetroTypes.hpp" #include "Runtime/rstl.hpp" #include "Runtime/Graphics/CLineRenderer.hpp" +#include "Runtime/Graphics/CSkinnedModel.hpp" #include @@ -24,7 +25,7 @@ class CRainSplashGenerator { u8 x15_length = 1; bool x16_active = true; // used to be one-bit bitfield CLineRenderer m_renderer; - explicit SSplashLine(boo::IGraphicsDataFactory::Context& ctx); + explicit SSplashLine(); void Update(float dt, CStateManager& mgr); void Draw(float alpha, float dt, const zeus::CVector3f& pos); void SetActive() { x16_active = true; } @@ -33,7 +34,7 @@ class CRainSplashGenerator { rstl::reserved_vector x0_lines; zeus::CVector3f x64_pos; float x70_ = 0.f; - explicit SRainSplash(boo::IGraphicsDataFactory::Context& ctx); + explicit SRainSplash(); SRainSplash(const SRainSplash&) = delete; SRainSplash& operator=(const SRainSplash&) = delete; SRainSplash(SRainSplash&&) = default; @@ -61,14 +62,13 @@ class CRainSplashGenerator { void UpdateRainSplashRange(CStateManager& mgr, int start, int end, float dt); void UpdateRainSplashes(CStateManager& mgr, float magnitude, float dt); void DoDraw(const zeus::CTransform& xf); - static u32 GetNextBestPt(u32 pt, const std::vector>& vn, CRandom16& rand, - float minZ); + static u32 GetNextBestPt(u32 pt, const SSkinningWorkspace& workspace, CRandom16& rand, float minZ); void AddPoint(const zeus::CVector3f& pos); public: CRainSplashGenerator(const zeus::CVector3f& scale, u32 maxSplashes, u32 genRate, float minZ, float alpha); void Update(float dt, CStateManager& mgr); - void GeneratePoints(const std::vector>& vn); + void GeneratePoints(const SSkinningWorkspace& workspace); void Draw(const zeus::CTransform& xf); bool IsRaining() const { return x48_25_raining; } }; diff --git a/Runtime/Graphics/CSimpleShadow.cpp b/Runtime/Graphics/CSimpleShadow.cpp index 5048a9103..ceb2f37f0 100644 --- a/Runtime/Graphics/CSimpleShadow.cpp +++ b/Runtime/Graphics/CSimpleShadow.cpp @@ -19,29 +19,39 @@ zeus::CAABox CSimpleShadow::GetMaxShadowBox(const zeus::CAABox& aabb) const { zeus::CAABox CSimpleShadow::GetBounds() const { float extent = x34_radius * x30_scale; - return {{x0_xf.origin.x() - extent, x0_xf.origin.y() - extent, x0_xf.origin.z() - extent}, - {x0_xf.origin.x() + extent, x0_xf.origin.y() + extent, x0_xf.origin.z() + extent}}; + return { + {x0_xf.origin.x() - extent, x0_xf.origin.y() - extent, x0_xf.origin.z() - extent}, + {x0_xf.origin.x() + extent, x0_xf.origin.y() + extent, x0_xf.origin.z() + extent}, + }; } -void CSimpleShadow::Render(const TLockedToken& tex) { +void CSimpleShadow::Render(TLockedToken& tex) { if (!x48_24_collision) return; SCOPED_GRAPHICS_DEBUG_GROUP("CSimpleShadow::Render", zeus::skGrey); CGraphics::DisableAllLights(); CGraphics::SetModelMatrix(x0_xf); + tex->Load(GX_TEXMAP0, EClampMode::Repeat); - if (!m_filter || m_filter->GetTex().GetObj() != tex.GetObj()) - m_filter.emplace(EFilterType::InvDstMultiply, tex, CTexturedQuadFilter::ZTest::LEqual); - + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); + CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, false); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + CGraphics::StreamBegin(GX_QUADS); float radius = x34_radius * x30_scale; - const std::array verts{{ - {{-radius, 0.f, -radius}, {0.f, 0.f}}, - {{radius, 0.f, -radius}, {0.f, 1.f}}, - {{-radius, 0.f, radius}, {1.f, 0.f}}, - {{radius, 0.f, radius}, {1.f, 1.f}}, - }}; - m_filter->drawVerts(zeus::skWhite, verts); + CGraphics::StreamColor(zeus::CColor{1.f, x3c_heightAlpha * x38_userAlpha}); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex(-radius, 0.f, -radius); + CGraphics::StreamTexcoord(0.f, 1.f); + CGraphics::StreamVertex(radius, 0.f, -radius); + CGraphics::StreamTexcoord(1.f, 1.f); + CGraphics::StreamVertex(radius, 0.f, radius); + CGraphics::StreamTexcoord(1.f, 0.f); + CGraphics::StreamVertex(-radius, 0.f, radius); + CGraphics::StreamEnd(); } void CSimpleShadow::Calculate(const zeus::CAABox& aabb, const zeus::CTransform& xf, const CStateManager& mgr) { @@ -57,8 +67,10 @@ void CSimpleShadow::Calculate(const zeus::CAABox& aabb, const zeus::CTransform& } if (height > 0.1f + halfHeight) { - TUniqueId cid = kInvalidUniqueId; EntityList nearList; + mgr.BuildNearList(nearList, pos, zeus::skDown, x40_maxObjHeight, CMaterialFilter::MakeInclude(CMaterialList(EMaterialTypes::Floor)), nullptr); + + TUniqueId cid = kInvalidUniqueId; CRayCastResult resD = CGameCollision::RayDynamicIntersection(mgr, cid, pos, zeus::skDown, x40_maxObjHeight, CMaterialFilter::skPassEverything, nearList); if (resD.IsValid() && resD.GetT() < height) { diff --git a/Runtime/Graphics/CSimpleShadow.hpp b/Runtime/Graphics/CSimpleShadow.hpp index acf8827e5..cfa1d72f1 100644 --- a/Runtime/Graphics/CSimpleShadow.hpp +++ b/Runtime/Graphics/CSimpleShadow.hpp @@ -1,8 +1,9 @@ #pragma once -#include +#include "Runtime/CToken.hpp" +#include "Runtime/Graphics/CTexture.hpp" -#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" +#include #include #include @@ -22,18 +23,17 @@ class CSimpleShadow { bool x48_24_collision : 1 = false; bool x48_25_alwaysCalculateRadius : 1 = true; bool x48_26_radiusCalculated : 1 = false; - std::optional m_filter; public: CSimpleShadow(float scale, float userAlpha, float maxObjHeight, float displacement); bool Valid() const { return x48_24_collision; } zeus::CAABox GetMaxShadowBox(const zeus::CAABox& aabb) const; zeus::CAABox GetBounds() const; - void SetAlwaysCalculateRadius(bool) { x48_25_alwaysCalculateRadius = true; } + void SetAlwaysCalculateRadius(bool b) { x48_25_alwaysCalculateRadius = b; } float GetMaxObjectHeight() const { return x40_maxObjHeight; } void SetUserAlpha(float a) { x38_userAlpha = a; } const zeus::CTransform& GetTransform() const { return x0_xf; } - void Render(const TLockedToken& tex); + void Render(TLockedToken& tex); void Calculate(const zeus::CAABox& aabb, const zeus::CTransform& xf, const CStateManager& mgr); }; } // namespace metaforce diff --git a/Runtime/Graphics/CSkinnedModel.cpp b/Runtime/Graphics/CSkinnedModel.cpp index 65eba6f43..0ffa5b318 100644 --- a/Runtime/Graphics/CSkinnedModel.cpp +++ b/Runtime/Graphics/CSkinnedModel.cpp @@ -1,16 +1,21 @@ #include "Runtime/Graphics/CSkinnedModel.hpp" #include "Runtime/Character/CSkinRules.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CVertexMorphEffect.hpp" #include +#include namespace metaforce { static logvisor::Module Log("metaforce::CSkinnedModel"); -CSkinnedModel::CSkinnedModel(TLockedToken model, TLockedToken skinRules, - TLockedToken layoutInfo, int shaderIdx, int drawInsts) -: x4_model(std::move(model)), x10_skinRules(std::move(skinRules)), x1c_layoutInfo(std::move(layoutInfo)) { +CSkinnedModel::CSkinnedModel(const TLockedToken& model, const TLockedToken& skinRules, + const TLockedToken& layoutInfo) +: x4_model(std::move(model)) +, x10_skinRules(std::move(skinRules)) +, x1c_layoutInfo(std::move(layoutInfo)) +, m_workspace(*x10_skinRules) { if (!x4_model) { Log.report(logvisor::Fatal, FMT_STRING("bad model token provided to CSkinnedModel")); } @@ -20,48 +25,116 @@ CSkinnedModel::CSkinnedModel(TLockedToken model, TLockedTokenMakeNewInstance(shaderIdx, drawInsts); } -CSkinnedModel::CSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo, - int shaderIdx, int drawInsts) +CSkinnedModel::CSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo) : CSkinnedModel(store.GetObj(SObjectTag{FOURCC('CMDL'), model}), store.GetObj(SObjectTag{FOURCC('CSKR'), skinRules}), - store.GetObj(SObjectTag{FOURCC('CINF'), layoutInfo}), shaderIdx, drawInsts) {} + store.GetObj(SObjectTag{FOURCC('CINF'), layoutInfo})) {} -void CSkinnedModel::Calculate(const CPoseAsTransforms& pose, const CModelFlags& drawFlags, - const std::optional& morphEffect, const float* morphMagnitudes) { - if (morphEffect || g_PointGenFunc) { - if (boo::ObjToken vertBuf = m_modelInst->UpdateUniformData(drawFlags, nullptr, nullptr)) { - x10_skinRules->TransformVerticesCPU(m_vertWorkspace, pose, *x4_model); - if (morphEffect) - morphEffect->MorphVertices(m_vertWorkspace, morphMagnitudes, x10_skinRules, pose); - if (g_PointGenFunc) - g_PointGenFunc(g_PointGenCtx, m_vertWorkspace); - x4_model->ApplyVerticesCPU(vertBuf, m_vertWorkspace); - m_modifiedVBO = true; +void CSkinnedModel::AllocateStorage() { + if (x34_owned) { + m_workspace.Reset(*x10_skinRules); + } +} + +void CSkinnedModel::Calculate(const CPoseAsTransforms& pose, CVertexMorphEffect* morphEffect, + TConstVectorRef averagedNormals, SSkinningWorkspace* workspace) { + if (workspace == nullptr) { + if (x35_disableWorkspaces) { + x10_skinRules->BuildAccumulatedTransforms(pose, *x1c_layoutInfo); + return; } + AllocateStorage(); + workspace = &m_workspace; } else { - if (boo::ObjToken vertBuf = - m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose)) { - if (m_modifiedVBO) { - x4_model->RestoreVerticesCPU(vertBuf); - m_modifiedVBO = false; + workspace->Reset(*x10_skinRules); + } + + x10_skinRules->BuildAccumulatedTransforms(pose, *x1c_layoutInfo); + x10_skinRules->BuildPoints(x4_model->GetPositions(), &workspace->m_vertexWorkspace); + x10_skinRules->BuildNormals(x4_model->GetNormals(), &workspace->m_normalWorkspace); + + if (morphEffect) { + morphEffect->MorphVertices(*workspace, averagedNormals, x10_skinRules, pose, x10_skinRules->GetVertexCount()); + } + if (g_PointGenFunc != nullptr) { + g_PointGenFunc(*workspace); + } +} + +void CSkinnedModel::Draw(TConstVectorRef verts, TConstVectorRef norms, const CModelFlags& drawFlags) { + OPTICK_EVENT(); + x4_model->Draw(verts, norms, drawFlags); + // PostDrawFunc(); +} + +void CSkinnedModel::Draw(const CModelFlags& drawFlags) { + if (x35_disableWorkspaces) { + const auto mtx = CGraphics::g_GXModelMatrix; + CGraphics::SetModelMatrix(mtx * x10_skinRules->x0_bones.front().x20_xf); + x4_model->Draw(drawFlags); + CGraphics::SetModelMatrix(mtx); + } else if (m_workspace.IsEmpty()) { + x4_model->Draw(drawFlags); + } else { + x4_model->Draw(&m_workspace.m_vertexWorkspace, &m_workspace.m_normalWorkspace, drawFlags); + // PostDrawFunc(); + } +} + +void CSkinnedModel::DoDrawCallback(const FCustomDraw& func) const { + if (x35_disableWorkspaces) { + const auto mtx = CGraphics::g_GXModelMatrix; + CGraphics::SetModelMatrix(mtx * x10_skinRules->x0_bones.front().x20_xf); + func(x4_model->GetPositions(), x4_model->GetNormals()); + CGraphics::SetModelMatrix(mtx); + } else if (m_workspace.IsEmpty()) { + func(x4_model->GetPositions(), x4_model->GetNormals()); + } else { + func(&m_workspace.m_vertexWorkspace, &m_workspace.m_normalWorkspace); + // PostDrawFunc(); + } +} + +void CSkinnedModel::CalculateDefault() { m_workspace.Clear(); } + +SSkinningWorkspace CSkinnedModel::CloneWorkspace() { return m_workspace; } + +CSkinnedModelWithAvgNormals::CSkinnedModelWithAvgNormals(IObjectStore& store, CAssetId model, CAssetId skinRules, + CAssetId layoutInfo) +: CSkinnedModel(store, model, skinRules, layoutInfo) { + const auto vertexCount = GetSkinRules()->GetVertexCount(); + const auto& modelPositions = *GetModel()->GetPositions(); + + x40_averagedNormals.resize(vertexCount); + std::vector>> vertMap; + for (int vertIdx = 0; vertIdx < vertexCount; ++vertIdx) { + const auto curPos = modelPositions[vertIdx]; + if (std::find_if(vertMap.cbegin(), vertMap.cend(), [=](const auto& pair) { return pair.first.isEqu(curPos); }) == + vertMap.cend()) { + auto& [_, list] = vertMap.emplace_back(curPos, std::list{}); + for (int idx = vertIdx; idx < vertexCount; ++idx) { + // Originally uses ==, but adjusted to match above + if (modelPositions[idx].isEqu(curPos)) { + list.emplace_back(idx); + } } } } + + const auto& modelNormals = *GetModel()->GetNormals(); + for (const auto& [_, idxs] : vertMap) { + zeus::CVector3f averagedNormal; + for (const auto idx : idxs) { + averagedNormal += modelNormals[idx]; + } + averagedNormal.normalize(); + for (const auto idx : idxs) { + x40_averagedNormals[idx] = averagedNormal; + } + } } -void CSkinnedModel::Draw(const CModelFlags& drawFlags) const { - OPTICK_EVENT(); - if (m_modelInst->TryLockTextures()) - m_modelInst->DrawSurfaces(drawFlags); -} - -CMorphableSkinnedModel::CMorphableSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, - CAssetId layoutInfo, int shaderIdx, int drawInsts) -: CSkinnedModel(store, model, skinRules, layoutInfo, shaderIdx, drawInsts) {} - -CSkinnedModel::FPointGenerator CSkinnedModel::g_PointGenFunc = nullptr; -void* CSkinnedModel::g_PointGenCtx = nullptr; +FPointGenerator CSkinnedModel::g_PointGenFunc; } // namespace metaforce diff --git a/Runtime/Graphics/CSkinnedModel.hpp b/Runtime/Graphics/CSkinnedModel.hpp index e977c1078..cad58db5a 100644 --- a/Runtime/Graphics/CSkinnedModel.hpp +++ b/Runtime/Graphics/CSkinnedModel.hpp @@ -18,52 +18,78 @@ class CPoseAsTransforms; class CVertexMorphEffect; class IObjectStore; +// Originally vert + normal workspaces were allocated together, but here separated for ease of use +struct SSkinningWorkspace { + std::vector m_vertexWorkspace; + std::vector m_normalWorkspace; + + SSkinningWorkspace(const CSkinRules& rules) { Reset(rules); } + void Reset(const CSkinRules& rules) { + m_vertexWorkspace.clear(); + m_normalWorkspace.clear(); + m_vertexWorkspace.reserve(rules.GetVertexCount()); + m_normalWorkspace.reserve(rules.GetNormalCount()); + } + void Clear() { + m_vertexWorkspace.clear(); + m_normalWorkspace.clear(); + } + [[nodiscard]] bool IsEmpty() const { return m_vertexWorkspace.empty() || m_normalWorkspace.empty(); } +}; + +// Lambda instead of userdata pointer +using FCustomDraw = std::function; +using FPointGenerator = std::function; + class CSkinnedModel { - friend class CBooModel; - std::unique_ptr m_modelInst; TLockedToken x4_model; TLockedToken x10_skinRules; TLockedToken x1c_layoutInfo; - std::vector> m_vertWorkspace; - bool m_modifiedVBO = false; + // rstl::auto_ptr x24_vertWorkspace; + // rstl::auto_ptr x2c_normalWorkspace; + SSkinningWorkspace m_workspace; + bool x34_owned = true; + bool x35_disableWorkspaces = false; public: - enum class EDataOwnership { Zero, One }; - CSkinnedModel(TLockedToken model, TLockedToken skinRules, - TLockedToken layoutInfo, int shaderIdx, int drawInsts); - CSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo, int shaderIdx, - int drawInsts); - std::unique_ptr Clone(int shaderIdx = 0, int drawInsts = 1) const { - return std::make_unique(x4_model, x10_skinRules, x1c_layoutInfo, shaderIdx, drawInsts); - } + enum class EDataOwnership { Unowned, Owned }; + CSkinnedModel(const TLockedToken& model, const TLockedToken& skinRules, + const TLockedToken& layoutInfo /*, EDataOwnership ownership*/); + CSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo); + virtual ~CSkinnedModel() = default; + TLockedToken& GetModel() { return x4_model; } const TLockedToken& GetModel() const { return x4_model; } - const std::unique_ptr& GetModelInst() const { return m_modelInst; } const TLockedToken& GetSkinRules() const { return x10_skinRules; } void SetLayoutInfo(const TLockedToken& inf) { x1c_layoutInfo = inf; } const TLockedToken& GetLayoutInfo() const { return x1c_layoutInfo; } - void Calculate(const CPoseAsTransforms& pose, const CModelFlags& drawFlags, - const std::optional& morphEffect, const float* morphMagnitudes); - void Draw(const CModelFlags& drawFlags) const; + void AllocateStorage(); + // Metaforce addition: Originally morphEffect is rstl::optional_object* + // This prevents constructing it as a reference to the held pointer in CPatterned, thus in + // retail it's copied in every invocation of RenderIceModelWithFlags. + void Calculate(const CPoseAsTransforms& pose, CVertexMorphEffect* morphEffect, TConstVectorRef averagedNormals, + SSkinningWorkspace* workspace); + void Draw(TConstVectorRef verts, TConstVectorRef normals, const CModelFlags& drawFlags); + void Draw(const CModelFlags& drawFlags); + void DoDrawCallback(const FCustomDraw& func) const; + void CalculateDefault(); + // Originally returns cloned vertex workspace, with arg for cloned normal workspace + SSkinningWorkspace CloneWorkspace(); - using FPointGenerator = void (*)(void* item, const std::vector>& vn); - static void SetPointGeneratorFunc(void* ctx, FPointGenerator func) { - g_PointGenFunc = func; - g_PointGenCtx = ctx; - } + static void SetPointGeneratorFunc(FPointGenerator func) { g_PointGenFunc = std::move(func); } static void ClearPointGeneratorFunc() { g_PointGenFunc = nullptr; } static FPointGenerator g_PointGenFunc; - static void* g_PointGenCtx; }; -class CMorphableSkinnedModel : public CSkinnedModel { - std::unique_ptr x40_morphMagnitudes; +class CSkinnedModelWithAvgNormals : public CSkinnedModel { + std::vector x40_averagedNormals; // was rstl::auto_ptr public: - CMorphableSkinnedModel(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo, int shaderIdx, - int drawInsts); - const float* GetMorphMagnitudes() const { return x40_morphMagnitudes.get(); } + CSkinnedModelWithAvgNormals(IObjectStore& store, CAssetId model, CAssetId skinRules, CAssetId layoutInfo); + ~CSkinnedModelWithAvgNormals() override = default; + + TConstVectorRef GetAveragedNormals() const { return &x40_averagedNormals; } }; } // namespace metaforce diff --git a/Runtime/Graphics/CTevCombiners.cpp b/Runtime/Graphics/CTevCombiners.cpp new file mode 100644 index 000000000..5afc6e185 --- /dev/null +++ b/Runtime/Graphics/CTevCombiners.cpp @@ -0,0 +1,114 @@ +#include "Graphics/CTevCombiners.hpp" + +#include "Graphics/CGX.hpp" + +namespace metaforce::CTevCombiners { +u32 CTevPass::sNextUniquePass = 0; + +void CTevPass::Execute(ERglTevStage stage) const { + const auto stageId = GXTevStageID(stage); + CGX::SetTevColorIn(stageId, x4_colorPass.x0_a, x4_colorPass.x4_b, x4_colorPass.x8_c, x4_colorPass.xc_d); + CGX::SetTevAlphaIn(stageId, x14_alphaPass.x0_a, x14_alphaPass.x4_b, x14_alphaPass.x8_c, x14_alphaPass.xc_d); + CGX::SetTevColorOp(stageId, x24_colorOp.x4_op, x24_colorOp.x8_bias, x24_colorOp.xc_scale, x24_colorOp.x0_clamp, + x24_colorOp.x10_regId); + CGX::SetTevAlphaOp(stageId, x38_alphaOp.x4_op, x38_alphaOp.x8_bias, x38_alphaOp.xc_scale, x38_alphaOp.x0_clamp, + x38_alphaOp.x10_regId); + CGX::SetTevKColorSel(stageId, GX_TEV_KCSEL_8_8); + CGX::SetTevKAlphaSel(stageId, GX_TEV_KASEL_8_8); +} + +constexpr u32 maxTevPasses = 2; +static u32 sNumEnabledPasses; +static std::array sValidPasses; + +const CTevPass kEnvPassthru{ + {GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC}, + {GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA}, +}; +const CTevPass kEnvBlendCTandCConCF{ + {GX_CC_C0, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO}, + {GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA}, +}; +const CTevPass kEnvModulateConstColor{ + {GX_CC_ZERO, GX_CC_RASC, GX_CC_C0, GX_CC_ZERO}, + {GX_CA_ZERO, GX_CA_RASA, GX_CA_A0, GX_CA_ZERO}, +}; +const CTevPass kEnvConstColor{ + {GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0}, + {GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0}, +}; +const CTevPass kEnvModulate{ + {GX_CC_ZERO, GX_CC_RASC, GX_CC_TEXC, GX_CC_ZERO}, + {GX_CA_ZERO, GX_CA_RASA, GX_CA_TEXA, GX_CA_ZERO}, +}; +const CTevPass kEnvDecal{ + {GX_CC_RASC, GX_CC_TEXC, GX_CC_TEXA, GX_CC_ZERO}, + {GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_RASA}, +}; +const CTevPass kEnvBlend{ + {GX_CC_RASC, GX_CC_ONE, GX_CC_TEXC, GX_CC_ZERO}, + {GX_CA_ZERO, GX_CA_TEXA, GX_CA_RASA, GX_CA_ZERO}, +}; +const CTevPass kEnvReplace{ + {GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC}, + {GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA}, +}; +const CTevPass kEnvModulateAlpha{ + {GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC}, + {GX_CA_ZERO, GX_CA_TEXA, GX_CA_RASA, GX_CA_ZERO}, +}; +const CTevPass kEnvModulateColor{ + {GX_CC_ZERO, GX_CC_TEXC, GX_CC_RASC, GX_CC_ZERO}, + {GX_CA_ZERO, GX_CA_KONST, GX_CA_RASA, GX_CA_ZERO}, +}; +const CTevPass kEnvModulateColorByAlpha{ + {GX_CC_ZERO, GX_CC_CPREV, GX_CC_APREV, GX_CC_ZERO}, + {GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV}, +}; + +void Init() { + sNumEnabledPasses = maxTevPasses; + sValidPasses.fill(true); + for (int i = 0; i < maxTevPasses; ++i) { + DeletePass(static_cast(i)); + } + sValidPasses.fill(false); + RecomputePasses(); +} + +void SetupPass(ERglTevStage stage, const CTevPass& pass) { + if (pass == kEnvPassthru) { + DeletePass(stage); + return; + } + if (SetPassCombiners(stage, pass)) { + sValidPasses[static_cast(stage)] = true; + RecomputePasses(); + } +} + +void DeletePass(ERglTevStage stage) { + SetPassCombiners(stage, kEnvPassthru); + sValidPasses[static_cast(stage)] = false; + RecomputePasses(); +} + +bool SetPassCombiners(ERglTevStage stage, const CTevPass& pass) { + pass.Execute(stage); + return true; +} + +void RecomputePasses() { + u8 tmp = static_cast((sValidPasses[maxTevPasses - 1] != 0)); + tmp++; + sNumEnabledPasses = tmp; + CGX::SetNumTevStages(tmp); +} + +void ResetStates() { + sValidPasses.fill(false); + kEnvPassthru.Execute(ERglTevStage::Stage0); + sNumEnabledPasses = 1; + CGX::SetNumTevStages(1); +} +} // namespace metaforce::CTevCombiners diff --git a/Runtime/Graphics/CTevCombiners.hpp b/Runtime/Graphics/CTevCombiners.hpp new file mode 100644 index 000000000..91087f25f --- /dev/null +++ b/Runtime/Graphics/CTevCombiners.hpp @@ -0,0 +1,126 @@ +#pragma once + +#include "Graphics/GX.hpp" +#include "RetroTypes.hpp" + +namespace metaforce { +enum class ERglTevStage : std::underlying_type_t { + Stage0 = GX_TEVSTAGE0, + Stage1 = GX_TEVSTAGE1, + Stage2 = GX_TEVSTAGE2, + Stage3 = GX_TEVSTAGE3, + Stage4 = GX_TEVSTAGE4, + Stage5 = GX_TEVSTAGE5, + Stage6 = GX_TEVSTAGE6, + Stage7 = GX_TEVSTAGE7, + Stage8 = GX_TEVSTAGE8, + Stage9 = GX_TEVSTAGE9, + Stage10 = GX_TEVSTAGE10, + Stage11 = GX_TEVSTAGE11, + Stage12 = GX_TEVSTAGE12, + Stage13 = GX_TEVSTAGE13, + Stage14 = GX_TEVSTAGE14, + Stage15 = GX_TEVSTAGE15, + Max = GX_MAX_TEVSTAGE, +}; + +namespace CTevCombiners { +struct CTevOp { + bool x0_clamp = true; + GXTevOp x4_op = GX_TEV_ADD; + GXTevBias x8_bias = GX_TB_ZERO; + GXTevScale xc_scale = GX_CS_SCALE_1; + GXTevRegID x10_regId = GX_TEVPREV; + + constexpr CTevOp() = default; + constexpr CTevOp(bool clamp, GXTevOp op, GXTevBias bias, GXTevScale scale, GXTevRegID regId) + : x0_clamp(clamp), x4_op(op), x8_bias(bias), xc_scale(scale), x10_regId(regId) {} + constexpr CTevOp(u32 compressedDesc) + : x0_clamp((compressedDesc >> 8 & 1) != 0) + , x4_op(static_cast(compressedDesc & 0xF)) + , x8_bias(static_cast(compressedDesc >> 4 & 3)) + , xc_scale(static_cast(compressedDesc >> 6 & 3)) + , x10_regId(static_cast(compressedDesc >> 9 & 3)) {} + + bool operator==(const CTevOp& rhs) const { + return x0_clamp == rhs.x0_clamp && x4_op == rhs.x4_op && x8_bias == rhs.x8_bias && xc_scale == rhs.xc_scale; + } +}; +struct ColorPass { + GXTevColorArg x0_a; + GXTevColorArg x4_b; + GXTevColorArg x8_c; + GXTevColorArg xc_d; + + constexpr ColorPass(GXTevColorArg a, GXTevColorArg b, GXTevColorArg c, GXTevColorArg d) + : x0_a(a), x4_b(b), x8_c(c), xc_d(d) {} + constexpr ColorPass(u32 compressedDesc) + : x0_a(static_cast(compressedDesc & 0x1F)) + , x4_b(static_cast(compressedDesc >> 5 & 0x1F)) + , x8_c(static_cast(compressedDesc >> 10 & 0x1F)) + , xc_d(static_cast(compressedDesc >> 15 & 0x1F)) {} + + bool operator==(const ColorPass& rhs) const { return memcmp(this, &rhs, sizeof(*this)) == 0; } +}; +struct AlphaPass { + GXTevAlphaArg x0_a; + GXTevAlphaArg x4_b; + GXTevAlphaArg x8_c; + GXTevAlphaArg xc_d; + + constexpr AlphaPass(GXTevAlphaArg a, GXTevAlphaArg b, GXTevAlphaArg c, GXTevAlphaArg d) + : x0_a(a), x4_b(b), x8_c(c), xc_d(d) {} + constexpr AlphaPass(u32 compressedDesc) + : x0_a(static_cast(compressedDesc & 0x1F)) + , x4_b(static_cast(compressedDesc >> 5 & 0x1F)) + , x8_c(static_cast(compressedDesc >> 10 & 0x1F)) + , xc_d(static_cast(compressedDesc >> 15 & 0x1F)) {} + + bool operator==(const AlphaPass& rhs) const { return memcmp(this, &rhs, sizeof(*this)) == 0; } +}; +class CTevPass { + u32 x0_id; + ColorPass x4_colorPass; + AlphaPass x14_alphaPass; + CTevOp x24_colorOp; + CTevOp x38_alphaOp; + + static u32 sNextUniquePass; + +public: + CTevPass(const ColorPass& colPass, const AlphaPass& alphaPass, const CTevOp& colorOp = {}, const CTevOp& alphaOp = {}) + : x0_id(++sNextUniquePass) + , x4_colorPass(colPass) + , x14_alphaPass(alphaPass) + , x24_colorOp(colorOp) + , x38_alphaOp(alphaOp) {} + + void Execute(ERglTevStage stage) const; + + bool operator==(const CTevPass& rhs) const { + return x0_id == rhs.x0_id && x4_colorPass == rhs.x4_colorPass && x14_alphaPass == rhs.x14_alphaPass && + x24_colorOp == rhs.x24_colorOp && x38_alphaOp == rhs.x38_alphaOp; + } +}; + +extern const CTevPass kEnvPassthru; +// TODO move below to CGraphics +extern const CTevPass kEnvBlendCTandCConCF; +extern const CTevPass kEnvModulateConstColor; +extern const CTevPass kEnvConstColor; +extern const CTevPass kEnvModulate; +extern const CTevPass kEnvDecal; +extern const CTevPass kEnvBlend; +extern const CTevPass kEnvReplace; +extern const CTevPass kEnvModulateAlpha; +extern const CTevPass kEnvModulateColor; +extern const CTevPass kEnvModulateColorByAlpha; + +void Init(); +void SetupPass(ERglTevStage stage, const CTevPass& pass); +void DeletePass(ERglTevStage stage); +bool SetPassCombiners(ERglTevStage stage, const CTevPass& pass); +void RecomputePasses(); +void ResetStates(); +} // namespace CTevCombiners +} // namespace metaforce diff --git a/Runtime/Graphics/CTexture.cpp b/Runtime/Graphics/CTexture.cpp new file mode 100644 index 000000000..cea30657c --- /dev/null +++ b/Runtime/Graphics/CTexture.cpp @@ -0,0 +1,290 @@ +#include "Graphics/CTexture.hpp" + +#include "CToken.hpp" + +#include +#include + +namespace metaforce { +static std::array sLoadedTextures{}; + +CTexture::CTexture(ETexelFormat fmt, u16 w, u16 h, s32 mips, std::string_view label) +: x0_fmt(fmt) +, x4_w(w) +, x6_h(h) +, x8_mips(mips) +, x9_bitsPerPixel(TexelFormatBitsPerPixel(fmt)) +, x64_frameAllocated(sCurrentFrameCount) +, m_label(fmt::format(FMT_STRING("{} ({})"), label, magic_enum::enum_name(fmt))) { + InitBitmapBuffers(fmt, w, h, mips); + InitTextureObjs(); +} + +CTexture::CTexture(CInputStream& in, std::string_view label, EAutoMipmap automip, EBlackKey blackKey) +: x0_fmt(static_cast(in.ReadLong())) +, x4_w(in.ReadShort()) +, x6_h(in.ReadShort()) +, x8_mips(in.ReadLong()) +, x64_frameAllocated(sCurrentFrameCount) +, m_label(fmt::format(FMT_STRING("{} ({})"), label, magic_enum::enum_name(x0_fmt))) { + bool hasPalette = (x0_fmt == ETexelFormat::C4 || x0_fmt == ETexelFormat::C8 || x0_fmt == ETexelFormat::C14X2); + if (hasPalette) { + x10_graphicsPalette = std::make_unique(in); + xa_25_canLoadPalette = true; + } + x9_bitsPerPixel = TexelFormatBitsPerPixel(x0_fmt); + InitBitmapBuffers(x0_fmt, x4_w, x6_h, x8_mips); + u32 bufLen = 0; + if (x8_mips > 0) { + for (u32 i = 0; i < x8_mips; ++i) { + u32 curMip = i & 63; + const u32 width = ROUND_UP_4(x4_w >> curMip); + const u32 height = ROUND_UP_4(x6_h >> curMip); + bufLen += (width * height * x9_bitsPerPixel) / 8; + } + } + + for (u32 i = 0, len = 0; i < bufLen; i += len) { + len = bufLen - i; + if (len > 256) { + len = 256; + } + + auto image_ptr = /*x44_aramToken.GetMRAMSafe() */ x44_aramToken_x4_buff.get(); + in.Get(image_ptr + i, len); + // DCFlushRangeNoSync(x44_aramToken_x4_buff.get() + i, ROUND_UP_32(len)); + } + + if (sMangleMips) { + for (u32 i = 0; i < x8_mips; ++i) { + MangleMipmap(i); + } + } + + InitTextureObjs(); +} + +CTexture::~CTexture() { GXDestroyTexObj(&x20_texObj); } + +u8* CTexture::Lock() { + xa_24_locked = true; + return GetBitMapData(0); +} + +void CTexture::UnLock() { + xa_24_locked = false; + CountMemory(); + // DCFlushRange(x44_aramToken.GetMRAMSafe(), ROUND_UP_32(xc_memoryAllocated)); + + // Aurora change: track when texture data needs to be invalidated + m_needsTexObjDataLoad = true; +} + +void CTexture::Load(GXTexMapID id, EClampMode clamp) { + if (sLoadedTextures[id] != this || xa_29_canLoadObj) { + auto* data = /*x44_aramToken.GetMRAMSafe() */ x44_aramToken_x4_buff.get(); + CountMemory(); + if (HasPalette()) { + x10_graphicsPalette->Load(); + xa_25_canLoadPalette = false; + } + xa_29_canLoadObj = false; + if (x40_clampMode != clamp) { + x40_clampMode = !xa_26_isPowerOfTwo ? EClampMode::Clamp : clamp; + GXInitTexObjWrapMode(&x20_texObj, static_cast(x40_clampMode), + static_cast(x40_clampMode)); + } + + // Aurora change: track when texture data needs to be invalidated + if (m_needsTexObjDataLoad) { + GXInitTexObjData(&x20_texObj, data); + m_needsTexObjDataLoad = false; + } + GXLoadTexObj(&x20_texObj, id); + sLoadedTextures[id] = this; + x64_frameAllocated = sCurrentFrameCount; + } +} + +void CTexture::LoadMipLevel(s32 mip, GXTexMapID id, EClampMode clamp) { + auto* image_ptr = /*x44_aramToken.GetMRAMSafe() */ x44_aramToken_x4_buff.get(); + u32 width = x4_w; + u32 height = x6_h; + u32 iVar15 = 0; + u32 offset = 0; + if (mip > 0) { + for (u32 i = 0; i < mip; ++i) { + offset += ROUND_UP_32((x9_bitsPerPixel * (ROUND_UP_4(width) * ROUND_UP_4(height))) / 8); + width /= 2; + height /= 2; + } + } + + GXTexObj texObj; + const auto wrap = static_cast(clamp); + GXInitTexObj(&texObj, image_ptr + offset, width, height, x18_gxFormat, wrap, wrap, false); + GXInitTexObjLOD(&texObj, GX_LINEAR, GX_LINEAR, 0.f, 0.f, 0.f, false, false, GX_ANISO_1); + if (HasPalette()) { + x10_graphicsPalette->Load(); + xa_25_canLoadPalette = false; + } + GXLoadTexObj(&texObj, id); +#ifdef AURORA + GXDestroyTexObj(&texObj); +#endif + x64_frameAllocated = sCurrentFrameCount; + sLoadedTextures[id] = nullptr; +} + +void CTexture::MakeSwappable() { + if (!xa_27_noSwap) { + return; + } + + xa_27_noSwap = false; +} + +const u8* CTexture::GetConstBitMapData(s32 mip) const { + u32 buffOffset = 0; + if (x8_mips > mip) { + for (u32 i = 0; i < mip; ++i) { + buffOffset += (x9_bitsPerPixel >> 3) * (x4_w >> (i & 0x3f)) * (x6_h >> (i & 0x3f)); + } + } + return x44_aramToken_x4_buff.get() + buffOffset; /* x44_aramToken.GetMRAMSafe() + buffOffset*/ +} + +u8* CTexture::GetBitMapData(s32 mip) const { return const_cast(GetConstBitMapData(mip)); } + +void CTexture::InitBitmapBuffers(ETexelFormat fmt, u16 width, u16 height, s32 mips) { + switch (fmt) { + case ETexelFormat::I4: + x18_gxFormat = GX_TF_I4; + break; + case ETexelFormat::I8: + x18_gxFormat = GX_TF_I8; + break; + case ETexelFormat::IA4: + x18_gxFormat = GX_TF_IA4; + break; + case ETexelFormat::IA8: + x18_gxFormat = GX_TF_IA8; + break; + case ETexelFormat::C4: + x1c_gxCIFormat = GX_TF_C4; + break; + case ETexelFormat::C8: + x1c_gxCIFormat = GX_TF_C8; + break; + case ETexelFormat::C14X2: + x1c_gxCIFormat = GX_TF_C14X2; + break; + case ETexelFormat::RGB565: + x18_gxFormat = GX_TF_RGB565; + break; + case ETexelFormat::RGB5A3: + x18_gxFormat = GX_TF_RGB5A3; + break; + case ETexelFormat::RGBA8: + x18_gxFormat = GX_TF_RGBA8; + break; + case ETexelFormat::CMPR: + x18_gxFormat = GX_TF_CMPR; + break; + // Metaforce additions + case ETexelFormat::R8PC: + x18_gxFormat = GX_TF_R8_PC; + break; + case ETexelFormat::RGBA8PC: + x18_gxFormat = GX_TF_RGBA8_PC; + break; + default: + break; + } + + u32 format = (x0_fmt == ETexelFormat::C4 || x0_fmt == ETexelFormat::C8 || x0_fmt == ETexelFormat::C14X2) + ? u32(x1c_gxCIFormat) + : x18_gxFormat; + xc_memoryAllocated = GXGetTexBufferSize(width, height, format, mips > 1, mips > 1 ? 11 : 0); + x44_aramToken_x4_buff = std::make_unique(xc_memoryAllocated); + /*x44_aramToken.PostConstruct(buf, xc_memoryAllocated, 1);*/ + CountMemory(); +} + +void CTexture::InitTextureObjs() { + xa_26_isPowerOfTwo = zeus::floorPowerOfTwo(x4_w) == x4_w && zeus::floorPowerOfTwo(x6_h) == x6_h; + + if (!xa_26_isPowerOfTwo) { + x40_clampMode = EClampMode::Clamp; + } + + CountMemory(); + if (IsCITexture()) { + GXInitTexObjCI(&x20_texObj, x44_aramToken_x4_buff.get(), x4_w, x6_h, x1c_gxCIFormat, + static_cast(x40_clampMode), static_cast(x40_clampMode), x8_mips > 1, + 0); + } else { + GXInitTexObj(&x20_texObj, x44_aramToken_x4_buff.get(), x4_w, x6_h, x18_gxFormat, + static_cast(x40_clampMode), static_cast(x40_clampMode), x8_mips > 1); + GXInitTexObjLOD(&x20_texObj, x8_mips > 1 ? GX_LIN_MIP_LIN : GX_LINEAR, GX_LINEAR, 0.f, + static_cast(x8_mips) - 1.f, 0.f, false, false, x8_mips > 1 ? GX_ANISO_4 : GX_ANISO_1); + } + xa_29_canLoadObj = true; +} + +void CTexture::CountMemory() { + if (xa_28_counted) { + return; + } + + xa_28_counted = true; + sTotalAllocatedMemory += xc_memoryAllocated; +} + +void CTexture::UncountMemory() { + if (!xa_28_counted) { + return; + } + + xa_28_counted = false; + sTotalAllocatedMemory -= xc_memoryAllocated; +} + +void CTexture::MangleMipmap(u32 mip) { + // TODO(phil): Mangle mipmap +} + +u32 CTexture::TexelFormatBitsPerPixel(ETexelFormat fmt) { + switch (fmt) { + case ETexelFormat::I4: + case ETexelFormat::C4: + case ETexelFormat::CMPR: + return 4; + case ETexelFormat::I8: + case ETexelFormat::IA4: + case ETexelFormat::C8: + return 8; + case ETexelFormat::IA8: + case ETexelFormat::C14X2: + case ETexelFormat::RGB565: + case ETexelFormat::RGB5A3: + return 16; + case ETexelFormat::RGBA8: + return 32; + default: + return 0; + } +} + +bool CTexture::sMangleMips = false; +u32 CTexture::sCurrentFrameCount = 0; +u32 CTexture::sTotalAllocatedMemory = 0; + +void CTexture::InvalidateTexMap(GXTexMapID id) { sLoadedTextures[id] = nullptr; } + +CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, + CObjectReference* selfRef) { + const auto label = fmt::format(FMT_STRING("{} {}"), tag.type, tag.id); + return TToken::GetIObjObjectFor(std::make_unique(in, label)); +} +} // namespace metaforce diff --git a/Runtime/Graphics/CTexture.hpp b/Runtime/Graphics/CTexture.hpp index 272dac108..96c68df3a 100644 --- a/Runtime/Graphics/CTexture.hpp +++ b/Runtime/Graphics/CTexture.hpp @@ -1,22 +1,57 @@ #pragma once -#include -#include - #include "Runtime/CFactoryMgr.hpp" -#include "Runtime/GCNTypes.hpp" -#include "Runtime/IObj.hpp" -#include "Runtime/IOStreams.hpp" #include "Runtime/Graphics/CGraphics.hpp" - -#include +#include "Runtime/Graphics/CGraphicsPalette.hpp" +#include "Runtime/Graphics/GX.hpp" +#include "Runtime/IObj.hpp" +#include "Runtime/Streams/CInputStream.hpp" +#include "GX.hpp" namespace metaforce { -class CVParamTransfer; -class CTextureInfo; +enum class ETexelFormat { + Invalid = -1, + I4 = 0, + I8 = 1, + IA4 = 2, + IA8 = 3, + C4 = 4, + C8 = 5, + C14X2 = 6, + RGB565 = 7, + RGB5A3 = 8, + RGBA8 = 9, + CMPR = 10, + // Metaforce addition: non-converting formats + RGBA8PC = 11, + R8PC = 12, +}; + +enum class EClampMode : std::underlying_type_t { + Clamp = GX_CLAMP, + Repeat = GX_REPEAT, + Mirror = GX_MIRROR, +}; class CTexture { + class CDumpedBitmapDataReloader { + int x0_; + u32 x4_; + int x8_; + u32 xc_; + bool x10_; + int x14_; + void* x18_; + }; + public: + enum class EAutoMipmap { + Zero, + One, + }; + + enum class EBlackKey { Zero, One }; + enum class EFontType { None = -1, OneLayer = 0, /* Fill bit0 */ @@ -28,56 +63,79 @@ public: }; private: - ETexelFormat x0_fmt; - u16 x4_w; - u16 x6_h; - u32 x8_mips; - boo::ObjToken m_booTex; - boo::ObjToken m_paletteTex; - std::unique_ptr m_otex; - EFontType m_ftype = EFontType::None; - const CTextureInfo* m_textureInfo; + static bool sMangleMips; + static u32 sCurrentFrameCount; + static u32 sTotalAllocatedMemory; - size_t ComputeMippedTexelCount() const; - size_t ComputeMippedBlockCountDXT1() const; - void BuildI4FromGCN(CInputStream& in); - void BuildI8FromGCN(CInputStream& in); - void BuildIA4FromGCN(CInputStream& in); - void BuildIA8FromGCN(CInputStream& in); - void BuildC4FromGCN(CInputStream& in); - void BuildC8FromGCN(CInputStream& in); - void BuildC14X2FromGCN(CInputStream& in); - void BuildRGB565FromGCN(CInputStream& in); - void BuildRGB5A3FromGCN(CInputStream& in); - void BuildRGBA8FromGCN(CInputStream& in); - void BuildDXT1FromGCN(CInputStream& in); - void BuildRGBA8(const void* data, size_t length); - void BuildC8(const void* data, size_t length); - void BuildC8Font(const void* data, EFontType ftype); - void BuildDXT1(const void* data, size_t length); - void BuildDXT3(const void* data, size_t length); + ETexelFormat x0_fmt = ETexelFormat::Invalid; + u16 x4_w = 0; + u16 x6_h = 0; + u8 x8_mips = 0; + u8 x9_bitsPerPixel = 0; + bool xa_24_locked : 1 = false; + bool xa_25_canLoadPalette : 1 = false; + bool xa_26_isPowerOfTwo : 1 = false; + bool xa_27_noSwap : 1 = true; + bool xa_28_counted : 1 = false; + bool xa_29_canLoadObj : 1 = false; + u32 xc_memoryAllocated = 0; + std::unique_ptr x10_graphicsPalette; + std::unique_ptr x14_bitmapReloader; + u32 x18_gxFormat = GX_TF_RGB565; + GXCITexFmt x1c_gxCIFormat = GX_TF_C8; + GXTexObj x20_texObj; + EClampMode x40_clampMode = EClampMode::Repeat; + std::unique_ptr x44_aramToken_x4_buff; // was CARAMToken + u32 x64_frameAllocated{}; + + // Metaforce additions + std::string m_label; + bool m_needsTexObjDataLoad = true; + + void InitBitmapBuffers(ETexelFormat fmt, u16 width, u16 height, s32 mips); + void InitTextureObjs(); + void CountMemory(); + void UncountMemory(); + void MangleMipmap(u32 mip); + static u32 TexelFormatBitsPerPixel(ETexelFormat fmt); public: - CTexture(ETexelFormat, s16, s16, s32); - CTexture(std::unique_ptr&& in, u32 length, bool otex, const CTextureInfo* inf); - enum class EClampMode { None, One }; - ETexelFormat GetTexelFormat() const { return x0_fmt; } - ETexelFormat GetMemoryCardTexelFormat() const { - return x0_fmt == ETexelFormat::C8PC ? ETexelFormat::C8 : ETexelFormat::RGB5A3; - } - u16 GetWidth() const { return x4_w; } - u16 GetHeight() const { return x6_h; } - u32 GetNumMips() const { return x8_mips; } - void Load(int slot, EClampMode clamp) const; - const boo::ObjToken& GetBooTexture() const { return m_booTex; } - const boo::ObjToken& GetPaletteTexture() const { return m_paletteTex; } - std::unique_ptr BuildMemoryCardTex(u32& sizeOut, ETexelFormat& fmtOut, std::unique_ptr& paletteOut) const; - const boo::ObjToken& GetFontTexture(EFontType tp); + // Label parameters are new for Metaforce + CTexture(ETexelFormat fmt, u16 w, u16 h, s32 mips, std::string_view label); + CTexture(CInputStream& in, std::string_view label, EAutoMipmap automip = EAutoMipmap::Zero, + EBlackKey blackKey = EBlackKey::Zero); + ~CTexture(); - const CTextureInfo* GetTextureInfo() const { return m_textureInfo; } + [[nodiscard]] ETexelFormat GetTextureFormat() const { return x0_fmt; } + [[nodiscard]] u16 GetWidth() const { return x4_w; } + [[nodiscard]] u16 GetHeight() const { return x6_h; } + [[nodiscard]] u8 GetNumberOfMipMaps() const { return x8_mips; } + [[nodiscard]] u32 GetBitDepth() const { return x9_bitsPerPixel; } + [[nodiscard]] u32 GetMemoryAllocated() const { return xc_memoryAllocated; } + [[nodiscard]] const std::unique_ptr& GetPalette() const { return x10_graphicsPalette; } + [[nodiscard]] bool HasPalette() const { return x10_graphicsPalette != nullptr; } + [[nodiscard]] u8* Lock(); + void UnLock(); + void Load(GXTexMapID id, EClampMode clamp); + void LoadMipLevel(s32 mip, GXTexMapID id, EClampMode clamp); + // void UnloadBitmapData(u32) const; + // void TryReloadBitmapData(CResFactory&) const; + // void LoadToMRAM() const; + // void LoadToARAM() const; + // bool IsARAMTransferInProgress() const { return false; } + void MakeSwappable(); + + [[nodiscard]] const u8* GetConstBitMapData(s32 mip) const; + [[nodiscard]] u8* GetBitMapData(s32 mip) const; + [[nodiscard]] bool IsCITexture() const { + return x0_fmt == ETexelFormat::C4 || x0_fmt == ETexelFormat::C8 || x0_fmt == ETexelFormat::C14X2; + } + + static void InvalidateTexMap(GXTexMapID id); + static void SetMangleMips(bool b) { sMangleMips = b; } + static void SetCurrentFrameCount(u32 frameCount) { sCurrentFrameCount = frameCount; } }; -CFactoryFnReturn FTextureFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, - const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); - +CFactoryFnReturn FTextureFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, + CObjectReference* selfRef); } // namespace metaforce diff --git a/Runtime/Graphics/CTexture.hpp.old b/Runtime/Graphics/CTexture.hpp.old new file mode 100644 index 000000000..1cf50baf7 --- /dev/null +++ b/Runtime/Graphics/CTexture.hpp.old @@ -0,0 +1,116 @@ +#pragma once + +#include +#include + +#include "Runtime/CFactoryMgr.hpp" +#include "Runtime/GCNTypes.hpp" +#include "Runtime/Graphics/CGraphics.hpp" +#include "Runtime/IObj.hpp" +#include "Runtime/Streams/IOStreams.hpp" +#include "Runtime/Graphics/CGraphicsPalette.hpp" + +namespace metaforce { +class CVParamTransfer; +class CTextureInfo; + +class CTexture { + class CDumpedBitmapDataReloader { + int x0_; + u32 x4_; + int x8_; + u32 xc_; + bool x10_; + int x14_; + void* x18_; + }; + +public: + enum class EClampMode { + Clamp, + Repeat, + Mirror, + }; + + enum class EFontType { + None = -1, + OneLayer = 0, /* Fill bit0 */ + OneLayerOutline = 1, /* Fill bit0, Outline bit1 */ + FourLayers = 2, + TwoLayersOutlines = 3, /* Fill bit0/2, Outline bit1/3 */ + TwoLayers = 4, /* Fill bit0/1 and copied to bit2/3 */ + TwoLayersOutlines2 = 8 /* Fill bit2/3, Outline bit0/1 */ + }; + +private: + static u32 sCurrentFrameCount; + ETexelFormat x0_fmt; + u16 x4_w; + u16 x6_h; + u8 x8_mips; + u8 x9_bitsPerPixel; + u32 xc_memoryAllocated{}; + std::unique_ptr x10_graphicsPalette; + std::unique_ptr x14_bitmapReloader; + u32 x18_gxFormat{}; + u32 x1c_gxCIFormat{}; + /* GXTexObj x20_texObj */ + EClampMode x40_clampMode = EClampMode::Repeat; + /* CARAMToken x44_aramToken */ + u32 x64_frameAllocated{}; + + aurora::gfx::TextureHandle m_tex; + aurora::gfx::TextureHandle m_paletteTex; + std::unique_ptr m_otex; + EFontType m_ftype = EFontType::None; + const CTextureInfo* m_textureInfo{}; + + size_t ComputeMippedTexelCount() const; + size_t ComputeMippedBlockCountDXT1() const; + void BuildI4FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildI8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildIA4FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildIA8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildC4FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildC8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildC14X2FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGB565FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGB5A3FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGBA8FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildDXT1FromGCN(CInputStream& in, aurora::zstring_view label); + void BuildRGBA8(const void* data, size_t length, aurora::zstring_view label); + void BuildC8(const void* data, size_t length, aurora::zstring_view label); + void BuildC8Font(const void* data, EFontType ftype, aurora::zstring_view label); + void BuildDXT1(const void* data, size_t length, aurora::zstring_view label); + void BuildDXT3(const void* data, size_t length, aurora::zstring_view label); + + void InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mips); + void InitTextureObjs(); + +public: + CTexture(ETexelFormat, s16, s16, s32); + CTexture(std::unique_ptr&& in, u32 length, bool otex, const CTextureInfo* inf, CAssetId id); + [[nodiscard]] ETexelFormat GetTexelFormat() const { return x0_fmt; } + [[nodiscard]] ETexelFormat GetMemoryCardTexelFormat() const { + return x0_fmt == ETexelFormat::C8PC ? ETexelFormat::C8 : ETexelFormat::RGB5A3; + } + [[nodiscard]] u16 GetWidth() const { return x4_w; } + [[nodiscard]] u16 GetHeight() const { return x6_h; } + [[nodiscard]] u8 GetNumMips() const { return x8_mips; } + [[nodiscard]] u8 GetBitsPerPixel() const { return x9_bitsPerPixel; } + void Load(int slot, EClampMode clamp) const; + [[nodiscard]] const aurora::gfx::TextureHandle& GetTexture() const { return m_tex; } + [[nodiscard]] const aurora::gfx::TextureHandle& GetPaletteTexture() const { return m_paletteTex; } + std::unique_ptr BuildMemoryCardTex(u32& sizeOut, ETexelFormat& fmtOut, std::unique_ptr& paletteOut) const; + const aurora::gfx::TextureHandle& GetFontTexture(EFontType tp); + + [[nodiscard]] const CTextureInfo* GetTextureInfo() const { return m_textureInfo; } + + static u32 TexelFormatBitsPerPixel(ETexelFormat fmt); + static void SetCurrentFrameCount(u32 frameCount) { sCurrentFrameCount = frameCount; } +}; + +CFactoryFnReturn FTextureFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, + const metaforce::CVParamTransfer& vparms, CObjectReference* selfRef); + +} // namespace metaforce diff --git a/Runtime/Graphics/CTextureBoo.cpp b/Runtime/Graphics/CTextureBoo.cpp index 2bfc78089..beba48d5e 100644 --- a/Runtime/Graphics/CTextureBoo.cpp +++ b/Runtime/Graphics/CTextureBoo.cpp @@ -2,11 +2,14 @@ #include +#include "Runtime/CBasics.hpp" #include "Runtime/CSimplePool.hpp" -#include "Runtime/CToken.hpp" -#include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/CTextureCache.hpp" +#include "Runtime/CToken.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CGraphics.hpp" + +#include namespace metaforce { namespace { @@ -75,7 +78,7 @@ size_t CTexture::ComputeMippedBlockCountDXT1() const { return ret; } -void CTexture::BuildI4FromGCN(CInputStream& in) { +void CTexture::BuildI4FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); @@ -89,11 +92,11 @@ void CTexture::BuildI4FromGCN(CInputStream& in) { const int baseY = by * 8; for (int bx = 0; bx < bwidth; ++bx) { const int baseX = bx * 8; - for (int y = 0; y < 8; ++y) { + for (int y = 0; y < std::min(h, 8); ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), source.size()); - for (size_t x = 0; x < 8; ++x) { + in.Get(source.data(), std::min(size_t(w) / 4, source.size())); + for (size_t x = 0; x < std::min(w, 8); ++x) { target[x].r = Convert4To8(source[x / 2] >> ((x & 1) ? 0 : 4) & 0xf); target[x].g = target[x].r; target[x].b = target[x].r; @@ -111,15 +114,11 @@ void CTexture::BuildI4FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildI8FromGCN(CInputStream& in) { +void CTexture::BuildI8FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); @@ -136,7 +135,7 @@ void CTexture::BuildI8FromGCN(CInputStream& in) { for (int y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), source.size()); + in.Get(source.data(), source.size()); for (size_t x = 0; x < source.size(); ++x) { target[x].r = source[x]; target[x].g = source[x]; @@ -155,15 +154,11 @@ void CTexture::BuildI8FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildIA4FromGCN(CInputStream& in) { +void CTexture::BuildIA4FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); @@ -180,7 +175,7 @@ void CTexture::BuildIA4FromGCN(CInputStream& in) { for (int y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), source.size()); + in.Get(source.data(), source.size()); for (size_t x = 0; x < source.size(); ++x) { const u8 intensity = Convert4To8(source[x] >> 4 & 0xf); target[x].r = intensity; @@ -200,15 +195,11 @@ void CTexture::BuildIA4FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildIA8FromGCN(CInputStream& in) { +void CTexture::BuildIA8FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); @@ -225,7 +216,7 @@ void CTexture::BuildIA8FromGCN(CInputStream& in) { for (int y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), sizeof(source)); + in.Get(reinterpret_cast(source.data()), sizeof(source)); for (size_t x = 0; x < source.size(); ++x) { const u8 intensity = source[x] >> 8; target[x].r = intensity; @@ -245,12 +236,8 @@ void CTexture::BuildIA8FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } static std::vector DecodePalette(int numEntries, CInputStream& in) { @@ -259,27 +246,27 @@ static std::vector DecodePalette(int numEntries, CInputStream& in) { enum class EPaletteType { IA8, RGB565, RGB5A3 }; - EPaletteType format = EPaletteType(in.readUint32Big()); - in.readUint32Big(); + EPaletteType format = EPaletteType(in.ReadLong()); + in.ReadLong(); switch (format) { case EPaletteType::IA8: { for (int e = 0; e < numEntries; ++e) { - u8 intensity = in.readUByte(); - u8 alpha = in.readUByte(); + u8 intensity = in.ReadUint8(); + u8 alpha = in.ReadUint8(); ret.push_back({intensity, intensity, intensity, alpha}); } break; } case EPaletteType::RGB565: { for (int e = 0; e < numEntries; ++e) { - u16 texel = in.readUint16Big(); + u16 texel = in.ReadShort(); ret.push_back({Convert5To8(texel >> 11 & 0x1f), Convert6To8(texel >> 5 & 0x3f), Convert5To8(texel & 0x1f), 0xff}); } break; } case EPaletteType::RGB5A3: { for (int e = 0; e < numEntries; ++e) { - u16 texel = in.readUint16Big(); + u16 texel = in.ReadShort(); if (texel & 0x8000) { ret.push_back( {Convert5To8(texel >> 10 & 0x1f), Convert5To8(texel >> 5 & 0x1f), Convert5To8(texel & 0x1f), 0xff}); @@ -294,7 +281,7 @@ static std::vector DecodePalette(int numEntries, CInputStream& in) { return ret; } -void CTexture::BuildC4FromGCN(CInputStream& in) { +void CTexture::BuildC4FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); std::vector palette = DecodePalette(16, in); @@ -312,7 +299,7 @@ void CTexture::BuildC4FromGCN(CInputStream& in) { for (int y = 0; y < 8; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), source.size()); + in.Get(source.data(), source.size()); for (size_t x = 0; x < 8; ++x) { target[x] = palette[source[x / 2] >> ((x & 1) ? 0 : 4) & 0xf]; } @@ -328,15 +315,11 @@ void CTexture::BuildC4FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildC8FromGCN(CInputStream& in) { +void CTexture::BuildC8FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); std::vector palette = DecodePalette(256, in); @@ -354,7 +337,7 @@ void CTexture::BuildC8FromGCN(CInputStream& in) { for (int y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), source.size()); + in.Get(source.data(), source.size()); for (size_t x = 0; x < source.size(); ++x) { target[x] = palette[source[x]]; } @@ -370,17 +353,15 @@ void CTexture::BuildC8FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildC14X2FromGCN(CInputStream& in) {} +void CTexture::BuildC14X2FromGCN(CInputStream& in, aurora::zstring_view label) { + Log.report(logvisor::Fatal, FMT_STRING("C14X2 not implemented")); +} -void CTexture::BuildRGB565FromGCN(CInputStream& in) { +void CTexture::BuildRGB565FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); @@ -397,7 +378,7 @@ void CTexture::BuildRGB565FromGCN(CInputStream& in) { for (int y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; for (size_t x = 0; x < 4; ++x) { - const u16 texel = in.readUint16Big(); + const u16 texel = in.ReadShort(); target[x].r = Convert5To8(texel >> 11 & 0x1f); target[x].g = Convert6To8(texel >> 5 & 0x3f); target[x].b = Convert5To8(texel & 0x1f); @@ -415,15 +396,11 @@ void CTexture::BuildRGB565FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildRGB5A3FromGCN(CInputStream& in) { +void CTexture::BuildRGB5A3FromGCN(CInputStream& in, aurora::zstring_view label) { size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); @@ -440,7 +417,7 @@ void CTexture::BuildRGB5A3FromGCN(CInputStream& in) { for (int y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; for (size_t x = 0; x < 4; ++x) { - const u16 texel = in.readUint16Big(); + const u16 texel = in.ReadShort(); if ((texel & 0x8000) != 0) { target[x].r = Convert5To8(texel >> 10 & 0x1f); target[x].g = Convert5To8(texel >> 5 & 0x1f); @@ -465,15 +442,11 @@ void CTexture::BuildRGB5A3FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildRGBA8FromGCN(CInputStream& in) { +void CTexture::BuildRGBA8FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t texelCount = ComputeMippedTexelCount(); std::unique_ptr buf(new RGBA8[texelCount]); @@ -491,7 +464,7 @@ void CTexture::BuildRGBA8FromGCN(CInputStream& in) { for (int y = 0; y < 4; ++y) { RGBA8* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), source.size()); + in.Get(source.data(), source.size()); for (size_t x = 0; x < 4; ++x) { if (c != 0) { target[x].g = source[x * 2]; @@ -514,15 +487,11 @@ void CTexture::BuildRGBA8FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - buf.get(), texelCount * 4) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(buf.get()), texelCount * 4}, label); } -void CTexture::BuildDXT1FromGCN(CInputStream& in) { +void CTexture::BuildDXT1FromGCN(CInputStream& in, aurora::zstring_view label) { const size_t blockCount = ComputeMippedBlockCountDXT1(); std::unique_ptr buf(new DXT1Block[blockCount]); @@ -539,10 +508,10 @@ void CTexture::BuildDXT1FromGCN(CInputStream& in) { for (int y = 0; y < 2; ++y) { DXT1Block* target = targetMip + (baseY + y) * w + baseX; std::array source; - in.readBytesToBuf(source.data(), sizeof(source)); + in.Get(reinterpret_cast(source.data()), sizeof(source)); for (size_t x = 0; x < source.size(); ++x) { - target[x].color1 = hecl::SBig(source[x].color1); - target[x].color2 = hecl::SBig(source[x].color2); + target[x].color1 = CBasics::SwapBytes(source[x].color1); + target[x].color2 = CBasics::SwapBytes(source[x].color2); for (size_t i = 0; i < 4; ++i) { std::array ind; const u8 packed = source[x].lines[i]; @@ -566,48 +535,35 @@ void CTexture::BuildDXT1FromGCN(CInputStream& in) { } } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::DXT1, boo::TextureClampMode::Repeat, - buf.get(), blockCount * 8) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::DXT1, + {reinterpret_cast(buf.get()), blockCount * 8}, label); } -void CTexture::BuildRGBA8(const void* data, size_t length) { +void CTexture::BuildRGBA8(const void* data, size_t length, aurora::zstring_view label) { size_t texelCount = ComputeMippedTexelCount(); size_t expectedSize = texelCount * 4; if (expectedSize > length) Log.report(logvisor::Fatal, FMT_STRING("insufficient TXTR length ({}/{})"), length, expectedSize); - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, data, - expectedSize) - .get(); - return true; - } BooTrace); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(data), expectedSize}, label); } -void CTexture::BuildC8(const void* data, size_t length) { +void CTexture::BuildC8(const void* data, size_t length, aurora::zstring_view label) { size_t texelCount = ComputeMippedTexelCount(); if (texelCount > length) Log.report(logvisor::Fatal, FMT_STRING("insufficient TXTR length ({}/{})"), length, texelCount); - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - uint32_t nentries = hecl::SBig(*reinterpret_cast(data)); - const u8* paletteTexels = reinterpret_cast(data) + 4; - const u8* texels = reinterpret_cast(data) + 4 + nentries * 4; - m_paletteTex = ctx.newStaticTexture(nentries, 1, 1, boo::TextureFormat::RGBA8, boo::TextureClampMode::Repeat, - paletteTexels, nentries * 4) - .get(); - m_booTex = ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::I8, boo::TextureClampMode::Repeat, texels, - texelCount) - .get(); - return true; - } BooTrace); + uint32_t nentries = CBasics::SwapBytes(*reinterpret_cast(data)); + const u8* paletteTexels = reinterpret_cast(data) + 4; + const u8* texels = reinterpret_cast(data) + 4 + nentries * 4; + m_paletteTex = aurora::gfx::new_static_texture_2d(nentries, 1, 1, aurora::gfx::TextureFormat::RGBA8, + {paletteTexels, nentries * 4}, label); + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::R8, {texels, texelCount}, + label); } -void CTexture::BuildC8Font(const void* data, EFontType ftype) { +void CTexture::BuildC8Font(const void* data, EFontType ftype, aurora::zstring_view label) { size_t texelCount = ComputeMippedTexelCount(); size_t layerCount = 1; @@ -628,7 +584,7 @@ void CTexture::BuildC8Font(const void* data, EFontType ftype) { break; } - const uint32_t nentries = hecl::SBig(*reinterpret_cast(data)); + const uint32_t nentries = CBasics::SwapBytes(*reinterpret_cast(data)); const u8* texels = reinterpret_cast(data) + 4 + nentries * 4; auto buf = std::make_unique(texelCount * layerCount); @@ -697,95 +653,176 @@ void CTexture::BuildC8Font(const void* data, EFontType ftype) { h /= 2; } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = ctx.newStaticArrayTexture(x4_w, x6_h, layerCount, x8_mips, boo::TextureFormat::RGBA8, - boo::TextureClampMode::Repeat, buf.get(), texelCount * layerCount * 4) - .get(); - return true; - } BooTrace); + // TODO array tex + // CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { + // m_booTex = ctx.newStaticArrayTexture(x4_w, x6_h, layerCount, x8_mips, boo::TextureFormat::RGBA8, + // boo::TextureClampMode::Repeat, buf.get(), texelCount * layerCount * 4) + // .get(); + // return true; + // } BooTrace); } -void CTexture::BuildDXT1(const void* data, size_t length) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = - ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::DXT1, boo::TextureClampMode::Repeat, data, length) - .get(); - return true; - } BooTrace); +void CTexture::BuildDXT1(const void* data, size_t length, aurora::zstring_view label) { + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::DXT1, + {reinterpret_cast(data), length}, label); } -void CTexture::BuildDXT3(const void* data, size_t length) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_booTex = - ctx.newStaticTexture(x4_w, x6_h, x8_mips, boo::TextureFormat::DXT3, boo::TextureClampMode::Repeat, data, length) - .get(); - return true; - } BooTrace); +void CTexture::BuildDXT3(const void* data, size_t length, aurora::zstring_view label) { + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::DXT3, + {reinterpret_cast(data), length}, label); } -CTexture::CTexture(ETexelFormat fmt, s16 w, s16 h, s32 mips) : x0_fmt(fmt), x4_w(w), x6_h(h), x8_mips(mips) { - /* - x64_ = sMangleMipmaps; +static std::string_view TextureFormatString(ETexelFormat format) { + switch (format) { + case ETexelFormat::I4: + return "I4"sv; + case ETexelFormat::I8: + return "I8"sv; + case ETexelFormat::IA4: + return "IA4"sv; + case ETexelFormat::IA8: + return "IA8"sv; + case ETexelFormat::C4: + return "C4"sv; + case ETexelFormat::C8: + return "C8"sv; + case ETexelFormat::C14X2: + return "C14X2"sv; + case ETexelFormat::RGB565: + return "RGB565"sv; + case ETexelFormat::RGB5A3: + return "RGB5A3"sv; + case ETexelFormat::RGBA8: + return "RGBA8"sv; + case ETexelFormat::CMPR: + return "CMPR"sv; + case ETexelFormat::RGBA8PC: + return "RGBA8PC"sv; + case ETexelFormat::C8PC: + return "C8PC"sv; + case ETexelFormat::CMPRPC: + return "CMPRPC"sv; + case ETexelFormat::CMPRPCA: + return "CMPRPCA"sv; + default: + return "Invalid"sv; + } +} + +u32 CTexture::TexelFormatBitsPerPixel(ETexelFormat fmt) { + switch (fmt) { + case ETexelFormat::I4: + case ETexelFormat::C4: + case ETexelFormat::CMPR: + return 4; + case ETexelFormat::I8: + case ETexelFormat::IA4: + case ETexelFormat::C8: + return 8; + case ETexelFormat::IA8: + case ETexelFormat::C14X2: + case ETexelFormat::RGB565: + case ETexelFormat::RGB5A3: + return 16; + case ETexelFormat::RGBA8: + return 32; + default: + return 0; + } +} + +u32 CTexture::sCurrentFrameCount = 0; + +void CTexture::InitBitmapBuffers(ETexelFormat fmt, s16 width, s16 height, s32 mips) {} +void CTexture::InitTextureObjs() {} + +CTexture::CTexture(ETexelFormat fmt, s16 w, s16 h, s32 mips) +: x0_fmt(fmt) +, x4_w(w) +, x6_h(h) +, x8_mips(mips) +, x9_bitsPerPixel(TexelFormatBitsPerPixel(fmt)) +, x64_frameAllocated(sCurrentFrameCount) { + InitBitmapBuffers(fmt, w, h, mips); InitTextureObjs(); - */ } -CTexture::CTexture(std::unique_ptr&& in, u32 length, bool otex, const CTextureInfo* inf) { - m_textureInfo = inf; +CTexture::CTexture(std::unique_ptr&& in, u32 length, bool otex, const CTextureInfo* inf, CAssetId id) { std::unique_ptr owned = std::move(in); - athena::io::MemoryReader r(owned.get(), length); - x0_fmt = ETexelFormat(r.readUint32Big()); - x4_w = r.readUint16Big(); - x6_h = r.readUint16Big(); - x8_mips = r.readUint32Big(); + CMemoryInStream r(owned.get(), length, CMemoryInStream::EOwnerShip::NotOwned); + x0_fmt = ETexelFormat(r.ReadLong()); + x4_w = r.ReadShort(); + x6_h = r.ReadShort(); + x8_mips = r.ReadLong(); + x9_bitsPerPixel = TexelFormatBitsPerPixel(x0_fmt); + m_textureInfo = inf; + auto label = fmt::format(FMT_STRING("TXTR {:08X} ({})"), id.Value(), TextureFormatString(x0_fmt)); switch (x0_fmt) { case ETexelFormat::I4: - BuildI4FromGCN(r); + BuildI4FromGCN(r, label); break; case ETexelFormat::I8: - BuildI8FromGCN(r); + BuildI8FromGCN(r, label); break; case ETexelFormat::IA4: - BuildIA4FromGCN(r); + BuildIA4FromGCN(r, label); break; case ETexelFormat::IA8: - BuildIA8FromGCN(r); + BuildIA8FromGCN(r, label); break; case ETexelFormat::C4: - BuildC4FromGCN(r); + BuildC4FromGCN(r, label); break; case ETexelFormat::C8: - BuildC8FromGCN(r); + BuildC8FromGCN(r, label); break; case ETexelFormat::C14X2: - BuildC14X2FromGCN(r); + BuildC14X2FromGCN(r, label); break; case ETexelFormat::RGB565: - BuildRGB565FromGCN(r); + BuildRGB565FromGCN(r, label); break; case ETexelFormat::RGB5A3: - BuildRGB5A3FromGCN(r); + BuildRGB5A3FromGCN(r, label); break; case ETexelFormat::RGBA8: - BuildRGBA8FromGCN(r); + BuildRGBA8FromGCN(r, label); break; case ETexelFormat::CMPR: - BuildDXT1FromGCN(r); + if (aurora::gfx::get_dxt_compression_supported()) { + BuildDXT1FromGCN(r, label); + } else { + Log.report(logvisor::Error, FMT_STRING("BC/DXT1 compression is not supported on your GPU, unable to load {}"), + label); + x0_fmt = ETexelFormat::RGBA8PC; + x8_mips = 1; + std::unique_ptr data = std::make_unique(x4_w * x6_h * 4); + /* Build a fake texture to use */ + for (u32 i = 0; i < (x4_w * x6_h) * 4; i += 4) { + data[i + 0] = 0xFF; + data[i + 1] = 0x00; + data[i + 2] = 0xFF; + data[i + 3] = 0xFF; + } + m_tex = aurora::gfx::new_static_texture_2d(x4_w, x6_h, x8_mips, aurora::gfx::TextureFormat::RGBA8, + {reinterpret_cast(data.get()), (x4_w * x6_h * 4ul)}, + label); + } break; case ETexelFormat::RGBA8PC: - BuildRGBA8(owned.get() + 12, length - 12); + BuildRGBA8(owned.get() + 12, length - 12, label); break; case ETexelFormat::C8PC: - BuildC8(owned.get() + 12, length - 12); + BuildC8(owned.get() + 12, length - 12, label); otex = true; break; case ETexelFormat::CMPRPC: - BuildDXT1(owned.get() + 12, length - 12); + BuildDXT1(owned.get() + 12, length - 12, label); break; case ETexelFormat::CMPRPCA: - BuildDXT3(owned.get() + 12, length - 12); + BuildDXT3(owned.get() + 12, length - 12, label); break; default: Log.report(logvisor::Fatal, FMT_STRING("invalid texture type {} for boo"), int(x0_fmt)); @@ -823,10 +860,11 @@ std::unique_ptr CTexture::BuildMemoryCardTex(u32& sizeOut, ETexelFormat& f const RGBA8* source = sourceMip + (x6_h - (baseY + y) - 1) * w + baseX; for (int x = 0; x < 4; ++x) { if (source[x].a == 0xff) { - *texel++ = hecl::SBig(u16((source[x].r >> 3 << 10) | (source[x].g >> 3 << 5) | (source[x].b >> 3))); + *texel++ = + CBasics::SwapBytes(u16((source[x].r >> 3 << 10) | (source[x].g >> 3 << 5) | (source[x].b >> 3))); } else { - *texel++ = hecl::SBig(u16((source[x].r >> 4 << 8) | (source[x].g >> 4 << 4) | (source[x].b >> 4) | - (source[x].a >> 5 << 12))); + *texel++ = CBasics::SwapBytes(u16((source[x].r >> 4 << 8) | (source[x].g >> 4 << 4) | (source[x].b >> 4) | + (source[x].a >> 5 << 12))); } } } @@ -843,7 +881,7 @@ std::unique_ptr CTexture::BuildMemoryCardTex(u32& sizeOut, ETexelFormat& f int w = x4_w; int h = x6_h; const u8* data = m_otex.get() + 12; - u32 nentries = hecl::SBig(*reinterpret_cast(data)); + u32 nentries = CBasics::SwapBytes(*reinterpret_cast(data)); const RGBA8* paletteTexels = reinterpret_cast(data + 4); const u8* sourceMip = data + 4 + nentries * 4; @@ -854,9 +892,9 @@ std::unique_ptr CTexture::BuildMemoryCardTex(u32& sizeOut, ETexelFormat& f } else { const RGBA8& colorIn = paletteTexels[i]; if (colorIn.a == 0xff) { - color = hecl::SBig(u16((colorIn.r >> 3 << 10) | (colorIn.g >> 3 << 5) | (colorIn.b >> 3) | 0x8000)); + color = CBasics::SwapBytes(u16((colorIn.r >> 3 << 10) | (colorIn.g >> 3 << 5) | (colorIn.b >> 3) | 0x8000)); } else { - color = hecl::SBig( + color = CBasics::SwapBytes( u16((colorIn.r >> 4 << 8) | (colorIn.g >> 4 << 4) | (colorIn.b >> 4) | (colorIn.a >> 5 << 12))); } } @@ -881,12 +919,12 @@ std::unique_ptr CTexture::BuildMemoryCardTex(u32& sizeOut, ETexelFormat& f return ret; } -const boo::ObjToken& CTexture::GetFontTexture(EFontType tp) { +const aurora::gfx::TextureHandle& CTexture::GetFontTexture(EFontType tp) { if (m_ftype != tp && x0_fmt == ETexelFormat::C8PC) { m_ftype = tp; - BuildC8Font(m_otex.get() + 12, m_ftype); + BuildC8Font(m_otex.get() + 12, m_ftype, "Font (TODO)"); } - return m_booTex; + return m_tex; } CFactoryFnReturn FTextureFactory(const metaforce::SObjectTag& tag, std::unique_ptr&& in, u32 len, @@ -896,7 +934,7 @@ CFactoryFnReturn FTextureFactory(const metaforce::SObjectTag& tag, std::unique_p if (g_TextureCache) inf = g_TextureCache->GetTextureInfo(tag.id); return TToken::GetIObjObjectFor( - std::make_unique(std::move(in), len, u32Owned == SBIG('OTEX'), inf)); + std::make_unique(std::move(in), len, u32Owned == SBIG('OTEX'), inf, tag.id)); } } // namespace metaforce diff --git a/Runtime/Graphics/CVertexMorphEffect.cpp b/Runtime/Graphics/CVertexMorphEffect.cpp index eb4678d3b..bf877cc29 100644 --- a/Runtime/Graphics/CVertexMorphEffect.cpp +++ b/Runtime/Graphics/CVertexMorphEffect.cpp @@ -1,15 +1,46 @@ #include "Runtime/Graphics/CVertexMorphEffect.hpp" #include "Runtime/Character/CSkinRules.hpp" +#include "Runtime/Graphics/CSkinnedModel.hpp" namespace metaforce { -CVertexMorphEffect::CVertexMorphEffect(const zeus::CUnitVector3f& v1, const zeus::CVector3f& v2, float diagExtent, - float f2, CRandom16& random) -: x0_(v1), x20_diagExtent(diagExtent), x24_random(random) {} +CVertexMorphEffect::CVertexMorphEffect(const zeus::CUnitVector3f& dir, const zeus::CVector3f& pos, float duration, + float diagExtent, CRandom16& random) +: x0_dir(dir), xc_pos(pos), x18_duration(duration), x20_diagExtent(diagExtent), x24_random(random) {} -void CVertexMorphEffect::MorphVertices(std::vector>& vn, - const float* magnitudes, const TLockedToken& skinRules, - const CPoseAsTransforms& pose) const {} +void CVertexMorphEffect::MorphVertices(SSkinningWorkspace& workspace, TConstVectorRef averagedNormals, + TLockedToken& skinRules, const CPoseAsTransforms& pose, + u32 vertexCount) { + if (x28_indices.empty()) { + std::vector normalsOut; + normalsOut.reserve(vertexCount); + skinRules->BuildNormals(averagedNormals, &normalsOut); + for (int i = 0; i < vertexCount; ++i) { + float dist = normalsOut[i].dot(x0_dir); + if (dist > 0.5f) { + x28_indices.emplace_back(i); + const auto vert = workspace.m_vertexWorkspace[i]; + const auto length = vert.x() + vert.y() + vert.z(); + x38_floats.emplace_back((length - std::trunc(length)) * (dist - 0.5f)); + } + } + } + for (int i = 0; i < x28_indices.size(); ++i) { + const auto scale = x1c_elapsed / x18_duration; + workspace.m_vertexWorkspace[x28_indices[i]] += scale * x20_diagExtent * x38_floats[i] * x0_dir; + } +} -} // namespace metaforce \ No newline at end of file +void CVertexMorphEffect::Reset(const zeus::CVector3f& dir, const zeus::CVector3f& pos, float duration) { + x0_dir = dir; + xc_pos = pos; + x18_duration = duration; + x1c_elapsed = 0.f; + x28_indices.clear(); + x38_floats.clear(); +} + +void CVertexMorphEffect::Update(float dt) { x1c_elapsed = std::min(x1c_elapsed + dt, x18_duration); } + +} // namespace metaforce diff --git a/Runtime/Graphics/CVertexMorphEffect.hpp b/Runtime/Graphics/CVertexMorphEffect.hpp index 49a7c294f..aeb91c906 100644 --- a/Runtime/Graphics/CVertexMorphEffect.hpp +++ b/Runtime/Graphics/CVertexMorphEffect.hpp @@ -5,6 +5,7 @@ #include "Runtime/CToken.hpp" #include "Runtime/Character/CPoseAsTransforms.hpp" +#include "Runtime/Graphics/CCubeModel.hpp" #include #include @@ -12,26 +13,25 @@ namespace metaforce { class CRandom16; class CSkinRules; +struct SSkinningWorkspace; class CVertexMorphEffect { - zeus::CUnitVector3f x0_; - float xc_ = 0.f; - float x10_ = 0.f; - float x14_ = 0.f; - float x18_ = 0.f; - float x1c_ = 0.f; + zeus::CUnitVector3f x0_dir; + zeus::CVector3f xc_pos; + float x18_duration; + float x1c_elapsed = 0.f; float x20_diagExtent; CRandom16& x24_random; - std::vector x28_; - std::vector x38_; + std::vector x28_indices; + std::vector x38_floats; public: - CVertexMorphEffect(const zeus::CUnitVector3f& v1, const zeus::CVector3f& v2, float diagExtent, float f2, + CVertexMorphEffect(const zeus::CUnitVector3f& dir, const zeus::CVector3f& pos, float duration, float diagExtent, CRandom16& random); - void MorphVertices(std::vector>& vn, const float* magnitudes, - const TLockedToken& skinRules, const CPoseAsTransforms& pose) const; - void Reset(const zeus::CVector3f& dir, const zeus::CVector3f& pos, float duration) {} - void Update(float) {} + void MorphVertices(SSkinningWorkspace& workspace, TConstVectorRef averagedNormals, + TLockedToken& skinRules, const CPoseAsTransforms& pose, u32 vertexCount); + void Reset(const zeus::CVector3f& dir, const zeus::CVector3f& pos, float duration); + void Update(float dt); }; } // namespace metaforce diff --git a/Runtime/Graphics/GX.hpp b/Runtime/Graphics/GX.hpp new file mode 100644 index 000000000..27a6a898b --- /dev/null +++ b/Runtime/Graphics/GX.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include + +#include +#include + +namespace GX { +constexpr u8 MaxLights = 8; +using LightMask = std::bitset; +} // namespace GX + +constexpr GXColor GX_BLACK{0, 0, 0, 255}; +constexpr GXColor GX_WHITE{255, 255, 255, 255}; +constexpr GXColor GX_CLEAR{0, 0, 0, 0}; + +inline bool operator==(const GXColor& lhs, const GXColor& rhs) noexcept { + return lhs.r == rhs.r && lhs.g == rhs.g && lhs.b == rhs.b && lhs.a == rhs.a; +} +inline bool operator!=(const GXColor& lhs, const GXColor& rhs) noexcept { + return !(lhs == rhs); +} + +static inline void GXPosition3f32(const zeus::CVector3f& v) { GXPosition3f32(v.x(), v.y(), v.z()); } +static inline void GXNormal3f32(const zeus::CVector3f& v) { GXNormal3f32(v.x(), v.y(), v.z()); } +static inline void GXTexCoord2f32(const zeus::CVector2f& v) { GXTexCoord2f32(v.x(), v.y()); } +static inline void GXColor4f32(const zeus::CColor& v) { GXColor4f32(v.r(), v.g(), v.b(), v.a()); } + +static inline GXColor to_gx_color(const zeus::CColor& color) { + return { + static_cast(color.r() * 255.f), + static_cast(color.g() * 255.f), + static_cast(color.b() * 255.f), + static_cast(color.a() * 255.f), + }; +} +static inline zeus::CColor from_gx_color(GXColor color) { + return { + static_cast(color.r) / 255.f, + static_cast(color.g) / 255.f, + static_cast(color.b) / 255.f, + static_cast(color.a) / 255.f, + }; +} diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index eb5364a92..b1f238dfb 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -4,8 +4,9 @@ #include #include "Runtime/CToken.hpp" -#include "Runtime/RetroTypes.hpp" #include "Runtime/Graphics/CGraphics.hpp" +#include "Runtime/Graphics/CModel.hpp" +#include "Runtime/RetroTypes.hpp" #include #include @@ -17,7 +18,6 @@ namespace metaforce { class CAreaOctTree; class CLight; class CMetroidModelInstance; -class CModel; class CPVSVisSet; class CParticleGen; class CSkinnedModel; @@ -31,26 +31,31 @@ public: using TReflectionCallback = std::function; enum class EDrawableSorting { SortedCallback, UnsortedCallback }; - enum class EDebugOption { Zero, One }; - enum class EPrimitiveType {}; + enum class EDebugOption { Invalid = -1, PVSMode, PVSState, FogDisabled }; + enum class EPrimitiveType { + Triangles = GX_TRIANGLES, + TriangleFan = GX_TRIANGLEFAN, + TriangleStrip = GX_TRIANGLESTRIP, + Lines = GX_LINES, + LineStrip = GX_LINESTRIP, + }; virtual ~IRenderer() = default; virtual void AddStaticGeometry(const std::vector* geometry, const CAreaRenderOctTree* octTree, - int areaIdx, const SShader* shaderSet) = 0; + s32 areaIdx) = 0; virtual void EnablePVS(const CPVSVisSet& set, u32 areaIdx) = 0; virtual void DisablePVS() = 0; virtual void RemoveStaticGeometry(const std::vector* geometry) = 0; - virtual void DrawAreaGeometry(int areaIdx, int mask, int targetMask) = 0; - virtual void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask, bool shadowRender = false) = 0; - virtual void DrawSortedGeometry(int areaIdx, int mask, int targetMask) = 0; - virtual void DrawStaticGeometry(int areaIdx, int mask, int targetMask) = 0; - virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly) = 0; + virtual void DrawUnsortedGeometry(s32 areaIdx, s32 mask, s32 targetMask) = 0; + virtual void DrawSortedGeometry(s32 areaIdx, s32 mask, s32 targetMask) = 0; + virtual void DrawStaticGeometry(s32 areaIdx, s32 mask, s32 targetMask) = 0; + virtual void DrawAreaGeometry(s32 areaIdx, s32 mask, s32 targetMask) = 0; virtual void PostRenderFogs() = 0; virtual void SetModelMatrix(const zeus::CTransform& xf) = 0; virtual void AddParticleGen(CParticleGen& gen) = 0; virtual void AddParticleGen(CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds) = 0; - virtual void AddPlaneObject(void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type) = 0; - virtual void AddDrawable(void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, int mode, + virtual void AddPlaneObject(void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, s32 type) = 0; + virtual void AddDrawable(void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, s32 mode, EDrawableSorting sorting) = 0; virtual void SetDrawableCallback(TDrawableCallback cb, void* ctx) = 0; virtual void SetWorldViewpoint(const zeus::CTransform& xf) = 0; @@ -58,38 +63,42 @@ public: virtual void SetPerspective(float fovy, float aspect, float znear, float zfar) = 0; virtual std::pair SetViewportOrtho(bool centered, float znear, float zfar) = 0; virtual void SetClippingPlanes(const zeus::CFrustum& frustum) = 0; - virtual void SetViewport(int left, int bottom, int width, int height) = 0; - // virtual void SetDepthReadWrite(bool, bool)=0; - // virtual void SetBlendMode_AdditiveAlpha()=0; - // virtual void SetBlendMode_AlphaBlended()=0; - // virtual void SetBlendMode_NoColorWrite()=0; - // virtual void SetBlendMode_ColorMultiply()=0; - // virtual void SetBlendMode_InvertDst()=0; - // virtual void SetBlendMode_InvertSrc()=0; - // virtual void SetBlendMode_Replace()=0; - // virtual void SetBlendMode_AdditiveDestColor()=0; - virtual void SetDebugOption(EDebugOption, int) = 0; + virtual void SetViewport(s32 left, s32 bottom, s32 width, s32 height) = 0; + virtual void SetDepthReadWrite(bool, bool) = 0; + virtual void SetBlendMode_AdditiveAlpha() = 0; + virtual void SetBlendMode_AlphaBlended() = 0; + virtual void SetBlendMode_NoColorWrite() = 0; + virtual void SetBlendMode_ColorMultiply() = 0; + virtual void SetBlendMode_InvertDst() = 0; + virtual void SetBlendMode_InvertSrc() = 0; + virtual void SetBlendMode_Replace() = 0; + virtual void SetBlendMode_AdditiveDestColor() = 0; + virtual void SetDebugOption(EDebugOption, s32) = 0; virtual void BeginScene() = 0; virtual void EndScene() = 0; - // virtual void BeginPrimitive(EPrimitiveType, int)=0; - // virtual void BeginLines(int)=0; - // virtual void BeginLineStrip(int)=0; - // virtual void BeginTriangles(int)=0; - // virtual void BeginTriangleStrip(int)=0; - // virtual void BeginTriangleFan(int)=0; - // virtual void PrimVertex(const zeus::CVector3f&)=0; - // virtual void PrimNormal(const zeus::CVector3f&)=0; - // virtual void PrimColor(float, float, float, float)=0; - // virtual void PrimColor(const zeus::CColor&)=0; - // virtual void EndPrimitive()=0; + virtual void BeginPrimitive(EPrimitiveType, s32) = 0; + virtual void BeginLines(s32) = 0; + virtual void BeginLineStrip(s32) = 0; + virtual void BeginTriangles(s32) = 0; + virtual void BeginTriangleStrip(s32) = 0; + virtual void BeginTriangleFan(s32) = 0; + virtual void PrimVertex(const zeus::CVector3f&) = 0; + virtual void PrimNormal(const zeus::CVector3f&) = 0; + virtual void PrimColor(float, float, float, float) = 0; + virtual void PrimColor(const zeus::CColor&) = 0; + virtual void EndPrimitive() = 0; virtual void SetAmbientColor(const zeus::CColor& color) = 0; virtual void DrawString(const char* string, int, int) = 0; virtual u32 GetFPS() = 0; virtual void CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter) = 0; virtual void DrawSpaceWarp(const zeus::CVector3f& pt, float strength) = 0; - virtual void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol) = 0; - virtual void DrawXRayOutline(const zeus::CAABox& aabb) = 0; - virtual void SetWireframeFlags(int flags) = 0; + virtual void DrawThermalModel(CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol, + TConstVectorRef positions, TConstVectorRef normals, const CModelFlags& flags) = 0; + virtual void DrawModelDisintegrate(CModel& model, CTexture& tex, const zeus::CColor& color, TConstVectorRef positions, + TConstVectorRef normals, float t) = 0; + virtual void DrawModelFlat(CModel& model, const CModelFlags& flags, bool unsortedOnly, TConstVectorRef positions, + TConstVectorRef normals) = 0; + virtual void SetWireframeFlags(s32 flags) = 0; virtual void SetWorldFog(ERglFogMode mode, float startz, float endz, const zeus::CColor& color) = 0; virtual void RenderFogVolume(const zeus::CColor& color, const zeus::CAABox& aabb, const TLockedToken* model, const CSkinnedModel* sModel) = 0; @@ -99,8 +108,8 @@ public: virtual void DoThermalBlendHot() = 0; virtual u32 GetStaticWorldDataSize() = 0; virtual void SetGXRegister1Color(const zeus::CColor& color) = 0; - virtual void SetWorldLightMultiplyColor(const zeus::CColor& color) = 0; virtual void SetWorldLightFadeLevel(float level) = 0; + // Something virtual void PrepareDynamicLights(const std::vector& lights) = 0; }; diff --git a/Runtime/Graphics/Shaders/CAABoxShader.cpp b/Runtime/Graphics/Shaders/CAABoxShader.cpp index 6303478bc..749280c93 100644 --- a/Runtime/Graphics/Shaders/CAABoxShader.cpp +++ b/Runtime/Graphics/Shaders/CAABoxShader.cpp @@ -4,35 +4,35 @@ #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include #include namespace metaforce { -static boo::ObjToken s_Pipeline; -static boo::ObjToken s_zOnlyPipeline; +//static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_zOnlyPipeline; void CAABoxShader::Initialize() { - s_Pipeline = hecl::conv->convert(Shader_CAABoxShader{}); - s_zOnlyPipeline = hecl::conv->convert(Shader_CAABoxShaderZOnly{}); +// s_Pipeline = hecl::conv->convert(Shader_CAABoxShader{}); +// s_zOnlyPipeline = hecl::conv->convert(Shader_CAABoxShaderZOnly{}); } void CAABoxShader::Shutdown() { - s_Pipeline.reset(); - s_zOnlyPipeline.reset(); +// s_Pipeline.reset(); +// s_zOnlyPipeline.reset(); } CAABoxShader::CAABoxShader(bool zOnly) { - CGraphics::CommitResources([this, zOnly](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(zeus::CVector3f), 34); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - m_dataBind = - ctx.newShaderDataBinding(zOnly ? s_zOnlyPipeline : s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), - bufs.data(), stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([this, zOnly](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(zeus::CVector3f), 34); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// m_dataBind = +// ctx.newShaderDataBinding(zOnly ? s_zOnlyPipeline : s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), +// bufs.data(), stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); +// return true; +// } BooTrace); } void CAABoxShader::setAABB(const zeus::CAABox& aabb) { @@ -62,18 +62,18 @@ void CAABoxShader::setAABB(const zeus::CAABox& aabb) { {aabb.max.x(), aabb.max.y(), aabb.min.z()}, }}; - m_vbo->load(vboData.data(), sizeof(vboData)); +// m_vbo->load(vboData.data(), sizeof(vboData)); } void CAABoxShader::draw(const zeus::CColor& color) { SCOPED_GRAPHICS_DEBUG_GROUP("CAABoxShader::draw", zeus::skMagenta); - m_uniform.m_xf = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniform.m_xf = CGraphics::GetPerspectiveProjectionMatrix(/*true*/) * CGraphics::g_GXModelView.toMatrix4f(); m_uniform.m_color = color; - m_uniBuf->load(&m_uniform, sizeof(Uniform)); - - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 34); +// m_uniBuf->load(&m_uniform, sizeof(Uniform)); +// +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 34); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CAABoxShader.hpp b/Runtime/Graphics/Shaders/CAABoxShader.hpp index 831a58234..ec201302c 100644 --- a/Runtime/Graphics/Shaders/CAABoxShader.hpp +++ b/Runtime/Graphics/Shaders/CAABoxShader.hpp @@ -1,6 +1,6 @@ #pragma once -#include +//#include #include #include @@ -16,9 +16,9 @@ class CAABoxShader { zeus::CMatrix4f m_xf; zeus::CColor m_color; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; public: diff --git a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp index 341ac9afe..82bd316c7 100644 --- a/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp +++ b/Runtime/Graphics/Shaders/CCameraBlurFilter.cpp @@ -6,7 +6,7 @@ #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include #include namespace metaforce { @@ -16,24 +16,28 @@ struct Vert { zeus::CVector2f m_uv; }; -boo::ObjToken s_Pipeline; +//boo::ObjToken s_Pipeline; } // Anonymous namespace -void CCameraBlurFilter::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CCameraBlurFilter{}); } +void CCameraBlurFilter::Initialize() { +// s_Pipeline = hecl::conv->convert(Shader_CCameraBlurFilter{}); +} -void CCameraBlurFilter::Shutdown() { s_Pipeline.reset(); } +void CCameraBlurFilter::Shutdown() { +// s_Pipeline.reset(); +} CCameraBlurFilter::CCameraBlurFilter() { - CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 1> texs{CGraphics::g_SpareTexture.get()}; - m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 1> texs{CGraphics::g_SpareTexture.get()}; +// m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); } void CCameraBlurFilter::draw(float amount, bool clearDepth) { @@ -43,14 +47,14 @@ void CCameraBlurFilter::draw(float amount, bool clearDepth) { SCOPED_GRAPHICS_DEBUG_GROUP("CCameraBlurFilter::draw", zeus::skMagenta); - const SClipScreenRect clipRect(g_Viewport); - CGraphics::ResolveSpareTexture(clipRect, 0, clearDepth); + const SClipScreenRect clipRect(CGraphics::g_Viewport); +// CGraphics::ResolveSpareTexture(clipRect, 0, clearDepth); const float aspect = float(CGraphics::g_CroppedViewport.xc_width) / float(CGraphics::g_CroppedViewport.x10_height); - const float xFac = float(CGraphics::g_CroppedViewport.xc_width) / float(g_Viewport.x8_width); - const float yFac = float(CGraphics::g_CroppedViewport.x10_height) / float(g_Viewport.xc_height); - const float xBias = float(CGraphics::g_CroppedViewport.x4_left) / float(g_Viewport.x8_width); - const float yBias = float(CGraphics::g_CroppedViewport.x8_top) / float(g_Viewport.xc_height); + const float xFac = float(CGraphics::GetCroppedViewportWidth()) / float(CGraphics::GetViewportWidth()); + const float yFac = float(CGraphics::GetCroppedViewportHeight()) / float(CGraphics::GetViewportHeight()); + const float xBias = float(CGraphics::GetCroppedViewportLeft()) / float(CGraphics::GetViewportWidth()); + const float yBias = float(CGraphics::GetCroppedViewportTop()) / float(CGraphics::GetViewportHeight()); const std::array verts{{ {{-1.0, -1.0}, {xBias, yBias}}, @@ -58,7 +62,7 @@ void CCameraBlurFilter::draw(float amount, bool clearDepth) { {{1.0, -1.0}, {xBias + xFac, yBias}}, {{1.0, 1.0}, {xBias + xFac, yBias + yFac}}, }}; - m_vbo->load(verts.data(), sizeof(verts)); +// m_vbo->load(verts.data(), sizeof(verts)); for (size_t i = 0; i < m_uniform.m_uv.size(); ++i) { auto tmp = static_cast(i); @@ -75,10 +79,10 @@ void CCameraBlurFilter::draw(float amount, bool clearDepth) { m_uniform.m_uv[i][1] = amtY * yFac; } m_uniform.m_opacity = std::min(amount / 2.f, 1.f); - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp b/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp index 0c1235b43..46fe2dc03 100644 --- a/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp +++ b/Runtime/Graphics/Shaders/CCameraBlurFilter.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +//#include #include namespace metaforce { @@ -12,9 +12,9 @@ class CCameraBlurFilter { float m_opacity = 1.f; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; public: diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp b/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp index da9b3c921..006c76aac 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilter.cpp @@ -5,61 +5,62 @@ #include "Runtime/Camera/CCameraFilter.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_AlphaPipeline; -static boo::ObjToken s_AddPipeline; -static boo::ObjToken s_MultPipeline; +// static boo::ObjToken s_AlphaPipeline; +// static boo::ObjToken s_AddPipeline; +// static boo::ObjToken s_MultPipeline; void CColoredQuadFilter::Initialize() { - s_AlphaPipeline = hecl::conv->convert(Shader_CColoredQuadFilter{}); - s_AddPipeline = hecl::conv->convert(Shader_CColoredQuadFilterAdd{}); - s_MultPipeline = hecl::conv->convert(Shader_CColoredQuadFilterMul{}); + // s_AlphaPipeline = hecl::conv->convert(Shader_CColoredQuadFilter{}); + // s_AddPipeline = hecl::conv->convert(Shader_CColoredQuadFilterAdd{}); + // s_MultPipeline = hecl::conv->convert(Shader_CColoredQuadFilterMul{}); } void CColoredQuadFilter::Shutdown() { - s_AlphaPipeline.reset(); - s_AddPipeline.reset(); - s_MultPipeline.reset(); + // s_AlphaPipeline.reset(); + // s_AddPipeline.reset(); + // s_MultPipeline.reset(); } -static boo::ObjToken SelectPipeline(EFilterType type) { - switch (type) { - case EFilterType::Blend: - return s_AlphaPipeline; - case EFilterType::Add: - return s_AddPipeline; - case EFilterType::Multiply: - return s_MultPipeline; - default: - return s_AlphaPipeline; - } -} +// static boo::ObjToken SelectPipeline(EFilterType type) { +// switch (type) { +// case EFilterType::Blend: +// return s_AlphaPipeline; +// case EFilterType::Add: +// return s_AddPipeline; +// case EFilterType::Multiply: +// return s_MultPipeline; +// default: +// return s_AlphaPipeline; +// } +// } CColoredQuadFilter::CColoredQuadFilter(EFilterType type) { - CGraphics::CommitResources([this, type](boo::IGraphicsDataFactory::Context& ctx) { - struct Vert { - zeus::CVector2f m_pos; - }; - - const std::array verts{{ - {{0.0, 0.0}}, - {{0.0, 1.0}}, - {{1.0, 0.0}}, - {{1.0, 1.0}}, - }}; - - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 16, verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - m_dataBind = ctx.newShaderDataBinding(SelectPipeline(type), m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); - return true; - } BooTrace); + // CGraphics::CommitResources([this, type](boo::IGraphicsDataFactory::Context& ctx) { + // struct Vert { + // zeus::CVector2f m_pos; + // }; + // + // const std::array verts{{ + // {{0.0, 0.0}}, + // {{0.0, 1.0}}, + // {{1.0, 0.0}}, + // {{1.0, 1.0}}, + // }}; + // + // m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 16, verts.size()); + // m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); + // + // const std::array, 1> bufs{m_uniBuf.get()}; + // constexpr std::array stages{boo::PipelineStage::Vertex}; + // m_dataBind = ctx.newShaderDataBinding(SelectPipeline(type), m_vbo.get(), nullptr, nullptr, bufs.size(), + // bufs.data(), + // stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); + // return true; + // } BooTrace); } void CColoredQuadFilter::draw(const zeus::CColor& color, const zeus::CRectangle& rect) { @@ -70,17 +71,17 @@ void CColoredQuadFilter::draw(const zeus::CColor& color, const zeus::CRectangle& m_uniform.m_matrix[3][0] = rect.position.x() * 2.f - 1.f; m_uniform.m_matrix[3][1] = rect.position.y() * 2.f - 1.f; m_uniform.m_color = color; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); + // m_uniBuf->load(&m_uniform, sizeof(m_uniform)); + // + // CGraphics::SetShaderDataBinding(m_dataBind); + // CGraphics::DrawArray(0, 4); } void CWideScreenFilter::draw(const zeus::CColor& color, float t) { - if (g_Viewport.aspect < 1.7777f) { - float targetHeight = g_Viewport.x8_width / 1.7777f; - float delta = (g_Viewport.xc_height - targetHeight) * t / 2.f; - delta /= float(g_Viewport.xc_height); + if (CGraphics::GetViewportAspect() < 1.7777f) { + float targetHeight = CGraphics::GetViewportWidth() / 1.7777f; + float delta = (CGraphics::GetViewportHeight() - targetHeight) * t / 2.f; + delta /= float(CGraphics::GetViewportHeight()); zeus::CRectangle rect(0.f, 0.f, 1.f, delta); m_bottom.draw(color, rect); rect.position.y() = 1.f - delta; @@ -89,28 +90,28 @@ void CWideScreenFilter::draw(const zeus::CColor& color, float t) { } float CWideScreenFilter::SetViewportToMatch(float t) { - if (g_Viewport.aspect < 1.7777f) { - float targetHeight = g_Viewport.x8_width / 1.7777f; - float delta = (g_Viewport.xc_height - targetHeight) * t / 2.f; - boo::SWindowRect rect = {}; - rect.size[0] = g_Viewport.x8_width; - rect.size[1] = g_Viewport.xc_height - delta * 2.f; - rect.location[1] = delta; - CGraphics::g_CroppedViewport = rect; - CGraphics::g_BooMainCommandQueue->setViewport(rect); + if (CGraphics::GetViewportAspect() < 1.7777f) { + float targetHeight = CGraphics::GetViewportWidth() / 1.7777f; + float delta = (CGraphics::GetViewportHeight() - targetHeight) * t / 2.f; + // boo::SWindowRect rect = {}; + // rect.size[0] = g_Viewport.x8_width; + // rect.size[1] = g_Viewport.xc_height - delta * 2.f; + // rect.location[1] = delta; + // CGraphics::g_CroppedViewport = rect; + // CGraphics::g_BooMainCommandQueue->setViewport(rect); return 1.7777f; - } else { - SetViewportToFull(); - return g_Viewport.aspect; } + + SetViewportToFull(); + return CGraphics::GetViewportAspect(); } void CWideScreenFilter::SetViewportToFull() { - boo::SWindowRect rect = {}; - rect.size[0] = g_Viewport.x8_width; - rect.size[1] = g_Viewport.xc_height; - CGraphics::g_CroppedViewport = rect; - CGraphics::g_BooMainCommandQueue->setViewport(rect); + // boo::SWindowRect rect = {}; + // rect.size[0] = g_Viewport.x8_width; + // rect.size[1] = g_Viewport.xc_height; + // CGraphics::g_CroppedViewport = rect; + // CGraphics::g_BooMainCommandQueue->setViewport(rect); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp b/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp index 388be7ce6..76d30f20c 100644 --- a/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp +++ b/Runtime/Graphics/Shaders/CColoredQuadFilter.hpp @@ -2,7 +2,7 @@ #include "Runtime/CToken.hpp" -#include +//#include #include #include @@ -19,9 +19,9 @@ class CColoredQuadFilter { zeus::CMatrix4f m_matrix; zeus::CColor m_color; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; public: diff --git a/Runtime/Graphics/Shaders/CColoredStripShader.cpp b/Runtime/Graphics/Shaders/CColoredStripShader.cpp index 1c2c8f716..10c12f780 100644 --- a/Runtime/Graphics/Shaders/CColoredStripShader.cpp +++ b/Runtime/Graphics/Shaders/CColoredStripShader.cpp @@ -3,87 +3,82 @@ #include #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_Pipeline; -static boo::ObjToken s_AdditivePipeline; -static boo::ObjToken s_FullAdditivePipeline; -static boo::ObjToken s_SubtractivePipeline; +//static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_AdditivePipeline; +//static boo::ObjToken s_FullAdditivePipeline; +//static boo::ObjToken s_SubtractivePipeline; void CColoredStripShader::Initialize() { - s_Pipeline = hecl::conv->convert(Shader_CColoredStripShader{}); - s_AdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderAdditive{}); - s_FullAdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderFullAdditive{}); - s_SubtractivePipeline = hecl::conv->convert(Shader_CColoredStripShaderSubtractive{}); +// s_Pipeline = hecl::conv->convert(Shader_CColoredStripShader{}); +// s_AdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderAdditive{}); +// s_FullAdditivePipeline = hecl::conv->convert(Shader_CColoredStripShaderFullAdditive{}); +// s_SubtractivePipeline = hecl::conv->convert(Shader_CColoredStripShaderSubtractive{}); } void CColoredStripShader::Shutdown() { - s_Pipeline.reset(); - s_AdditivePipeline.reset(); - s_FullAdditivePipeline.reset(); - s_SubtractivePipeline.reset(); +// s_Pipeline.reset(); +// s_AdditivePipeline.reset(); +// s_FullAdditivePipeline.reset(); +// s_SubtractivePipeline.reset(); } -static const boo::ObjToken& SelectPipeline(CColoredStripShader::Mode mode) { - switch (mode) { - case CColoredStripShader::Mode::Alpha: - default: - return s_Pipeline; - case CColoredStripShader::Mode::Additive: - return s_AdditivePipeline; - case CColoredStripShader::Mode::FullAdditive: - return s_FullAdditivePipeline; - case CColoredStripShader::Mode::Subtractive: - return s_SubtractivePipeline; - } -} +//static const boo::ObjToken& SelectPipeline(CColoredStripShader::Mode mode) { +// switch (mode) { +// case CColoredStripShader::Mode::Alpha: +// default: +// return s_Pipeline; +// case CColoredStripShader::Mode::Additive: +// return s_AdditivePipeline; +// case CColoredStripShader::Mode::FullAdditive: +// return s_FullAdditivePipeline; +// case CColoredStripShader::Mode::Subtractive: +// return s_SubtractivePipeline; +// } +//} +// +//void CColoredStripShader::BuildResources(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode, +// boo::ObjToken tex) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vert), maxVerts); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// std::array, 1> texs; +// if (tex) { +// texs[0] = tex; +// } else { +// texs[0] = g_Renderer->GetWhiteTexture(); +// } +// +// m_dataBind = ctx.newShaderDataBinding(SelectPipeline(mode), m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +//} -void CColoredStripShader::BuildResources(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode, - boo::ObjToken tex) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vert), maxVerts); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - std::array, 1> texs; - if (tex) { - texs[0] = tex; - } else { - texs[0] = g_Renderer->GetWhiteTexture(); - } - - m_dataBind = ctx.newShaderDataBinding(SelectPipeline(mode), m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); -} - -CColoredStripShader::CColoredStripShader(size_t maxVerts, Mode mode, boo::ObjToken tex) { - CGraphics::CommitResources([this, maxVerts, mode, tex](boo::IGraphicsDataFactory::Context& ctx) { - BuildResources(ctx, maxVerts, mode, tex); - return true; - } BooTrace); -} - -CColoredStripShader::CColoredStripShader(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode, - boo::ObjToken tex) { - BuildResources(ctx, maxVerts, mode, tex); +CColoredStripShader::CColoredStripShader(size_t maxVerts, Mode mode, CTexture& tex) { +// CGraphics::CommitResources([this, maxVerts, mode, tex](boo::IGraphicsDataFactory::Context& ctx) { +// BuildResources(ctx, maxVerts, mode, tex); +// return true; +// } BooTrace); } void CColoredStripShader::draw(const zeus::CColor& color, size_t numVerts, const Vert* verts) { SCOPED_GRAPHICS_DEBUG_GROUP("CColoredStripShader::draw", zeus::skMagenta); - m_vbo->load(verts, sizeof(Vert) * numVerts); +// m_vbo->load(verts, sizeof(Vert) * numVerts); - m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(/*true*/) * CGraphics::g_GXModelView.toMatrix4f(); m_uniform.m_color = color; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, numVerts); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, numVerts); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CColoredStripShader.hpp b/Runtime/Graphics/Shaders/CColoredStripShader.hpp index 620f7fdc6..ee0f356d5 100644 --- a/Runtime/Graphics/Shaders/CColoredStripShader.hpp +++ b/Runtime/Graphics/Shaders/CColoredStripShader.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include "Runtime/Graphics/CGraphics.hpp" #include #include @@ -16,13 +16,13 @@ private: zeus::CMatrix4f m_matrix; zeus::CColor m_color; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; - void BuildResources(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode, - boo::ObjToken tex); +// void BuildResources(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode, +// boo::ObjToken tex); public: struct Vert { @@ -32,9 +32,7 @@ public: }; static void Initialize(); static void Shutdown(); - CColoredStripShader(size_t maxVerts, Mode mode, boo::ObjToken tex); - CColoredStripShader(boo::IGraphicsDataFactory::Context& ctx, size_t maxVerts, Mode mode, - boo::ObjToken tex); + CColoredStripShader(size_t maxVerts, Mode mode, CTexture& tex); void draw(const zeus::CColor& color, size_t numVerts, const Vert* verts); }; diff --git a/Runtime/Graphics/Shaders/CDecalShaders.cpp b/Runtime/Graphics/Shaders/CDecalShaders.cpp index 28c0d45db..47c8d62a2 100644 --- a/Runtime/Graphics/Shaders/CDecalShaders.cpp +++ b/Runtime/Graphics/Shaders/CDecalShaders.cpp @@ -4,69 +4,69 @@ #include "Runtime/Particle/CDecal.hpp" -#include +//#include namespace metaforce { void CDecalShaders::Initialize() { - m_texZTestNoZWrite = hecl::conv->convert(Shader_CDecalShaderTexZTest{}); - m_texAdditiveZTest = hecl::conv->convert(Shader_CDecalShaderTexAdditiveZTest{}); - m_texRedToAlphaZTest = hecl::conv->convert(Shader_CDecalShaderTexRedToAlphaZTest{}); - m_noTexZTestNoZWrite = hecl::conv->convert(Shader_CDecalShaderNoTexZTest{}); - m_noTexAdditiveZTest = hecl::conv->convert(Shader_CDecalShaderNoTexAdditiveZTest{}); +// m_texZTestNoZWrite = hecl::conv->convert(Shader_CDecalShaderTexZTest{}); +// m_texAdditiveZTest = hecl::conv->convert(Shader_CDecalShaderTexAdditiveZTest{}); +// m_texRedToAlphaZTest = hecl::conv->convert(Shader_CDecalShaderTexRedToAlphaZTest{}); +// m_noTexZTestNoZWrite = hecl::conv->convert(Shader_CDecalShaderNoTexZTest{}); +// m_noTexAdditiveZTest = hecl::conv->convert(Shader_CDecalShaderNoTexAdditiveZTest{}); } void CDecalShaders::Shutdown() { - m_texZTestNoZWrite.reset(); - m_texAdditiveZTest.reset(); - m_texRedToAlphaZTest.reset(); - m_noTexZTestNoZWrite.reset(); - m_noTexAdditiveZTest.reset(); +// m_texZTestNoZWrite.reset(); +// m_texAdditiveZTest.reset(); +// m_texRedToAlphaZTest.reset(); +// m_noTexZTestNoZWrite.reset(); +// m_noTexAdditiveZTest.reset(); } -void CDecalShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CQuadDecal& decal) { - boo::ObjToken regPipeline; - boo::ObjToken redToAlphaPipeline; +void CDecalShaders::BuildShaderDataBinding(CQuadDecal& decal) { +// boo::ObjToken regPipeline; +// boo::ObjToken redToAlphaPipeline; - if (decal.m_desc->x14_TEX) { - if (decal.m_desc->x18_ADD) - regPipeline = m_texAdditiveZTest; - else - regPipeline = m_texZTestNoZWrite; - redToAlphaPipeline = m_texRedToAlphaZTest; - } else { - if (decal.m_desc->x18_ADD) - regPipeline = m_noTexAdditiveZTest; - else - regPipeline = m_noTexZTestNoZWrite; - } - - const SQuadDescr* const desc = decal.m_desc; - const CUVElement* const texr = desc->x14_TEX.get(); - size_t texCount = 0; - std::array, 1> textures; - - if (texr != nullptr) { - textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture(); - texCount = 1; - } - - if (!decal.m_instBuf) { - return; - } - - std::array, 1> uniforms{decal.m_uniformBuf.get()}; - - if (regPipeline) { - decal.m_normalDataBind = - ctx.newShaderDataBinding(regPipeline, nullptr, decal.m_instBuf.get(), nullptr, uniforms.size(), uniforms.data(), - nullptr, texCount, textures.data(), nullptr, nullptr); - } - if (redToAlphaPipeline) { - decal.m_redToAlphaDataBind = - ctx.newShaderDataBinding(redToAlphaPipeline, nullptr, decal.m_instBuf.get(), nullptr, uniforms.size(), - uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); - } +// if (decal.m_desc->x14_TEX) { +// if (decal.m_desc->x18_ADD) +// regPipeline = m_texAdditiveZTest; +// else +// regPipeline = m_texZTestNoZWrite; +// redToAlphaPipeline = m_texRedToAlphaZTest; +// } else { +// if (decal.m_desc->x18_ADD) +// regPipeline = m_noTexAdditiveZTest; +// else +// regPipeline = m_noTexZTestNoZWrite; +// } +// +// const SQuadDescr* const desc = decal.m_desc; +// const CUVElement* const texr = desc->x14_TEX.get(); +// size_t texCount = 0; +// std::array, 1> textures; +// +// if (texr != nullptr) { +// textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture(); +// texCount = 1; +// } +// +// if (!decal.m_instBuf) { +// return; +// } +// +// std::array, 1> uniforms{decal.m_uniformBuf.get()}; +// +// if (regPipeline) { +// decal.m_normalDataBind = +// ctx.newShaderDataBinding(regPipeline, nullptr, decal.m_instBuf.get(), nullptr, uniforms.size(), uniforms.data(), +// nullptr, texCount, textures.data(), nullptr, nullptr); +// } +// if (redToAlphaPipeline) { +// decal.m_redToAlphaDataBind = +// ctx.newShaderDataBinding(redToAlphaPipeline, nullptr, decal.m_instBuf.get(), nullptr, uniforms.size(), +// uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); +// } } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CDecalShaders.hpp b/Runtime/Graphics/Shaders/CDecalShaders.hpp index 32a402961..53cde90f4 100644 --- a/Runtime/Graphics/Shaders/CDecalShaders.hpp +++ b/Runtime/Graphics/Shaders/CDecalShaders.hpp @@ -1,23 +1,23 @@ #pragma once -#include +//#include namespace metaforce { struct CQuadDecal; class CDecalShaders { private: - static inline boo::ObjToken m_texZTestNoZWrite; - static inline boo::ObjToken m_texAdditiveZTest; - static inline boo::ObjToken m_texRedToAlphaZTest; - - static inline boo::ObjToken m_noTexZTestNoZWrite; - static inline boo::ObjToken m_noTexAdditiveZTest; +// static inline boo::ObjToken m_texZTestNoZWrite; +// static inline boo::ObjToken m_texAdditiveZTest; +// static inline boo::ObjToken m_texRedToAlphaZTest; +// +// static inline boo::ObjToken m_noTexZTestNoZWrite; +// static inline boo::ObjToken m_noTexAdditiveZTest; public: static void Initialize(); static void Shutdown(); - static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CQuadDecal& decal); + static void BuildShaderDataBinding(CQuadDecal& decal); }; } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CElementGenShaders.cpp b/Runtime/Graphics/Shaders/CElementGenShaders.cpp index 1648b88bb..90f39c69e 100644 --- a/Runtime/Graphics/Shaders/CElementGenShaders.cpp +++ b/Runtime/Graphics/Shaders/CElementGenShaders.cpp @@ -4,116 +4,116 @@ #include "Runtime/Particle/CElementGen.hpp" -#include +//#include namespace metaforce { void CElementGenShaders::Initialize() { - m_texZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{})}; - m_texNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWriteAWrite{})}; - m_texZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteAWrite{})}; - m_texNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteAWrite{})}; - m_texAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTest{}), - hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTestAWrite{})}; - m_texAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTest{}), - hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTestAWrite{})}; - m_texRedToAlphaZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTest{}), - hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestAWrite{})}; - m_texRedToAlphaNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTest{}), - hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestAWrite{})}; - m_texZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSub{}), - hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSubAWrite{})}; - m_texNoZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSub{}), - hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSubAWrite{})}; - m_texRedToAlphaZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSub{}), - hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSubAWrite{})}; - m_texRedToAlphaNoZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSub{}), - hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSubAWrite{})}; - - m_indTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderIndTexZWriteAWrite{})}; - m_indTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWriteAWrite{})}; - m_indTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderIndTexAdditive{}), - hecl::conv->convert(Shader_CElementGenShaderIndTexAdditiveAWrite{})}; - - m_cindTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderCindTexZWriteAWrite{})}; - m_cindTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWriteAWrite{})}; - m_cindTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderCindTexAdditive{}), - hecl::conv->convert(Shader_CElementGenShaderCindTexAdditiveAWrite{})}; - - m_noTexZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWriteAWrite{})}; - m_noTexNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWriteAWrite{})}; - m_noTexZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWriteAWrite{})}; - m_noTexNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWrite{}), - hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWriteAWrite{})}; - m_noTexAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTest{}), - hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTestAWrite{})}; - m_noTexAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTest{}), - hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTestAWrite{})}; +// m_texZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderTexZTestZWrite{})}; +// m_texNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderTexNoZTestZWriteAWrite{})}; +// m_texZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteAWrite{})}; +// m_texNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteAWrite{})}; +// m_texAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTest{}), +// hecl::conv->convert(Shader_CElementGenShaderTexAdditiveZTestAWrite{})}; +// m_texAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTest{}), +// hecl::conv->convert(Shader_CElementGenShaderTexAdditiveNoZTestAWrite{})}; +// m_texRedToAlphaZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTest{}), +// hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestAWrite{})}; +// m_texRedToAlphaNoZTest = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTest{}), +// hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestAWrite{})}; +// m_texZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSub{}), +// hecl::conv->convert(Shader_CElementGenShaderTexZTestNoZWriteSubAWrite{})}; +// m_texNoZTestNoZWriteSub = {hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSub{}), +// hecl::conv->convert(Shader_CElementGenShaderTexNoZTestNoZWriteSubAWrite{})}; +// m_texRedToAlphaZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSub{}), +// hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaZTestSubAWrite{})}; +// m_texRedToAlphaNoZTestSub = {hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSub{}), +// hecl::conv->convert(Shader_CElementGenShaderTexRedToAlphaNoZTestSubAWrite{})}; +// +// m_indTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderIndTexZWriteAWrite{})}; +// m_indTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderIndTexNoZWriteAWrite{})}; +// m_indTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderIndTexAdditive{}), +// hecl::conv->convert(Shader_CElementGenShaderIndTexAdditiveAWrite{})}; +// +// m_cindTexZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderCindTexZWriteAWrite{})}; +// m_cindTexNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderCindTexNoZWriteAWrite{})}; +// m_cindTexAdditive = {hecl::conv->convert(Shader_CElementGenShaderCindTexAdditive{}), +// hecl::conv->convert(Shader_CElementGenShaderCindTexAdditiveAWrite{})}; +// +// m_noTexZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderNoTexZTestZWriteAWrite{})}; +// m_noTexNoZTestZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestZWriteAWrite{})}; +// m_noTexZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderNoTexZTestNoZWriteAWrite{})}; +// m_noTexNoZTestNoZWrite = {hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWrite{}), +// hecl::conv->convert(Shader_CElementGenShaderNoTexNoZTestNoZWriteAWrite{})}; +// m_noTexAdditiveZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTest{}), +// hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveZTestAWrite{})}; +// m_noTexAdditiveNoZTest = {hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTest{}), +// hecl::conv->convert(Shader_CElementGenShaderNoTexAdditiveNoZTestAWrite{})}; } void CElementGenShaders::Shutdown() { - for (auto& s : m_texZTestZWrite) - s.reset(); - for (auto& s : m_texNoZTestZWrite) - s.reset(); - for (auto& s : m_texZTestNoZWrite) - s.reset(); - for (auto& s : m_texNoZTestNoZWrite) - s.reset(); - for (auto& s : m_texAdditiveZTest) - s.reset(); - for (auto& s : m_texAdditiveNoZTest) - s.reset(); - for (auto& s : m_texRedToAlphaZTest) - s.reset(); - for (auto& s : m_texRedToAlphaNoZTest) - s.reset(); - for (auto& s : m_texZTestNoZWriteSub) - s.reset(); - for (auto& s : m_texNoZTestNoZWriteSub) - s.reset(); - for (auto& s : m_texRedToAlphaZTestSub) - s.reset(); - for (auto& s : m_texRedToAlphaNoZTestSub) - s.reset(); - - for (auto& s : m_indTexZWrite) - s.reset(); - for (auto& s : m_indTexNoZWrite) - s.reset(); - for (auto& s : m_indTexAdditive) - s.reset(); - - for (auto& s : m_cindTexZWrite) - s.reset(); - for (auto& s : m_cindTexNoZWrite) - s.reset(); - for (auto& s : m_cindTexAdditive) - s.reset(); - - for (auto& s : m_noTexZTestZWrite) - s.reset(); - for (auto& s : m_noTexNoZTestZWrite) - s.reset(); - for (auto& s : m_noTexZTestNoZWrite) - s.reset(); - for (auto& s : m_noTexNoZTestNoZWrite) - s.reset(); - for (auto& s : m_noTexAdditiveZTest) - s.reset(); - for (auto& s : m_noTexAdditiveNoZTest) - s.reset(); +// for (auto& s : m_texZTestZWrite) +// s.reset(); +// for (auto& s : m_texNoZTestZWrite) +// s.reset(); +// for (auto& s : m_texZTestNoZWrite) +// s.reset(); +// for (auto& s : m_texNoZTestNoZWrite) +// s.reset(); +// for (auto& s : m_texAdditiveZTest) +// s.reset(); +// for (auto& s : m_texAdditiveNoZTest) +// s.reset(); +// for (auto& s : m_texRedToAlphaZTest) +// s.reset(); +// for (auto& s : m_texRedToAlphaNoZTest) +// s.reset(); +// for (auto& s : m_texZTestNoZWriteSub) +// s.reset(); +// for (auto& s : m_texNoZTestNoZWriteSub) +// s.reset(); +// for (auto& s : m_texRedToAlphaZTestSub) +// s.reset(); +// for (auto& s : m_texRedToAlphaNoZTestSub) +// s.reset(); +// +// for (auto& s : m_indTexZWrite) +// s.reset(); +// for (auto& s : m_indTexNoZWrite) +// s.reset(); +// for (auto& s : m_indTexAdditive) +// s.reset(); +// +// for (auto& s : m_cindTexZWrite) +// s.reset(); +// for (auto& s : m_cindTexNoZWrite) +// s.reset(); +// for (auto& s : m_cindTexAdditive) +// s.reset(); +// +// for (auto& s : m_noTexZTestZWrite) +// s.reset(); +// for (auto& s : m_noTexNoZTestZWrite) +// s.reset(); +// for (auto& s : m_noTexZTestNoZWrite) +// s.reset(); +// for (auto& s : m_noTexNoZTestNoZWrite) +// s.reset(); +// for (auto& s : m_noTexAdditiveZTest) +// s.reset(); +// for (auto& s : m_noTexAdditiveNoZTest) +// s.reset(); } CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& gen) { @@ -128,171 +128,171 @@ CElementGenShaders::EShaderClass CElementGenShaders::GetShaderClass(CElementGen& return EShaderClass::NoTex; } -void CElementGenShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CElementGen& gen) { +void CElementGenShaders::BuildShaderDataBinding(CElementGen& gen) { CGenDescription* desc = gen.x1c_genDesc.GetObj(); - std::array, 2>* regPipeline = nullptr; - std::array, 2>* regPipelineSub = nullptr; - std::array, 2>* redToAlphaPipeline = nullptr; - std::array, 2>* redToAlphaPipelineSub = nullptr; - std::array, 2>* regPipelinePmus = nullptr; - std::array, 2>* redToAlphaPipelinePmus = nullptr; - - if (gen.x26c_28_zTest) { - redToAlphaPipeline = &m_texRedToAlphaZTest; - regPipelineSub = &m_texZTestNoZWriteSub; - redToAlphaPipelineSub = &m_texRedToAlphaZTestSub; - } else { - redToAlphaPipeline = &m_texRedToAlphaNoZTest; - regPipelineSub = &m_texNoZTestNoZWriteSub; - redToAlphaPipelineSub = &m_texRedToAlphaNoZTestSub; - } - - if (desc->x54_x40_TEXR) { - if (desc->x58_x44_TIND) { - if (desc->x45_30_x32_24_CIND) { - if (gen.x26c_26_AAPH) - regPipeline = &m_cindTexAdditive; - else { - if (gen.x26c_27_ZBUF) - regPipeline = &m_cindTexZWrite; - else - regPipeline = &m_cindTexNoZWrite; - } - } else { - if (gen.x26c_26_AAPH) - regPipeline = &m_indTexAdditive; - else { - if (gen.x26c_27_ZBUF) - regPipeline = &m_indTexZWrite; - else - regPipeline = &m_indTexNoZWrite; - } - } - } else { - if (gen.x26c_26_AAPH) { - if (gen.x26c_28_zTest) - regPipeline = &m_texAdditiveZTest; - else - regPipeline = &m_texAdditiveNoZTest; - } else { - if (gen.x26c_28_zTest) { - if (gen.x26c_27_ZBUF) - regPipeline = &m_texZTestZWrite; - else - regPipeline = &m_texZTestNoZWrite; - } else { - if (gen.x26c_27_ZBUF) - regPipeline = &m_texNoZTestZWrite; - else - regPipeline = &m_texNoZTestNoZWrite; - } - } - } - } else { - if (gen.x26c_26_AAPH) { - if (gen.x26c_28_zTest) - regPipeline = &m_noTexAdditiveZTest; - else - regPipeline = &m_noTexAdditiveNoZTest; - } else { - if (gen.x26c_28_zTest) { - if (gen.x26c_27_ZBUF) - regPipeline = &m_noTexZTestZWrite; - else - regPipeline = &m_noTexZTestNoZWrite; - } else { - if (gen.x26c_27_ZBUF) - regPipeline = &m_noTexNoZTestZWrite; - else - regPipeline = &m_noTexNoZTestNoZWrite; - } - } - } - - if (desc->x45_24_x31_26_PMUS) { - if (desc->x54_x40_TEXR) { - redToAlphaPipelinePmus = &m_texRedToAlphaZTest; - if (desc->x44_31_x31_25_PMAB) - regPipelinePmus = &m_texAdditiveZTest; - else - regPipelinePmus = &m_texZTestZWrite; - } else { - if (desc->x44_31_x31_25_PMAB) - regPipelinePmus = &m_noTexAdditiveZTest; - else - regPipelinePmus = &m_noTexZTestZWrite; - } - } - - const CUVElement* const texr = desc->x54_x40_TEXR.get(); - const CUVElement* const tind = desc->x58_x44_TIND.get(); - int texCount = 0; - std::array, 3> textures; - - if (texr) { - textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture(); - texCount = 1; - if (gen.m_instBuf) { - if (tind) { - textures[1] = CGraphics::g_SpareTexture.get(); - textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture(); - texCount = 3; - } - } - } - - if (gen.m_instBuf) { - const std::array, 1> uniforms{gen.m_uniformBuf.get()}; - - if (regPipeline != nullptr) { - for (size_t i = 0; i < gen.m_normalDataBind.size(); ++i) { - gen.m_normalDataBind[i] = - ctx.newShaderDataBinding((*regPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), - uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); - } - } - if (regPipelineSub != nullptr) { - for (size_t i = 0; i < gen.m_normalSubDataBind.size(); ++i) { - gen.m_normalSubDataBind[i] = - ctx.newShaderDataBinding((*regPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), - uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); - } - } - if (redToAlphaPipeline != nullptr) { - for (size_t i = 0; i < gen.m_redToAlphaDataBind.size(); ++i) { - gen.m_redToAlphaDataBind[i] = - ctx.newShaderDataBinding((*redToAlphaPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), - uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); - } - } - if (redToAlphaPipelineSub != nullptr) { - for (size_t i = 0; i < gen.m_redToAlphaSubDataBind.size(); ++i) { - gen.m_redToAlphaSubDataBind[i] = ctx.newShaderDataBinding( - (*redToAlphaPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), uniforms.data(), - nullptr, texCount, textures.data(), nullptr, nullptr); - } - } - } - - if (gen.m_instBufPmus) { - const std::array, 1> uniforms{gen.m_uniformBufPmus.get()}; - texCount = std::min(texCount, 1); - - if (regPipelinePmus != nullptr) { - for (size_t i = 0; i < gen.m_normalDataBindPmus.size(); ++i) { - gen.m_normalDataBindPmus[i] = - ctx.newShaderDataBinding((*regPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(), - uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); - } - } - if (redToAlphaPipelinePmus != nullptr) { - for (size_t i = 0; i < gen.m_redToAlphaDataBindPmus.size(); ++i) { - gen.m_redToAlphaDataBindPmus[i] = ctx.newShaderDataBinding( - (*redToAlphaPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(), uniforms.data(), - nullptr, texCount, textures.data(), nullptr, nullptr); - } - } - } +// std::array, 2>* regPipeline = nullptr; +// std::array, 2>* regPipelineSub = nullptr; +// std::array, 2>* redToAlphaPipeline = nullptr; +// std::array, 2>* redToAlphaPipelineSub = nullptr; +// std::array, 2>* regPipelinePmus = nullptr; +// std::array, 2>* redToAlphaPipelinePmus = nullptr; +// +// if (gen.x26c_28_zTest) { +// redToAlphaPipeline = &m_texRedToAlphaZTest; +// regPipelineSub = &m_texZTestNoZWriteSub; +// redToAlphaPipelineSub = &m_texRedToAlphaZTestSub; +// } else { +// redToAlphaPipeline = &m_texRedToAlphaNoZTest; +// regPipelineSub = &m_texNoZTestNoZWriteSub; +// redToAlphaPipelineSub = &m_texRedToAlphaNoZTestSub; +// } +// +// if (desc->x54_x40_TEXR) { +// if (desc->x58_x44_TIND) { +// if (desc->x45_30_x32_24_CIND) { +// if (gen.x26c_26_AAPH) +// regPipeline = &m_cindTexAdditive; +// else { +// if (gen.x26c_27_ZBUF) +// regPipeline = &m_cindTexZWrite; +// else +// regPipeline = &m_cindTexNoZWrite; +// } +// } else { +// if (gen.x26c_26_AAPH) +// regPipeline = &m_indTexAdditive; +// else { +// if (gen.x26c_27_ZBUF) +// regPipeline = &m_indTexZWrite; +// else +// regPipeline = &m_indTexNoZWrite; +// } +// } +// } else { +// if (gen.x26c_26_AAPH) { +// if (gen.x26c_28_zTest) +// regPipeline = &m_texAdditiveZTest; +// else +// regPipeline = &m_texAdditiveNoZTest; +// } else { +// if (gen.x26c_28_zTest) { +// if (gen.x26c_27_ZBUF) +// regPipeline = &m_texZTestZWrite; +// else +// regPipeline = &m_texZTestNoZWrite; +// } else { +// if (gen.x26c_27_ZBUF) +// regPipeline = &m_texNoZTestZWrite; +// else +// regPipeline = &m_texNoZTestNoZWrite; +// } +// } +// } +// } else { +// if (gen.x26c_26_AAPH) { +// if (gen.x26c_28_zTest) +// regPipeline = &m_noTexAdditiveZTest; +// else +// regPipeline = &m_noTexAdditiveNoZTest; +// } else { +// if (gen.x26c_28_zTest) { +// if (gen.x26c_27_ZBUF) +// regPipeline = &m_noTexZTestZWrite; +// else +// regPipeline = &m_noTexZTestNoZWrite; +// } else { +// if (gen.x26c_27_ZBUF) +// regPipeline = &m_noTexNoZTestZWrite; +// else +// regPipeline = &m_noTexNoZTestNoZWrite; +// } +// } +// } +// +// if (desc->x45_24_x31_26_PMUS) { +// if (desc->x54_x40_TEXR) { +// redToAlphaPipelinePmus = &m_texRedToAlphaZTest; +// if (desc->x44_31_x31_25_PMAB) +// regPipelinePmus = &m_texAdditiveZTest; +// else +// regPipelinePmus = &m_texZTestZWrite; +// } else { +// if (desc->x44_31_x31_25_PMAB) +// regPipelinePmus = &m_noTexAdditiveZTest; +// else +// regPipelinePmus = &m_noTexZTestZWrite; +// } +// } +// +// const CUVElement* const texr = desc->x54_x40_TEXR.get(); +// const CUVElement* const tind = desc->x58_x44_TIND.get(); +// int texCount = 0; +// std::array, 3> textures; +// +// if (texr) { +// textures[0] = texr->GetValueTexture(0).GetObj()->GetBooTexture(); +// texCount = 1; +// if (gen.m_instBuf) { +// if (tind) { +// textures[1] = CGraphics::g_SpareTexture.get(); +// textures[2] = tind->GetValueTexture(0).GetObj()->GetBooTexture(); +// texCount = 3; +// } +// } +// } +// +// if (gen.m_instBuf) { +// const std::array, 1> uniforms{gen.m_uniformBuf.get()}; +// +// if (regPipeline != nullptr) { +// for (size_t i = 0; i < gen.m_normalDataBind.size(); ++i) { +// gen.m_normalDataBind[i] = +// ctx.newShaderDataBinding((*regPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), +// uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); +// } +// } +// if (regPipelineSub != nullptr) { +// for (size_t i = 0; i < gen.m_normalSubDataBind.size(); ++i) { +// gen.m_normalSubDataBind[i] = +// ctx.newShaderDataBinding((*regPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), +// uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); +// } +// } +// if (redToAlphaPipeline != nullptr) { +// for (size_t i = 0; i < gen.m_redToAlphaDataBind.size(); ++i) { +// gen.m_redToAlphaDataBind[i] = +// ctx.newShaderDataBinding((*redToAlphaPipeline)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), +// uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); +// } +// } +// if (redToAlphaPipelineSub != nullptr) { +// for (size_t i = 0; i < gen.m_redToAlphaSubDataBind.size(); ++i) { +// gen.m_redToAlphaSubDataBind[i] = ctx.newShaderDataBinding( +// (*redToAlphaPipelineSub)[i], nullptr, gen.m_instBuf.get(), nullptr, uniforms.size(), uniforms.data(), +// nullptr, texCount, textures.data(), nullptr, nullptr); +// } +// } +// } +// +// if (gen.m_instBufPmus) { +// const std::array, 1> uniforms{gen.m_uniformBufPmus.get()}; +// texCount = std::min(texCount, 1); +// +// if (regPipelinePmus != nullptr) { +// for (size_t i = 0; i < gen.m_normalDataBindPmus.size(); ++i) { +// gen.m_normalDataBindPmus[i] = +// ctx.newShaderDataBinding((*regPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(), +// uniforms.data(), nullptr, texCount, textures.data(), nullptr, nullptr); +// } +// } +// if (redToAlphaPipelinePmus != nullptr) { +// for (size_t i = 0; i < gen.m_redToAlphaDataBindPmus.size(); ++i) { +// gen.m_redToAlphaDataBindPmus[i] = ctx.newShaderDataBinding( +// (*redToAlphaPipelinePmus)[i], nullptr, gen.m_instBufPmus.get(), nullptr, uniforms.size(), uniforms.data(), +// nullptr, texCount, textures.data(), nullptr, nullptr); +// } +// } +// } } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CElementGenShaders.hpp b/Runtime/Graphics/Shaders/CElementGenShaders.hpp index 386e943d9..c5171a6c7 100644 --- a/Runtime/Graphics/Shaders/CElementGenShaders.hpp +++ b/Runtime/Graphics/Shaders/CElementGenShaders.hpp @@ -2,7 +2,7 @@ #include -#include +//#include namespace metaforce { class CElementGen; @@ -12,39 +12,39 @@ public: enum class EShaderClass { Tex, IndTex, NoTex }; private: - static inline std::array, 2> m_texZTestZWrite; - static inline std::array, 2> m_texNoZTestZWrite; - static inline std::array, 2> m_texZTestNoZWrite; - static inline std::array, 2> m_texNoZTestNoZWrite; - static inline std::array, 2> m_texAdditiveZTest; - static inline std::array, 2> m_texAdditiveNoZTest; - static inline std::array, 2> m_texRedToAlphaZTest; - static inline std::array, 2> m_texRedToAlphaNoZTest; - static inline std::array, 2> m_texZTestNoZWriteSub; - static inline std::array, 2> m_texNoZTestNoZWriteSub; - static inline std::array, 2> m_texRedToAlphaZTestSub; - static inline std::array, 2> m_texRedToAlphaNoZTestSub; - - static inline std::array, 2> m_indTexZWrite; - static inline std::array, 2> m_indTexNoZWrite; - static inline std::array, 2> m_indTexAdditive; - - static inline std::array, 2> m_cindTexZWrite; - static inline std::array, 2> m_cindTexNoZWrite; - static inline std::array, 2> m_cindTexAdditive; - - static inline std::array, 2> m_noTexZTestZWrite; - static inline std::array, 2> m_noTexNoZTestZWrite; - static inline std::array, 2> m_noTexZTestNoZWrite; - static inline std::array, 2> m_noTexNoZTestNoZWrite; - static inline std::array, 2> m_noTexAdditiveZTest; - static inline std::array, 2> m_noTexAdditiveNoZTest; +// static inline std::array, 2> m_texZTestZWrite; +// static inline std::array, 2> m_texNoZTestZWrite; +// static inline std::array, 2> m_texZTestNoZWrite; +// static inline std::array, 2> m_texNoZTestNoZWrite; +// static inline std::array, 2> m_texAdditiveZTest; +// static inline std::array, 2> m_texAdditiveNoZTest; +// static inline std::array, 2> m_texRedToAlphaZTest; +// static inline std::array, 2> m_texRedToAlphaNoZTest; +// static inline std::array, 2> m_texZTestNoZWriteSub; +// static inline std::array, 2> m_texNoZTestNoZWriteSub; +// static inline std::array, 2> m_texRedToAlphaZTestSub; +// static inline std::array, 2> m_texRedToAlphaNoZTestSub; +// +// static inline std::array, 2> m_indTexZWrite; +// static inline std::array, 2> m_indTexNoZWrite; +// static inline std::array, 2> m_indTexAdditive; +// +// static inline std::array, 2> m_cindTexZWrite; +// static inline std::array, 2> m_cindTexNoZWrite; +// static inline std::array, 2> m_cindTexAdditive; +// +// static inline std::array, 2> m_noTexZTestZWrite; +// static inline std::array, 2> m_noTexNoZTestZWrite; +// static inline std::array, 2> m_noTexZTestNoZWrite; +// static inline std::array, 2> m_noTexNoZTestNoZWrite; +// static inline std::array, 2> m_noTexAdditiveZTest; +// static inline std::array, 2> m_noTexAdditiveNoZTest; public: static void Initialize(); static void Shutdown(); static EShaderClass GetShaderClass(CElementGen& gen); - static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CElementGen& gen); + static void BuildShaderDataBinding(CElementGen& gen); }; } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CEnergyBarShader.cpp b/Runtime/Graphics/Shaders/CEnergyBarShader.cpp index 82810bdb4..c17ed0202 100644 --- a/Runtime/Graphics/Shaders/CEnergyBarShader.cpp +++ b/Runtime/Graphics/Shaders/CEnergyBarShader.cpp @@ -5,18 +5,22 @@ #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_Pipeline; -void CEnergyBarShader::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CEnergyBarShader{}); } +void CEnergyBarShader::Initialize() { +// s_Pipeline = hecl::conv->convert(Shader_CEnergyBarShader{}); +} -void CEnergyBarShader::Shutdown() { s_Pipeline.reset(); } +void CEnergyBarShader::Shutdown() { +// s_Pipeline.reset(); +} void CEnergyBarShader::updateModelMatrix() { - m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(/*true*/) * CGraphics::g_GXModelView.toMatrix4f(); } void CEnergyBarShader::draw(const zeus::CColor& color0, const std::vector& verts0, const zeus::CColor& color1, @@ -31,60 +35,60 @@ void CEnergyBarShader::draw(const zeus::CColor& color0, const std::vector m_maxVerts) { m_maxVerts = totalVerts; m_tex = tex; - CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), m_maxVerts); - - std::array, 1> bufs; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 1> texs{m_tex->GetBooTexture()}; - - for (size_t i = 0; i < m_uniBuf.size(); ++i) { - m_uniBuf[i] = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - bufs[0] = m_uniBuf[i].get(); - m_dataBind[i] = - ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), stages.data(), - nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - } - - return true; - } BooTrace); +// CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), m_maxVerts); +// +// std::array, 1> bufs; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 1> texs{m_tex->GetBooTexture()}; +// +// for (size_t i = 0; i < m_uniBuf.size(); ++i) { +// m_uniBuf[i] = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// bufs[0] = m_uniBuf[i].get(); +// m_dataBind[i] = +// ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), stages.data(), +// nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// } +// +// return true; +// } BooTrace); } size_t vertIter = 0; - Vertex* verts = reinterpret_cast(m_vbo->map(sizeof(Vertex) * totalVerts)); - if (verts0.size()) { - memmove(verts, verts0.data(), sizeof(Vertex) * verts0.size()); - vertIter += verts0.size(); - } - if (verts1.size()) { - memmove(verts + vertIter, verts1.data(), sizeof(Vertex) * verts1.size()); - vertIter += verts1.size(); - } - if (verts2.size()) { - memmove(verts + vertIter, verts2.data(), sizeof(Vertex) * verts2.size()); - } - m_vbo->unmap(); +// Vertex* verts = reinterpret_cast(m_vbo->map(sizeof(Vertex) * totalVerts)); +// if (verts0.size()) { +// memmove(verts, verts0.data(), sizeof(Vertex) * verts0.size()); +// vertIter += verts0.size(); +// } +// if (verts1.size()) { +// memmove(verts + vertIter, verts1.data(), sizeof(Vertex) * verts1.size()); +// vertIter += verts1.size(); +// } +// if (verts2.size()) { +// memmove(verts + vertIter, verts2.data(), sizeof(Vertex) * verts2.size()); +// } +// m_vbo->unmap(); vertIter = 0; if (verts0.size()) { m_uniform.m_color = color0; - m_uniBuf[0]->load(&m_uniform, sizeof(Uniform)); - CGraphics::SetShaderDataBinding(m_dataBind[0]); - CGraphics::DrawArray(0, verts0.size()); +// m_uniBuf[0]->load(&m_uniform, sizeof(Uniform)); +// CGraphics::SetShaderDataBinding(m_dataBind[0]); +// CGraphics::DrawArray(0, verts0.size()); vertIter += verts0.size(); } if (verts1.size()) { m_uniform.m_color = color1; - m_uniBuf[1]->load(&m_uniform, sizeof(Uniform)); - CGraphics::SetShaderDataBinding(m_dataBind[1]); - CGraphics::DrawArray(vertIter, verts1.size()); +// m_uniBuf[1]->load(&m_uniform, sizeof(Uniform)); +// CGraphics::SetShaderDataBinding(m_dataBind[1]); +// CGraphics::DrawArray(vertIter, verts1.size()); vertIter += verts1.size(); } if (verts2.size()) { m_uniform.m_color = color2; - m_uniBuf[2]->load(&m_uniform, sizeof(Uniform)); - CGraphics::SetShaderDataBinding(m_dataBind[2]); - CGraphics::DrawArray(vertIter, verts2.size()); +// m_uniBuf[2]->load(&m_uniform, sizeof(Uniform)); +// CGraphics::SetShaderDataBinding(m_dataBind[2]); +// CGraphics::DrawArray(vertIter, verts2.size()); } } diff --git a/Runtime/Graphics/Shaders/CEnergyBarShader.hpp b/Runtime/Graphics/Shaders/CEnergyBarShader.hpp index f04fa4330..6cb6b47a7 100644 --- a/Runtime/Graphics/Shaders/CEnergyBarShader.hpp +++ b/Runtime/Graphics/Shaders/CEnergyBarShader.hpp @@ -3,7 +3,7 @@ #include #include -#include +//#include #include #include @@ -25,9 +25,9 @@ private: zeus::CMatrix4f m_matrix; zeus::CColor m_color; }; - boo::ObjToken m_vbo; - std::array, 3> m_uniBuf; - std::array, 3> m_dataBind; +// boo::ObjToken m_vbo; +// std::array, 3> m_uniBuf; +// std::array, 3> m_dataBind; Uniform m_uniform; const CTexture* m_tex = nullptr; size_t m_maxVerts = 0; diff --git a/Runtime/Graphics/Shaders/CEnvFxShaders.cpp b/Runtime/Graphics/Shaders/CEnvFxShaders.cpp index 0a1d48fc5..7302486ea 100644 --- a/Runtime/Graphics/Shaders/CEnvFxShaders.cpp +++ b/Runtime/Graphics/Shaders/CEnvFxShaders.cpp @@ -2,56 +2,56 @@ #include "Runtime/World/CEnvFxManager.hpp" -#include +//#include namespace metaforce { -boo::ObjToken CEnvFxShaders::m_snowPipeline; -boo::ObjToken CEnvFxShaders::m_underwaterPipeline; +//boo::ObjToken CEnvFxShaders::m_snowPipeline; +//boo::ObjToken CEnvFxShaders::m_underwaterPipeline; void CEnvFxShaders::Initialize() { - m_snowPipeline = hecl::conv->convert(Shader_CEnvFxSnowShader{}); - m_underwaterPipeline = hecl::conv->convert(Shader_CEnvFxUnderwaterShader{}); +// m_snowPipeline = hecl::conv->convert(Shader_CEnvFxSnowShader{}); +// m_underwaterPipeline = hecl::conv->convert(Shader_CEnvFxUnderwaterShader{}); } void CEnvFxShaders::Shutdown() { - m_snowPipeline.reset(); - m_underwaterPipeline.reset(); +// m_snowPipeline.reset(); +// m_underwaterPipeline.reset(); } -void CEnvFxShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CEnvFxManager& fxMgr, +void CEnvFxShaders::BuildShaderDataBinding(CEnvFxManager& fxMgr, CEnvFxManagerGrid& grid) { - const auto uBufInfo = grid.m_uniformBuf.getBufferInfo(); - const auto iBufInfo = grid.m_instBuf.getBufferInfo(); +// const auto uBufInfo = grid.m_uniformBuf.getBufferInfo(); +// const auto iBufInfo = grid.m_instBuf.getBufferInfo(); - const std::array, 2> uniforms{{ - uBufInfo.first.get(), - fxMgr.m_fogUniformBuf.get(), - }}; - const std::array ubufOffsets{ - size_t(uBufInfo.second), - 0, - }; - constexpr std::array ubufSizes{ - sizeof(CEnvFxShaders::Uniform), - sizeof(CGraphics::g_Fog), - }; - constexpr std::array uniformStages{ - boo::PipelineStage::Vertex, - boo::PipelineStage::Fragment, - }; - std::array, 2> textures{ - fxMgr.xb74_txtrSnowFlake->GetBooTexture(), - fxMgr.x40_txtrEnvGradient->GetBooTexture(), - }; - - grid.m_snowBinding = ctx.newShaderDataBinding( - m_snowPipeline, nullptr, iBufInfo.first.get(), nullptr, uniforms.size(), uniforms.data(), uniformStages.data(), - ubufOffsets.data(), ubufSizes.data(), textures.size(), textures.data(), nullptr, nullptr, 0, iBufInfo.second); - textures[0] = fxMgr.xc48_underwaterFlake->GetBooTexture(); - grid.m_underwaterBinding = - ctx.newShaderDataBinding(m_underwaterPipeline, nullptr, iBufInfo.first.get(), nullptr, uniforms.size(), - uniforms.data(), uniformStages.data(), ubufOffsets.data(), ubufSizes.data(), - textures.size(), textures.data(), nullptr, nullptr, 0, iBufInfo.second); +// const std::array, 2> uniforms{{ +// uBufInfo.first.get(), +// fxMgr.m_fogUniformBuf.get(), +// }}; +// const std::array ubufOffsets{ +// size_t(uBufInfo.second), +// 0, +// }; +// constexpr std::array ubufSizes{ +// sizeof(CEnvFxShaders::Uniform), +// sizeof(CGraphics::g_Fog), +// }; +// constexpr std::array uniformStages{ +// boo::PipelineStage::Vertex, +// boo::PipelineStage::Fragment, +// }; +// std::array, 2> textures{ +// fxMgr.xb74_txtrSnowFlake->GetBooTexture(), +// fxMgr.x40_txtrEnvGradient->GetBooTexture(), +// }; +// +// grid.m_snowBinding = ctx.newShaderDataBinding( +// m_snowPipeline, nullptr, iBufInfo.first.get(), nullptr, uniforms.size(), uniforms.data(), uniformStages.data(), +// ubufOffsets.data(), ubufSizes.data(), textures.size(), textures.data(), nullptr, nullptr, 0, iBufInfo.second); +// textures[0] = fxMgr.xc48_underwaterFlake->GetBooTexture(); +// grid.m_underwaterBinding = +// ctx.newShaderDataBinding(m_underwaterPipeline, nullptr, iBufInfo.first.get(), nullptr, uniforms.size(), +// uniforms.data(), uniformStages.data(), ubufOffsets.data(), ubufSizes.data(), +// textures.size(), textures.data(), nullptr, nullptr, 0, iBufInfo.second); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CEnvFxShaders.hpp b/Runtime/Graphics/Shaders/CEnvFxShaders.hpp index 2425264b6..69fbbf5f5 100644 --- a/Runtime/Graphics/Shaders/CEnvFxShaders.hpp +++ b/Runtime/Graphics/Shaders/CEnvFxShaders.hpp @@ -2,7 +2,7 @@ #include -#include +//#include #include #include @@ -28,13 +28,13 @@ public: }; private: - static boo::ObjToken m_snowPipeline; - static boo::ObjToken m_underwaterPipeline; +// static boo::ObjToken m_snowPipeline; +// static boo::ObjToken m_underwaterPipeline; public: static void Initialize(); static void Shutdown(); - static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CEnvFxManager& fxMgr, + static void BuildShaderDataBinding(CEnvFxManager& fxMgr, CEnvFxManagerGrid& grid); }; diff --git a/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp b/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp index f11ffdc44..3dd8b1477 100644 --- a/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp +++ b/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp @@ -3,200 +3,202 @@ #include "Runtime/World/CRipple.hpp" #include "Runtime/World/CRippleManager.hpp" -#include +//#include namespace metaforce { -CFluidPlaneShader::Cache CFluidPlaneShader::_cache = {}; - -u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneShaderInfo& info) { - u16 ret = 0; - - switch (info.m_type) { - case EFluidType::NormalWater: - case EFluidType::PhazonFluid: - case EFluidType::Four: - if (info.m_hasLightmap) { - ret |= 1 << 2; - if (info.m_doubleLightmapBlend) - ret |= 1 << 3; - } - - if (!info.m_hasEnvMap && info.m_hasEnvBumpMap) - ret |= 1 << 4; - - if (info.m_hasEnvMap) - ret |= 1 << 5; - - break; - - case EFluidType::PoisonWater: - ret |= 1; - - if (info.m_hasLightmap) { - ret |= 1 << 2; - if (info.m_doubleLightmapBlend) - ret |= 1 << 3; - } - - if (info.m_hasEnvBumpMap) - ret |= 1 << 4; - - break; - - case EFluidType::Lava: - ret |= 2; - - if (info.m_hasBumpMap) - ret |= 1 << 2; - - break; - - case EFluidType::ThickLava: - ret |= 3; - - if (info.m_hasBumpMap) - ret |= 1 << 2; - - break; - } - - if (info.m_hasPatternTex1) - ret |= 1 << 6; - if (info.m_hasPatternTex2) - ret |= 1 << 7; - if (info.m_hasColorTex) - ret |= 1 << 8; - - if (info.m_additive) - ret |= 1 << 9; - - return ret; -} - -u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneDoorShaderInfo& info) { - u16 ret = 0; - - if (info.m_hasPatternTex1) - ret |= 1 << 0; - if (info.m_hasPatternTex2) - ret |= 1 << 1; - if (info.m_hasColorTex) - ret |= 1 << 2; - - return ret; -} - -template <> -CFluidPlaneShader::ShaderPair -CFluidPlaneShader::Cache::GetOrBuildShader(const SFluidPlaneShaderInfo& info) { - OPTICK_EVENT(); - u16 key = MakeCacheKey(info); - auto& slot = CacheSlot(info, key); - if (slot.m_regular) - return slot; - - slot.m_regular = hecl::conv->convert(Shader_CFluidPlaneShader{info, false}); - if (info.m_tessellation) - slot.m_tessellation = hecl::conv->convert(Shader_CFluidPlaneShader{info, true}); - - return slot; -} -template <> -CFluidPlaneShader::ShaderPair -CFluidPlaneShader::Cache::GetOrBuildShader(const SFluidPlaneDoorShaderInfo& info) { - OPTICK_EVENT(); - u16 key = MakeCacheKey(info); - auto& slot = CacheSlot(info, key); - if (slot.m_regular) - return slot; - - slot.m_regular = hecl::conv->convert(Shader_CFluidPlaneDoorShader{info}); - - return slot; -} - -void CFluidPlaneShader::Cache::Clear() { - for (auto& p : m_cache) - p.reset(); - for (auto& p : m_doorCache) - p.reset(); -} +//CFluidPlaneShader::Cache CFluidPlaneShader::_cache = {}; +// +//u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneShaderInfo& info) { +// u16 ret = 0; +// +// switch (info.m_type) { +// case EFluidType::NormalWater: +// case EFluidType::PhazonFluid: +// case EFluidType::Four: +// if (info.m_hasLightmap) { +// ret |= 1 << 2; +// if (info.m_doubleLightmapBlend) +// ret |= 1 << 3; +// } +// +// if (!info.m_hasEnvMap && info.m_hasEnvBumpMap) +// ret |= 1 << 4; +// +// if (info.m_hasEnvMap) +// ret |= 1 << 5; +// +// break; +// +// case EFluidType::PoisonWater: +// ret |= 1; +// +// if (info.m_hasLightmap) { +// ret |= 1 << 2; +// if (info.m_doubleLightmapBlend) +// ret |= 1 << 3; +// } +// +// if (info.m_hasEnvBumpMap) +// ret |= 1 << 4; +// +// break; +// +// case EFluidType::Lava: +// ret |= 2; +// +// if (info.m_hasBumpMap) +// ret |= 1 << 2; +// +// break; +// +// case EFluidType::ThickLava: +// ret |= 3; +// +// if (info.m_hasBumpMap) +// ret |= 1 << 2; +// +// break; +// } +// +// if (info.m_hasPatternTex1) +// ret |= 1 << 6; +// if (info.m_hasPatternTex2) +// ret |= 1 << 7; +// if (info.m_hasColorTex) +// ret |= 1 << 8; +// +// if (info.m_additive) +// ret |= 1 << 9; +// +// return ret; +//} +// +//u16 CFluidPlaneShader::Cache::MakeCacheKey(const SFluidPlaneDoorShaderInfo& info) { +// u16 ret = 0; +// +// if (info.m_hasPatternTex1) +// ret |= 1 << 0; +// if (info.m_hasPatternTex2) +// ret |= 1 << 1; +// if (info.m_hasColorTex) +// ret |= 1 << 2; +// +// return ret; +//} +// +//template <> +//CFluidPlaneShader::ShaderPair +//CFluidPlaneShader::Cache::GetOrBuildShader(const SFluidPlaneShaderInfo& info) { +// OPTICK_EVENT(); +// u16 key = MakeCacheKey(info); +// auto& slot = CacheSlot(info, key); +// if (slot.m_regular) +// return slot; +// +// slot.m_regular = hecl::conv->convert(Shader_CFluidPlaneShader{info, false}); +// if (info.m_tessellation) +// slot.m_tessellation = hecl::conv->convert(Shader_CFluidPlaneShader{info, true}); +// +// return slot; +//} +//template <> +//CFluidPlaneShader::ShaderPair +//CFluidPlaneShader::Cache::GetOrBuildShader(const SFluidPlaneDoorShaderInfo& info) { +// OPTICK_EVENT(); +// u16 key = MakeCacheKey(info); +// auto& slot = CacheSlot(info, key); +// if (slot.m_regular) +// return slot; +// +// slot.m_regular = hecl::conv->convert(Shader_CFluidPlaneDoorShader{info}); +// +// return slot; +//} +// +//void CFluidPlaneShader::Cache::Clear() { +// for (auto& p : m_cache) +// p.reset(); +// for (auto& p : m_doorCache) +// p.reset(); +//} void CFluidPlaneShader::PrepareBinding(u32 maxVertCount) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount); - if (m_pipelines.m_tessellation) { - m_pvbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(PatchVertex), maxVertCount); - } - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 3> ubufs{{ - m_uniBuf.get(), - m_uniBuf.get(), - m_uniBuf.get(), - }}; - constexpr std::array ubufStages{ - boo::PipelineStage::Vertex, - boo::PipelineStage::Vertex, - boo::PipelineStage::Fragment, - }; - constexpr std::array ubufOffs{ - 0, - 0, - 1280, - }; - constexpr std::array ubufSizes{ - 1280, - 1280, - sizeof(CModelShaders::LightingUniform), - }; - - size_t texCount = 0; - std::array, 8> texs; - if (m_patternTex1) { - texs[texCount++] = m_patternTex1->GetBooTexture(); - } - if (m_patternTex2) { - texs[texCount++] = m_patternTex2->GetBooTexture(); - } - if (m_colorTex) { - texs[texCount++] = m_colorTex->GetBooTexture(); - } - if (m_bumpMap) { - texs[texCount++] = m_bumpMap->GetBooTexture(); - } - if (m_envMap) { - texs[texCount++] = m_envMap->GetBooTexture(); - } - if (m_envBumpMap) { - texs[texCount++] = m_envBumpMap->GetBooTexture(); - } - if (m_lightmap) { - texs[texCount++] = m_lightmap->GetBooTexture(); - } - auto regular = ctx.newShaderDataBinding(m_pipelines.m_regular, m_vbo.get(), nullptr, nullptr, ubufs.size(), - ubufs.data(), ubufStages.data(), ubufOffs.data(), ubufSizes.data(), - texCount, texs.data(), nullptr, nullptr); - boo::ObjToken tessellation; - if (m_pipelines.m_tessellation) { - texs[texCount++] = m_rippleMap.get(); - tessellation = ctx.newShaderDataBinding(m_pipelines.m_tessellation, m_pvbo.get(), nullptr, nullptr, ubufs.size(), - ubufs.data(), ubufStages.data(), ubufOffs.data(), ubufSizes.data(), - texCount, texs.data(), nullptr, nullptr); - } - m_dataBind = {regular, tessellation}; - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Vertex), maxVertCount); +// if (m_pipelines.m_tessellation) { +// m_pvbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(PatchVertex), maxVertCount); +// } +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 3> ubufs{{ +// m_uniBuf.get(), +// m_uniBuf.get(), +// m_uniBuf.get(), +// }}; +// constexpr std::array ubufStages{ +// boo::PipelineStage::Vertex, +// boo::PipelineStage::Vertex, +// boo::PipelineStage::Fragment, +// }; +// constexpr std::array ubufOffs{ +// 0, +// 0, +// 1280, +// }; +// constexpr std::array ubufSizes{ +// 1280, +// 1280, +// sizeof(CModelShaders::LightingUniform), +// }; +// +// size_t texCount = 0; +// std::array, 8> texs; +// if (m_patternTex1) { +// texs[texCount++] = m_patternTex1->GetBooTexture(); +// } +// if (m_patternTex2) { +// texs[texCount++] = m_patternTex2->GetBooTexture(); +// } +// if (m_colorTex) { +// texs[texCount++] = m_colorTex->GetBooTexture(); +// } +// if (m_bumpMap) { +// texs[texCount++] = m_bumpMap->GetBooTexture(); +// } +// if (m_envMap) { +// texs[texCount++] = m_envMap->GetBooTexture(); +// } +// if (m_envBumpMap) { +// texs[texCount++] = m_envBumpMap->GetBooTexture(); +// } +// if (m_lightmap) { +// texs[texCount++] = m_lightmap->GetBooTexture(); +// } +// auto regular = ctx.newShaderDataBinding(m_pipelines.m_regular, m_vbo.get(), nullptr, nullptr, ubufs.size(), +// ubufs.data(), ubufStages.data(), ubufOffs.data(), ubufSizes.data(), +// texCount, texs.data(), nullptr, nullptr); +// boo::ObjToken tessellation; +// if (m_pipelines.m_tessellation) { +// texs[texCount++] = m_rippleMap.get(); +// tessellation = ctx.newShaderDataBinding(m_pipelines.m_tessellation, m_pvbo.get(), nullptr, nullptr, ubufs.size(), +// ubufs.data(), ubufStages.data(), ubufOffs.data(), ubufSizes.data(), +// texCount, texs.data(), nullptr, nullptr); +// } +// m_dataBind = {regular, tessellation}; +// return true; +// } BooTrace); } -void CFluidPlaneShader::Shutdown() { _cache.Clear(); } +void CFluidPlaneShader::Shutdown() { +// _cache.Clear(); +} CFluidPlaneShader::CFluidPlaneShader(EFluidType type, const TLockedToken& patternTex1, const TLockedToken& patternTex2, const TLockedToken& colorTex, const TLockedToken& bumpMap, const TLockedToken& envMap, const TLockedToken& envBumpMap, const TLockedToken& lightmap, - const boo::ObjToken& rippleMap, bool doubleLightmapBlend, + CTexture& rippleMap, bool doubleLightmapBlend, bool additive, u32 maxVertCount) : m_patternTex1(patternTex1) , m_patternTex2(patternTex2) @@ -205,12 +207,13 @@ CFluidPlaneShader::CFluidPlaneShader(EFluidType type, const TLockedToken& patternTex1, : m_patternTex1(patternTex1), m_patternTex2(patternTex2), m_colorTex(colorTex) { SFluidPlaneDoorShaderInfo shaderInfo(m_patternTex1.HasReference(), m_patternTex2.HasReference(), m_colorTex.HasReference()); - m_pipelines = _cache.GetOrBuildShader(shaderInfo); +// m_pipelines = _cache.GetOrBuildShader(shaderInfo); PrepareBinding(maxVertCount); } void CFluidPlaneShader::prepareDraw(const RenderSetupInfo& info) { - Uniform& uni = *reinterpret_cast(m_uniBuf->map(sizeof(Uniform))); - uni.m_mv = CGraphics::g_GXModelView.toMatrix4f(); - uni.m_mvNorm = info.normMtx; - uni.m_proj = CGraphics::GetPerspectiveProjectionMatrix(true); - uni.m_texMtxs = info.texMtxs; - uni.m_lighting.ActivateLights(info.lights); - for (size_t i = 0; i < uni.m_lighting.colorRegs.size(); ++i) { - uni.m_lighting.colorRegs[i] = info.kColors[i]; - } - uni.m_lighting.mulColor = info.kColors[3]; - uni.m_lighting.fog = CGraphics::g_Fog; - uni.m_pad2.x() = info.indScale; - m_uniBuf->unmap(); +// Uniform& uni = *reinterpret_cast(m_uniBuf->map(sizeof(Uniform))); +// uni.m_mv = CGraphics::g_GXModelView.toMatrix4f(); +// uni.m_mvNorm = info.normMtx; +// uni.m_proj = CGraphics::GetPerspectiveProjectionMatrix(true); +// uni.m_texMtxs = info.texMtxs; +// uni.m_lighting.ActivateLights(info.lights); +// for (size_t i = 0; i < uni.m_lighting.colorRegs.size(); ++i) { +// uni.m_lighting.colorRegs[i] = info.kColors[i]; +// } +// uni.m_lighting.mulColor = info.kColors[3]; +// uni.m_lighting.fog = CGraphics::g_Fog; +// uni.m_pad2.x() = info.indScale; +// m_uniBuf->unmap(); } void CFluidPlaneShader::prepareDraw(const RenderSetupInfo& info, const zeus::CVector3f& waterCenter, const CRippleManager& rippleManager, const zeus::CColor& colorMul, float rippleNormResolution) { - Uniform& uni = *reinterpret_cast(m_uniBuf->map(sizeof(Uniform))); - uni.m_mv = CGraphics::g_GXModelView.toMatrix4f(); - uni.m_mvNorm = info.normMtx; - uni.m_proj = CGraphics::GetPerspectiveProjectionMatrix(true); - uni.m_texMtxs = info.texMtxs; - - size_t i = 0; - for (const CRipple& ripple : rippleManager.GetRipples()) { - assert(i < uni.m_ripple.size() && "Too many ripples"); - Ripple& rOut = uni.m_ripple[i++]; - if (ripple.GetTime() >= ripple.GetTimeFalloff()) { - rOut.center.zeroOut(); - rOut.params.zeroOut(); - continue; - } - zeus::CVector3f localPos = ripple.GetCenter() - waterCenter; - rOut.center.x() = float(localPos.x()); - rOut.center.y() = float(localPos.y()); - rOut.center.z() = ripple.GetTime() * ripple.GetOOTimeFalloff(); - rOut.center.w() = ripple.GetOODistanceFalloff(); - rOut.params.x() = ripple.GetAmplitude(); - rOut.params.y() = ripple.GetPhase(); - rOut.params.z() = - (1.f - ripple.GetTime() * ripple.GetOOTimeFalloff() * ripple.GetOOTimeFalloff()) * ripple.GetFrequency(); - } - uni.m_colorMul = colorMul; - uni.m_pad[0].x() = rippleNormResolution; - uni.m_lighting.ActivateLights(info.lights); - for (i = 0; i < uni.m_lighting.colorRegs.size(); ++i) { - uni.m_lighting.colorRegs[i] = info.kColors[i]; - } - uni.m_lighting.mulColor = info.kColors[3]; - uni.m_lighting.fog = CGraphics::g_Fog; - uni.m_pad2.x() = info.indScale; - m_uniBuf->unmap(); +// Uniform& uni = *reinterpret_cast(m_uniBuf->map(sizeof(Uniform))); +// uni.m_mv = CGraphics::g_GXModelView.toMatrix4f(); +// uni.m_mvNorm = info.normMtx; +// uni.m_proj = CGraphics::GetPerspectiveProjectionMatrix(true); +// uni.m_texMtxs = info.texMtxs; +// +// size_t i = 0; +// for (const CRipple& ripple : rippleManager.GetRipples()) { +// assert(i < uni.m_ripple.size() && "Too many ripples"); +// Ripple& rOut = uni.m_ripple[i++]; +// if (ripple.GetTime() >= ripple.GetTimeFalloff()) { +// rOut.center.zeroOut(); +// rOut.params.zeroOut(); +// continue; +// } +// zeus::CVector3f localPos = ripple.GetCenter() - waterCenter; +// rOut.center.x() = float(localPos.x()); +// rOut.center.y() = float(localPos.y()); +// rOut.center.z() = ripple.GetTime() * ripple.GetOOTimeFalloff(); +// rOut.center.w() = ripple.GetOODistanceFalloff(); +// rOut.params.x() = ripple.GetAmplitude(); +// rOut.params.y() = ripple.GetPhase(); +// rOut.params.z() = +// (1.f - ripple.GetTime() * ripple.GetOOTimeFalloff() * ripple.GetOOTimeFalloff()) * ripple.GetFrequency(); +// } +// uni.m_colorMul = colorMul; +// uni.m_pad[0].x() = rippleNormResolution; +// uni.m_lighting.ActivateLights(info.lights); +// for (i = 0; i < uni.m_lighting.colorRegs.size(); ++i) { +// uni.m_lighting.colorRegs[i] = info.kColors[i]; +// } +// uni.m_lighting.mulColor = info.kColors[3]; +// uni.m_lighting.fog = CGraphics::g_Fog; +// uni.m_pad2.x() = info.indScale; +// m_uniBuf->unmap(); } void CFluidPlaneShader::loadVerts(const std::vector& verts, const std::vector& pVerts) { - m_vbo->load(verts.data(), verts.size() * sizeof(Vertex)); - if (m_pvbo) - m_pvbo->load(pVerts.data(), pVerts.size() * sizeof(PatchVertex)); +// m_vbo->load(verts.data(), verts.size() * sizeof(Vertex)); +// if (m_pvbo) +// m_pvbo->load(pVerts.data(), pVerts.size() * sizeof(PatchVertex)); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp b/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp index 2b78d4cb8..b4cbf9c1b 100644 --- a/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp +++ b/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp @@ -10,7 +10,7 @@ #include "Shaders/shader_CFluidPlaneShader.hpp" -#include +//#include #include #include @@ -53,51 +53,51 @@ public: }; private: - struct ShaderPair { - boo::ObjToken m_regular; - boo::ObjToken m_tessellation; - void reset() { - m_regular.reset(); - m_tessellation.reset(); - } - }; +// struct ShaderPair { +// boo::ObjToken m_regular; +// boo::ObjToken m_tessellation; +// void reset() { +// m_regular.reset(); +// m_tessellation.reset(); +// } +// }; +// +// struct BindingPair { +// boo::ObjToken m_regular; +// boo::ObjToken m_tessellation; +// }; - struct BindingPair { - boo::ObjToken m_regular; - boo::ObjToken m_tessellation; - }; - - class Cache { - std::array m_cache{}; - std::array m_doorCache{}; - ShaderPair& CacheSlot(const SFluidPlaneShaderInfo& info, int i) { return m_cache[i]; } - ShaderPair& CacheSlot(const SFluidPlaneDoorShaderInfo& info, int i) { return m_doorCache[i]; } - static u16 MakeCacheKey(const SFluidPlaneShaderInfo& info); - static u16 MakeCacheKey(const SFluidPlaneDoorShaderInfo& info); - - public: - template - ShaderPair GetOrBuildShader(const T& info); - void Clear(); - }; - static Cache _cache; +// class Cache { +// std::array m_cache{}; +// std::array m_doorCache{}; +// ShaderPair& CacheSlot(const SFluidPlaneShaderInfo& info, int i) { return m_cache[i]; } +// ShaderPair& CacheSlot(const SFluidPlaneDoorShaderInfo& info, int i) { return m_doorCache[i]; } +// static u16 MakeCacheKey(const SFluidPlaneShaderInfo& info); +// static u16 MakeCacheKey(const SFluidPlaneDoorShaderInfo& info); +// +// public: +// template +// ShaderPair GetOrBuildShader(const T& info); +// void Clear(); +// }; +// static Cache _cache; struct Ripple { zeus::CVector4f center; // time, distFalloff zeus::CVector4f params; // amplitude, lookupPhase, lookupTime }; - struct Uniform { - zeus::CMatrix4f m_mv; - zeus::CMatrix4f m_mvNorm; - zeus::CMatrix4f m_proj; - std::array m_texMtxs; - std::array m_ripple; - zeus::CVector4f m_colorMul; - std::array m_pad; // rippleNormResolution, Pad out to 1280 bytes - CModelShaders::LightingUniform m_lighting; - zeus::CVector3f m_pad2; // Pad out to 768 bytes, also holds ind scale - }; +// struct Uniform { +// zeus::CMatrix4f m_mv; +// zeus::CMatrix4f m_mvNorm; +// zeus::CMatrix4f m_proj; +// std::array m_texMtxs; +// std::array m_ripple; +// zeus::CVector4f m_colorMul; +// std::array m_pad; // rippleNormResolution, Pad out to 1280 bytes +// CModelShaders::LightingUniform m_lighting; +// zeus::CVector3f m_pad2; // Pad out to 768 bytes, also holds ind scale +// }; TLockedToken m_patternTex1; TLockedToken m_patternTex2; @@ -106,34 +106,34 @@ private: TLockedToken m_envMap; TLockedToken m_envBumpMap; TLockedToken m_lightmap; - boo::ObjToken m_rippleMap; - boo::ObjToken m_vbo; - boo::ObjToken m_pvbo; - boo::ObjToken m_uniBuf; - ShaderPair m_pipelines; - BindingPair m_dataBind; +// aurora::gfx::TextureHandle m_rippleMap; +// boo::ObjToken m_vbo; +// boo::ObjToken m_pvbo; +// boo::ObjToken m_uniBuf; +// ShaderPair m_pipelines; +// BindingPair m_dataBind; int m_lastBind = -1; -#if BOO_HAS_GL - static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); - static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); - BindingPair BuildBinding(boo::GLDataFactory::Context& ctx, const ShaderPair& pipeline); -#endif -#if _WIN32 - static ShaderPair BuildShader(boo::D3D11DataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); - static ShaderPair BuildShader(boo::D3D11DataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); - BindingPair BuildBinding(boo::D3D11DataFactory::Context& ctx, const ShaderPair& pipeline); -#endif -#if BOO_HAS_METAL - static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); - static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); - BindingPair BuildBinding(boo::MetalDataFactory::Context& ctx, const ShaderPair& pipeline); -#endif -#if BOO_HAS_VULKAN - static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); - static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); - BindingPair BuildBinding(boo::VulkanDataFactory::Context& ctx, const ShaderPair& pipeline); -#endif +//#if BOO_HAS_GL +// static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); +// static ShaderPair BuildShader(boo::GLDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); +// BindingPair BuildBinding(boo::GLDataFactory::Context& ctx, const ShaderPair& pipeline); +//#endif +//#if _WIN32 +// static ShaderPair BuildShader(boo::D3D11DataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); +// static ShaderPair BuildShader(boo::D3D11DataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); +// BindingPair BuildBinding(boo::D3D11DataFactory::Context& ctx, const ShaderPair& pipeline); +//#endif +//#if BOO_HAS_METAL +// static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); +// static ShaderPair BuildShader(boo::MetalDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); +// BindingPair BuildBinding(boo::MetalDataFactory::Context& ctx, const ShaderPair& pipeline); +//#endif +//#if BOO_HAS_VULKAN +// static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneShaderInfo& info); +// static ShaderPair BuildShader(boo::VulkanDataFactory::Context& ctx, const SFluidPlaneDoorShaderInfo& info); +// BindingPair BuildBinding(boo::VulkanDataFactory::Context& ctx, const ShaderPair& pipeline); +//#endif template static void _Shutdown(); @@ -145,7 +145,7 @@ public: const TLockedToken& patternTex2, const TLockedToken& colorTex, const TLockedToken& bumpMap, const TLockedToken& envMap, const TLockedToken& envBumpMap, const TLockedToken& lightmap, - const boo::ObjToken& rippleMap, bool doubleLightmapBlend, bool additive, + CTexture& rippleMap, bool doubleLightmapBlend, bool additive, u32 maxVertCount); CFluidPlaneShader(const TLockedToken& patternTex1, const TLockedToken& patternTex2, const TLockedToken& colorTex, u32 maxVertCount); @@ -154,13 +154,13 @@ public: const zeus::CColor& colorMul, float rippleNormResolution); void bindRegular() { if (m_lastBind != 0) { - CGraphics::SetShaderDataBinding(m_dataBind.m_regular); +// CGraphics::SetShaderDataBinding(m_dataBind.m_regular); m_lastBind = 0; } } bool bindTessellation() { if (m_lastBind != 1) { - CGraphics::SetShaderDataBinding(m_dataBind.m_tessellation); +// CGraphics::SetShaderDataBinding(m_dataBind.m_tessellation); m_lastBind = 1; } return true; @@ -168,7 +168,8 @@ public: void doneDrawing() { m_lastBind = -1; } void loadVerts(const std::vector& verts, const std::vector& pVerts); bool isReady() const { - return m_pipelines.m_regular->isReady() && (!m_pipelines.m_tessellation || m_pipelines.m_tessellation->isReady()); +// return m_pipelines.m_regular->isReady() && (!m_pipelines.m_tessellation || m_pipelines.m_tessellation->isReady()); + return false; } static void Shutdown(); diff --git a/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp b/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp index 80e3033fe..925f397e5 100644 --- a/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp +++ b/Runtime/Graphics/Shaders/CFogVolumeFilter.cpp @@ -3,75 +3,75 @@ #include #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include -#include +//#include +//#include #include namespace metaforce { -static boo::ObjToken s_1WayPipeline; -static boo::ObjToken s_2WayPipeline; +//static boo::ObjToken s_1WayPipeline; +//static boo::ObjToken s_2WayPipeline; void CFogVolumeFilter::Initialize() { - s_1WayPipeline = hecl::conv->convert(Shader_CFogVolumeFilter1Way{}); - s_2WayPipeline = hecl::conv->convert(Shader_CFogVolumeFilter2Way{}); +// s_1WayPipeline = hecl::conv->convert(Shader_CFogVolumeFilter1Way{}); +// s_2WayPipeline = hecl::conv->convert(Shader_CFogVolumeFilter2Way{}); } void CFogVolumeFilter::Shutdown() { - s_1WayPipeline.reset(); - s_2WayPipeline.reset(); +// s_1WayPipeline.reset(); +// s_2WayPipeline.reset(); } CFogVolumeFilter::CFogVolumeFilter() { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - struct Vert { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - }; - constexpr std::array verts{{ - {{-1.0, -1.0}, {0.0, 0.0}}, - {{-1.0, 1.0}, {0.0, 1.0}}, - {{1.0, -1.0}, {1.0, 0.0}}, - {{1.0, 1.0}, {1.0, 1.0}}, - }}; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CColor), 1); - const std::array, 3> texs{ - CGraphics::g_SpareTexture.get(), - CGraphics::g_SpareTexture.get(), - g_Renderer->GetFogRampTex().get(), - }; - constexpr std::array bindIdxs{0, 1, 0}; - constexpr std::array bindDepth{true, true, false}; - const std::array, 1> ubufs{m_uniBuf.get()}; - - m_dataBind1Way = - ctx.newShaderDataBinding(s_1WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, - nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); - m_dataBind2Way = - ctx.newShaderDataBinding(s_2WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, - nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// struct Vert { +// zeus::CVector2f m_pos; +// zeus::CVector2f m_uv; +// }; +// constexpr std::array verts{{ +// {{-1.0, -1.0}, {0.0, 0.0}}, +// {{-1.0, 1.0}, {0.0, 1.0}}, +// {{1.0, -1.0}, {1.0, 0.0}}, +// {{1.0, 1.0}, {1.0, 1.0}}, +// }}; +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CColor), 1); +// const std::array, 3> texs{ +// CGraphics::g_SpareTexture.get(), +// CGraphics::g_SpareTexture.get(), +// g_Renderer->GetFogRampTex().get(), +// }; +// constexpr std::array bindIdxs{0, 1, 0}; +// constexpr std::array bindDepth{true, true, false}; +// const std::array, 1> ubufs{m_uniBuf.get()}; +// +// m_dataBind1Way = +// ctx.newShaderDataBinding(s_1WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, +// nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); +// m_dataBind2Way = +// ctx.newShaderDataBinding(s_2WayPipeline, m_vbo.get(), nullptr, nullptr, ubufs.size(), ubufs.data(), nullptr, +// nullptr, nullptr, texs.size(), texs.data(), bindIdxs.data(), bindDepth.data()); +// return true; +// } BooTrace); } void CFogVolumeFilter::draw2WayPass(const zeus::CColor& color) { SCOPED_GRAPHICS_DEBUG_GROUP("CFogVolumeFilter::draw2WayPass", zeus::skMagenta); - m_uniBuf->load(&color, sizeof(zeus::CColor)); - CGraphics::SetShaderDataBinding(m_dataBind2Way); - CGraphics::DrawArray(0, 4); +// m_uniBuf->load(&color, sizeof(zeus::CColor)); +// CGraphics::SetShaderDataBinding(m_dataBind2Way); +// CGraphics::DrawArray(0, 4); } void CFogVolumeFilter::draw1WayPass(const zeus::CColor& color) { SCOPED_GRAPHICS_DEBUG_GROUP("CFogVolumeFilter::draw1WayPass", zeus::skMagenta); - m_uniBuf->load(&color, sizeof(zeus::CColor)); - CGraphics::SetShaderDataBinding(m_dataBind1Way); - CGraphics::DrawArray(0, 4); +// m_uniBuf->load(&color, sizeof(zeus::CColor)); +// CGraphics::SetShaderDataBinding(m_dataBind1Way); +// CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp b/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp index bff2340db..ced382d90 100644 --- a/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp +++ b/Runtime/Graphics/Shaders/CFogVolumeFilter.hpp @@ -1,24 +1,16 @@ #pragma once -#include - -namespace boo { -struct IGraphicsBufferD; -struct IGraphicsBufferS; -struct IShaderDataBinding; -} // namespace boo - namespace zeus { class CColor; -} +} // namespace zeus namespace metaforce { class CFogVolumeFilter { - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind1Way; - boo::ObjToken m_dataBind2Way; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind1Way; +// boo::ObjToken m_dataBind2Way; public: static void Initialize(); diff --git a/Runtime/Graphics/Shaders/CFogVolumePlaneShader.cpp b/Runtime/Graphics/Shaders/CFogVolumePlaneShader.cpp index 29f44ff7e..63dde5d69 100644 --- a/Runtime/Graphics/Shaders/CFogVolumePlaneShader.cpp +++ b/Runtime/Graphics/Shaders/CFogVolumePlaneShader.cpp @@ -2,42 +2,42 @@ #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include namespace metaforce { -static std::array, 4> s_Pipelines; - -void CFogVolumePlaneShader::Initialize() { - s_Pipelines[0] = hecl::conv->convert(Shader_CFogVolumePlaneShader0{}); - s_Pipelines[1] = hecl::conv->convert(Shader_CFogVolumePlaneShader1{}); - s_Pipelines[2] = hecl::conv->convert(Shader_CFogVolumePlaneShader2{}); - s_Pipelines[3] = hecl::conv->convert(Shader_CFogVolumePlaneShader3{}); -} - -void CFogVolumePlaneShader::Shutdown() { - s_Pipelines[0].reset(); - s_Pipelines[1].reset(); - s_Pipelines[2].reset(); - s_Pipelines[3].reset(); -} - -void CFogVolumePlaneShader::CommitResources(size_t capacity) { - m_vertCapacity = capacity; - CGraphics::CommitResources([this, capacity](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(zeus::CVector4f), capacity); - for (size_t i = 0; i < m_dataBinds.size(); ++i) { - m_dataBinds[i] = ctx.newShaderDataBinding(s_Pipelines[i], m_vbo.get(), nullptr, nullptr, 0, nullptr, nullptr, - nullptr, nullptr, 0, nullptr, nullptr, nullptr); - } - return true; - } BooTrace); -} +//static std::array, 4> s_Pipelines; +// +//void CFogVolumePlaneShader::Initialize() { +// s_Pipelines[0] = hecl::conv->convert(Shader_CFogVolumePlaneShader0{}); +// s_Pipelines[1] = hecl::conv->convert(Shader_CFogVolumePlaneShader1{}); +// s_Pipelines[2] = hecl::conv->convert(Shader_CFogVolumePlaneShader2{}); +// s_Pipelines[3] = hecl::conv->convert(Shader_CFogVolumePlaneShader3{}); +//} +// +//void CFogVolumePlaneShader::Shutdown() { +// s_Pipelines[0].reset(); +// s_Pipelines[1].reset(); +// s_Pipelines[2].reset(); +// s_Pipelines[3].reset(); +//} +// +//void CFogVolumePlaneShader::CommitResources(size_t capacity) { +// m_vertCapacity = capacity; +// CGraphics::CommitResources([this, capacity](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(zeus::CVector4f), capacity); +// for (size_t i = 0; i < m_dataBinds.size(); ++i) { +// m_dataBinds[i] = ctx.newShaderDataBinding(s_Pipelines[i], m_vbo.get(), nullptr, nullptr, 0, nullptr, nullptr, +// nullptr, nullptr, 0, nullptr, nullptr, nullptr); +// } +// return true; +// } BooTrace); +//} void CFogVolumePlaneShader::addFan(const zeus::CVector3f* verts, int numVerts) { - zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(true); + zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(/*true*/); zeus::CVector4f vert0 = proj * zeus::CVector4f(CGraphics::g_GXModelView * verts[0]); - if (m_verts.size()) { + if (!m_verts.empty()) { m_verts.push_back(m_verts.back()); m_verts.push_back(vert0); if (m_verts.size() & 1) @@ -53,13 +53,13 @@ void CFogVolumePlaneShader::draw(int pass) { if (m_verts.empty()) return; SCOPED_GRAPHICS_DEBUG_GROUP("CFogVolumePlaneShader::draw", zeus::skMagenta); - if (pass == 0) { - if (m_vertCapacity < m_verts.size()) - CommitResources(m_verts.size()); - m_vbo->load(m_verts.data(), m_verts.size() * sizeof(zeus::CVector4f)); - } - CGraphics::SetShaderDataBinding(m_dataBinds[pass]); - CGraphics::DrawArray(0, m_verts.size()); +// if (pass == 0) { +// if (m_vertCapacity < m_verts.size()) +// CommitResources(m_verts.size()); +// m_vbo->load(m_verts.data(), m_verts.size() * sizeof(zeus::CVector4f)); +// } +// CGraphics::SetShaderDataBinding(m_dataBinds[pass]); +// CGraphics::DrawArray(0, m_verts.size()); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CFogVolumePlaneShader.hpp b/Runtime/Graphics/Shaders/CFogVolumePlaneShader.hpp index 10f7473b4..25376341b 100644 --- a/Runtime/Graphics/Shaders/CFogVolumePlaneShader.hpp +++ b/Runtime/Graphics/Shaders/CFogVolumePlaneShader.hpp @@ -4,28 +4,25 @@ #include #include -#include +//#include #include #include namespace zeus { class CVector3f; -} +} // namespace zeus namespace metaforce { class CFogVolumePlaneShader { - boo::ObjToken m_vbo; - std::array, 4> m_dataBinds; - std::vector m_verts; +// boo::ObjToken m_vbo; +// std::array, 4> m_dataBinds; size_t m_vertCapacity = 0; - - void CommitResources(size_t capacity); +public: + std::vector m_verts; public: - static void Initialize(); - static void Shutdown(); static const zeus::CRectangle DefaultRect; void reset(int numVerts) { m_verts.clear(); diff --git a/Runtime/Graphics/Shaders/CLineRendererShaders.cpp b/Runtime/Graphics/Shaders/CLineRendererShaders.cpp index 05b4c3dc8..01f699abb 100644 --- a/Runtime/Graphics/Shaders/CLineRendererShaders.cpp +++ b/Runtime/Graphics/Shaders/CLineRendererShaders.cpp @@ -4,113 +4,113 @@ #include "Runtime/Graphics/CLineRenderer.hpp" -#include +//#include namespace metaforce { void CLineRendererShaders::Initialize() { - CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx) { - m_texAlpha = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlpha{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlphaAWrite{})}; - m_texAdditive = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditive{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditiveAWrite{})}; - m_noTexAlpha = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlpha{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaAWrite{})}; - m_noTexAdditive = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditive{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditiveAWrite{})}; - m_texAlphaZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlphaZ{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlphaZAWrite{})}; - m_texAdditiveZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditiveZ{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditiveZAWrite{})}; - m_noTexAlphaZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZ{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZAWrite{})}; - m_noTexAdditiveZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditiveZ{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditiveZAWrite{})}; - m_noTexAlphaZGEqual = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZGEqual{}), - hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZGEqualAWrite{})}; - return true; - } BooTrace); +// CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx) { +// m_texAlpha = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlpha{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlphaAWrite{})}; +// m_texAdditive = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditive{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditiveAWrite{})}; +// m_noTexAlpha = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlpha{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaAWrite{})}; +// m_noTexAdditive = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditive{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditiveAWrite{})}; +// m_texAlphaZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlphaZ{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAlphaZAWrite{})}; +// m_texAdditiveZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditiveZ{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderTexAdditiveZAWrite{})}; +// m_noTexAlphaZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZ{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZAWrite{})}; +// m_noTexAdditiveZ = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditiveZ{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAdditiveZAWrite{})}; +// m_noTexAlphaZGEqual = {hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZGEqual{}), +// hecl::conv->convert(ctx, Shader_CLineRendererShaderNoTexAlphaZGEqualAWrite{})}; +// return true; +// } BooTrace); } void CLineRendererShaders::Shutdown() { - for (auto& s : m_texAlpha) - s.reset(); - for (auto& s : m_texAdditive) - s.reset(); - for (auto& s : m_noTexAlpha) - s.reset(); - for (auto& s : m_noTexAdditive) - s.reset(); - for (auto& s : m_texAlphaZ) - s.reset(); - for (auto& s : m_texAdditiveZ) - s.reset(); - for (auto& s : m_noTexAlphaZ) - s.reset(); - for (auto& s : m_noTexAdditiveZ) - s.reset(); - for (auto& s : m_noTexAlphaZGEqual) - s.reset(); +// for (auto& s : m_texAlpha) +// s.reset(); +// for (auto& s : m_texAdditive) +// s.reset(); +// for (auto& s : m_noTexAlpha) +// s.reset(); +// for (auto& s : m_noTexAdditive) +// s.reset(); +// for (auto& s : m_texAlphaZ) +// s.reset(); +// for (auto& s : m_texAdditiveZ) +// s.reset(); +// for (auto& s : m_noTexAlphaZ) +// s.reset(); +// for (auto& s : m_noTexAdditiveZ) +// s.reset(); +// for (auto& s : m_noTexAlphaZGEqual) +// s.reset(); } -void CLineRendererShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CLineRenderer& renderer, - const boo::ObjToken& texture, bool additive, +void CLineRendererShaders::BuildShaderDataBinding(CLineRenderer& renderer, + CTexture& texture, bool additive, bool zTest, bool zGEqual) { - std::array, 2>* pipeline = nullptr; - - if (zGEqual) { - pipeline = &m_noTexAlphaZGEqual; - } else if (zTest) { - if (texture) { - if (additive) - pipeline = &m_texAdditiveZ; - else - pipeline = &m_texAlphaZ; - } else { - if (additive) - pipeline = &m_noTexAdditiveZ; - else - pipeline = &m_noTexAlphaZ; - } - } else { - if (texture) { - if (additive) - pipeline = &m_texAdditive; - else - pipeline = &m_texAlpha; - } else { - if (additive) - pipeline = &m_noTexAdditive; - else - pipeline = &m_noTexAlpha; - } - } - - size_t texCount = 0; - std::array, 1> textures; - - std::pair, hecl::VertexBufferPool::IndexTp> - vbufInfo; - std::pair, hecl::UniformBufferPool::IndexTp> - ubufInfo = renderer.m_uniformBuf.getBufferInfo(); - if (texture) { - vbufInfo = renderer.m_vertBufTex.getBufferInfo(); - textures[0] = texture; - texCount = 1; - } else { - vbufInfo = renderer.m_vertBufNoTex.getBufferInfo(); - } - - const std::array, 1> uniforms{ubufInfo.first.get()}; - constexpr std::array stages{boo::PipelineStage::Fragment}; - const std::array ubufOffs{size_t(ubufInfo.second)}; - const std::array ubufSizes{sizeof(CLineRenderer::SDrawUniform)}; - - for (size_t i = 0; i < renderer.m_shaderBind.size(); ++i) { - renderer.m_shaderBind[i] = ctx.newShaderDataBinding( - (*pipeline)[i], vbufInfo.first.get(), nullptr, nullptr, uniforms.size(), uniforms.data(), stages.data(), - ubufOffs.data(), ubufSizes.data(), texCount, textures.data(), nullptr, nullptr, vbufInfo.second); - } +// std::array, 2>* pipeline = nullptr; +// +// if (zGEqual) { +// pipeline = &m_noTexAlphaZGEqual; +// } else if (zTest) { +// if (texture) { +// if (additive) +// pipeline = &m_texAdditiveZ; +// else +// pipeline = &m_texAlphaZ; +// } else { +// if (additive) +// pipeline = &m_noTexAdditiveZ; +// else +// pipeline = &m_noTexAlphaZ; +// } +// } else { +// if (texture) { +// if (additive) +// pipeline = &m_texAdditive; +// else +// pipeline = &m_texAlpha; +// } else { +// if (additive) +// pipeline = &m_noTexAdditive; +// else +// pipeline = &m_noTexAlpha; +// } +// } +// +// size_t texCount = 0; +// std::array, 1> textures; +// +// std::pair, hecl::VertexBufferPool::IndexTp> +// vbufInfo; +// std::pair, hecl::UniformBufferPool::IndexTp> +// ubufInfo = renderer.m_uniformBuf.getBufferInfo(); +// if (texture) { +// vbufInfo = renderer.m_vertBufTex.getBufferInfo(); +// textures[0] = texture; +// texCount = 1; +// } else { +// vbufInfo = renderer.m_vertBufNoTex.getBufferInfo(); +// } +// +// const std::array, 1> uniforms{ubufInfo.first.get()}; +// constexpr std::array stages{boo::PipelineStage::Fragment}; +// const std::array ubufOffs{size_t(ubufInfo.second)}; +// const std::array ubufSizes{sizeof(CLineRenderer::SDrawUniform)}; +// +// for (size_t i = 0; i < renderer.m_shaderBind.size(); ++i) { +// renderer.m_shaderBind[i] = ctx.newShaderDataBinding( +// (*pipeline)[i], vbufInfo.first.get(), nullptr, nullptr, uniforms.size(), uniforms.data(), stages.data(), +// ubufOffs.data(), ubufSizes.data(), texCount, textures.data(), nullptr, nullptr, vbufInfo.second); +// } } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CLineRendererShaders.hpp b/Runtime/Graphics/Shaders/CLineRendererShaders.hpp index e0d44169d..758e15e97 100644 --- a/Runtime/Graphics/Shaders/CLineRendererShaders.hpp +++ b/Runtime/Graphics/Shaders/CLineRendererShaders.hpp @@ -2,31 +2,31 @@ #include -#include +#include "Runtime/Graphics/CGraphics.hpp" namespace metaforce { class CLineRenderer; class CLineRendererShaders { - static inline std::array, 2> m_texAlpha; - static inline std::array, 2> m_texAdditive; - - static inline std::array, 2> m_noTexAlpha; - static inline std::array, 2> m_noTexAdditive; - - static inline std::array, 2> m_texAlphaZ; - static inline std::array, 2> m_texAdditiveZ; - - static inline std::array, 2> m_noTexAlphaZ; - static inline std::array, 2> m_noTexAdditiveZ; - - static inline std::array, 2> m_noTexAlphaZGEqual; +// static inline std::array, 2> m_texAlpha; +// static inline std::array, 2> m_texAdditive; +// +// static inline std::array, 2> m_noTexAlpha; +// static inline std::array, 2> m_noTexAdditive; +// +// static inline std::array, 2> m_texAlphaZ; +// static inline std::array, 2> m_texAdditiveZ; +// +// static inline std::array, 2> m_noTexAlphaZ; +// static inline std::array, 2> m_noTexAdditiveZ; +// +// static inline std::array, 2> m_noTexAlphaZGEqual; public: static void Initialize(); static void Shutdown(); - static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CLineRenderer& renderer, - const boo::ObjToken& texture, bool additive, bool zTest, + static void BuildShaderDataBinding(CLineRenderer& renderer, + CTexture& texture, bool additive, bool zTest, bool zGEqual); }; diff --git a/Runtime/Graphics/Shaders/CMapSurfaceShader.cpp b/Runtime/Graphics/Shaders/CMapSurfaceShader.cpp index 5ad827ba4..3d43a79ca 100644 --- a/Runtime/Graphics/Shaders/CMapSurfaceShader.cpp +++ b/Runtime/Graphics/Shaders/CMapSurfaceShader.cpp @@ -4,33 +4,37 @@ #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_Pipeline; -void CMapSurfaceShader::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CMapSurfaceShader{}); } +void CMapSurfaceShader::Initialize() { +// s_Pipeline = hecl::conv->convert(Shader_CMapSurfaceShader{}); +} -void CMapSurfaceShader::Shutdown() { s_Pipeline.reset(); } +void CMapSurfaceShader::Shutdown() { +// s_Pipeline.reset(); +} -CMapSurfaceShader::CMapSurfaceShader(boo::IGraphicsDataFactory::Context& ctx, - const boo::ObjToken& vbo, - const boo::ObjToken& ibo) -: m_vbo(vbo), m_ibo(ibo) { - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, m_ibo.get(), bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); +CMapSurfaceShader::CMapSurfaceShader(std::vector vbo, + std::vector ibo) +//: m_vbo(vbo), m_ibo(ibo) +{ +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, m_ibo.get(), bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); } void CMapSurfaceShader::draw(const zeus::CColor& color, u32 start, u32 count) { SCOPED_GRAPHICS_DEBUG_GROUP("CMapSurfaceShader::draw", zeus::skMagenta); - Uniform uniform = {CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(), color}; - m_uniBuf->load(&uniform, sizeof(Uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArrayIndexed(start, count); + Uniform uniform = {CGraphics::GetPerspectiveProjectionMatrix(/*true*/) * CGraphics::g_GXModelView.toMatrix4f(), color}; +// m_uniBuf->load(&uniform, sizeof(Uniform)); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArrayIndexed(start, count); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CMapSurfaceShader.hpp b/Runtime/Graphics/Shaders/CMapSurfaceShader.hpp index b3504c15d..bb77cabaf 100644 --- a/Runtime/Graphics/Shaders/CMapSurfaceShader.hpp +++ b/Runtime/Graphics/Shaders/CMapSurfaceShader.hpp @@ -1,8 +1,7 @@ #pragma once #include "Runtime/GCNTypes.hpp" - -#include +#include "Runtime/Graphics/CGraphics.hpp" #include #include @@ -15,16 +14,16 @@ class CMapSurfaceShader { zeus::CColor color; }; - boo::ObjToken m_uniBuf; - boo::ObjToken m_vbo; - boo::ObjToken m_ibo; - boo::ObjToken m_dataBind; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_vbo; +// boo::ObjToken m_ibo; +// boo::ObjToken m_dataBind; public: static void Initialize(); static void Shutdown(); - CMapSurfaceShader(boo::IGraphicsDataFactory::Context& ctx, const boo::ObjToken& vbo, - const boo::ObjToken& ibo); + CMapSurfaceShader(std::vector vbo, + std::vector ibo); void draw(const zeus::CColor& color, u32 start, u32 count); }; diff --git a/Runtime/Graphics/Shaders/CModelShaders.cpp b/Runtime/Graphics/Shaders/CModelShaders.cpp index f2dd04f2f..192043249 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.cpp +++ b/Runtime/Graphics/Shaders/CModelShaders.cpp @@ -3,231 +3,233 @@ #include "Runtime/CStopwatch.hpp" #include "Runtime/Graphics/CLight.hpp" -#include -#include +//#include +//#include namespace metaforce { -std::unordered_map CModelShaders::g_ShaderPipelines; +//std::unordered_map CModelShaders::g_ShaderPipelines; -void CModelShaders::LightingUniform::ActivateLights(const std::vector& lts) { - ambient = zeus::skClear; - size_t curLight = 0; +//void CModelShaders::LightingUniform::ActivateLights(const std::vector& lts) { +// ambient = zeus::skClear; +// size_t curLight = 0; +// +// for (const CLight& light : lts) { +// switch (light.GetType()) { +// case ELightType::LocalAmbient: +// ambient += light.GetColor(); +// break; +// case ELightType::Point: +// case ELightType::Spot: +// case ELightType::Custom: +// case ELightType::Directional: { +// if (curLight >= lights.size()) { +// continue; +// } +// CModelShaders::Light& lightOut = lights[curLight++]; +// lightOut.pos = CGraphics::g_CameraMatrix * light.GetPosition(); +// lightOut.dir = CGraphics::g_CameraMatrix.basis * light.GetDirection(); +// lightOut.dir.normalize(); +// lightOut.color = light.GetColor(); +// lightOut.linAtt[0] = light.GetAttenuationConstant(); +// lightOut.linAtt[1] = light.GetAttenuationLinear(); +// lightOut.linAtt[2] = light.GetAttenuationQuadratic(); +// lightOut.angAtt[0] = light.GetAngleAttenuationConstant(); +// lightOut.angAtt[1] = light.GetAngleAttenuationLinear(); +// lightOut.angAtt[2] = light.GetAngleAttenuationQuadratic(); +// +// if (light.GetType() == ELightType::Directional) +// lightOut.pos = (-lightOut.dir) * 1048576.f; +// break; +// } +// } +// } +// +// for (; curLight < lights.size(); ++curLight) { +// CModelShaders::Light& lightOut = lights[curLight]; +// lightOut.pos = zeus::skZero3f; +// lightOut.dir = zeus::skDown; +// lightOut.color = zeus::skClear; +// lightOut.linAtt[0] = 1.f; +// lightOut.linAtt[1] = 0.f; +// lightOut.linAtt[2] = 0.f; +// lightOut.angAtt[0] = 1.f; +// lightOut.angAtt[1] = 0.f; +// lightOut.angAtt[2] = 0.f; +// } +//} - for (const CLight& light : lts) { - switch (light.GetType()) { - case ELightType::LocalAmbient: - ambient += light.GetColor(); - break; - case ELightType::Point: - case ELightType::Spot: - case ELightType::Custom: - case ELightType::Directional: { - if (curLight >= lights.size()) { - continue; - } - CModelShaders::Light& lightOut = lights[curLight++]; - lightOut.pos = CGraphics::g_CameraMatrix * light.GetPosition(); - lightOut.dir = CGraphics::g_CameraMatrix.basis * light.GetDirection(); - lightOut.dir.normalize(); - lightOut.color = light.GetColor(); - lightOut.linAtt[0] = light.GetAttenuationConstant(); - lightOut.linAtt[1] = light.GetAttenuationLinear(); - lightOut.linAtt[2] = light.GetAttenuationQuadratic(); - lightOut.angAtt[0] = light.GetAngleAttenuationConstant(); - lightOut.angAtt[1] = light.GetAngleAttenuationLinear(); - lightOut.angAtt[2] = light.GetAngleAttenuationQuadratic(); +//using TexCoordSource = hecl::Backend::TexCoordSource; +// +//constexpr std::array ThermalTextures{{ +// {TexCoordSource::Normal, 7, true}, +//}}; +// +//constexpr std::array BallFadeTextures{{ +// {TexCoordSource::Position, 0, false}, // ID tex +// {TexCoordSource::Position, 0, false}, // Sphere ramp +// {TexCoordSource::Position, 1, false}, // TXTR_BallFade +//}}; +// +//constexpr std::array WorldShadowTextures{{ +// {TexCoordSource::Position, 7, false}, // Shadow tex +//}}; +// +//constexpr std::array DisintegrateTextures{{ +// {TexCoordSource::Position, 0, false}, // Ashy tex +// {TexCoordSource::Position, 1, false}, // Ashy tex +//}}; - if (light.GetType() == ELightType::Directional) - lightOut.pos = (-lightOut.dir) * 1048576.f; - break; - } - } - } +//static std::array g_ExtensionSlots{{ +// /* Default solid shading */ +// {}, +// /* Normal lit shading */ +// {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, +// /* Thermal model shading */ +// {1, ThermalTextures.data(), hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, false, true}, +// /* Thermal model shading without Z-test or Z-write */ +// {1, ThermalTextures.data(), hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One, +// hecl::Backend::ZTest::None, hecl::Backend::CullMode::Backface, true, false, false, true}, +// /* Thermal static shading */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, +// hecl::Backend::CullMode::Backface, false, false, false, true, false, false, true}, +// /* Thermal static shading without Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, +// hecl::Backend::CullMode::Backface, true, false, false, true, false, false, false}, +// /* Forced alpha shading */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, +// /* Forced additive shading */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, +// hecl::Backend::CullMode::Backface, false, false, true}, +// /* Solid color */ +// {0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero, hecl::Backend::ZTest::LEqual, +// hecl::Backend::CullMode::Backface, false, false, false}, +// /* Solid color additive */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual, +// hecl::Backend::CullMode::Backface, true, false, true}, +// /* Alpha-only Solid color frontface cull, LEqual */ +// {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual, +// hecl::Backend::CullMode::Frontface, false, true, false}, +// /* Alpha-only Solid color frontface cull, Always, No Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::None, +// hecl::Backend::CullMode::Frontface, true, true, false}, +// /* Alpha-only Solid color backface cull, LEqual */ +// {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual, +// hecl::Backend::CullMode::Backface, false, true, false}, +// /* Alpha-only Solid color backface cull, Greater, No Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Greater, +// hecl::Backend::CullMode::Backface, true, true, false}, +// /* MorphBall shadow shading */ +// {3, BallFadeTextures.data(), hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, +// hecl::Backend::ZTest::Equal, hecl::Backend::CullMode::Backface, false, false, true, false, true}, +// /* World shadow shading (modified lighting) */ +// {1, WorldShadowTextures.data(), hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, +// /* Forced alpha shading without culling */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true}, +// /* Forced additive shading without culling */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, +// hecl::Backend::CullMode::None, false, false, true}, +// /* Forced alpha shading without Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true}, +// /* Forced additive shading without Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, +// hecl::Backend::CullMode::Original, true, false, true}, +// /* Forced alpha shading without culling or Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true}, +// /* Forced additive shading without culling or Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, +// hecl::Backend::CullMode::None, true, false, true}, +// /* Depth GEqual no Z-write */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, +// hecl::Backend::ZTest::GEqual, hecl::Backend::CullMode::Backface, true, false, true}, +// /* Disintegration */ +// {2, DisintegrateTextures.data(), hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, +// hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false, false, true, false, false, true}, +// /* Forced additive shading without culling or Z-write and greater depth test */ +// {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Greater, +// hecl::Backend::CullMode::None, true, false, true}, +// /* Thermal cold shading */ +// {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, false, false, true, false, false, false, true}, +// /* Normal lit shading with alpha */ +// {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface}, +// /* Normal lit shading with alpha without Z-write or depth test */ +// {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, hecl::Backend::ZTest::None, +// hecl::Backend::CullMode::Backface, true}, +// /* Normal lit shading with cube reflection */ +// {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, +// /* Normal lit shading with cube reflection and world shadow */ +// {1, WorldShadowTextures.data(), hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, +// hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, +//}}; - for (; curLight < lights.size(); ++curLight) { - CModelShaders::Light& lightOut = lights[curLight]; - lightOut.pos = zeus::skZero3f; - lightOut.dir = zeus::skDown; - lightOut.color = zeus::skClear; - lightOut.linAtt[0] = 1.f; - lightOut.linAtt[1] = 0.f; - lightOut.linAtt[2] = 0.f; - lightOut.angAtt[0] = 1.f; - lightOut.angAtt[1] = 0.f; - lightOut.angAtt[2] = 0.f; - } -} - -using TexCoordSource = hecl::Backend::TexCoordSource; - -constexpr std::array ThermalTextures{{ - {TexCoordSource::Normal, 7, true}, -}}; - -constexpr std::array BallFadeTextures{{ - {TexCoordSource::Position, 0, false}, // ID tex - {TexCoordSource::Position, 0, false}, // Sphere ramp - {TexCoordSource::Position, 1, false}, // TXTR_BallFade -}}; - -constexpr std::array WorldShadowTextures{{ - {TexCoordSource::Position, 7, false}, // Shadow tex -}}; - -constexpr std::array DisintegrateTextures{{ - {TexCoordSource::Position, 0, false}, // Ashy tex - {TexCoordSource::Position, 1, false}, // Ashy tex -}}; - -static std::array g_ExtensionSlots{{ - /* Default solid shading */ - {}, - /* Normal lit shading */ - {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, - /* Thermal model shading */ - {1, ThermalTextures.data(), hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, false, true}, - /* Thermal model shading without Z-test or Z-write */ - {1, ThermalTextures.data(), hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::One, - hecl::Backend::ZTest::None, hecl::Backend::CullMode::Backface, true, false, false, true}, - /* Thermal static shading */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, - hecl::Backend::CullMode::Backface, false, false, false, true, false, false, true}, - /* Thermal static shading without Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, - hecl::Backend::CullMode::Backface, true, false, false, true, false, false, false}, - /* Forced alpha shading */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, - /* Forced additive shading */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, - hecl::Backend::CullMode::Backface, false, false, true}, - /* Solid color */ - {0, nullptr, hecl::Backend::BlendFactor::One, hecl::Backend::BlendFactor::Zero, hecl::Backend::ZTest::LEqual, - hecl::Backend::CullMode::Backface, false, false, false}, - /* Solid color additive */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual, - hecl::Backend::CullMode::Backface, true, false, true}, - /* Alpha-only Solid color frontface cull, LEqual */ - {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual, - hecl::Backend::CullMode::Frontface, false, true, false}, - /* Alpha-only Solid color frontface cull, Always, No Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::None, - hecl::Backend::CullMode::Frontface, true, true, false}, - /* Alpha-only Solid color backface cull, LEqual */ - {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::LEqual, - hecl::Backend::CullMode::Backface, false, true, false}, - /* Alpha-only Solid color backface cull, Greater, No Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::Zero, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Greater, - hecl::Backend::CullMode::Backface, true, true, false}, - /* MorphBall shadow shading */ - {3, BallFadeTextures.data(), hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, - hecl::Backend::ZTest::Equal, hecl::Backend::CullMode::Backface, false, false, true, false, true}, - /* World shadow shading (modified lighting) */ - {1, WorldShadowTextures.data(), hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, - /* Forced alpha shading without culling */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, false, false, true}, - /* Forced additive shading without culling */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, - hecl::Backend::CullMode::None, false, false, true}, - /* Forced alpha shading without Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, true, false, true}, - /* Forced additive shading without Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, - hecl::Backend::CullMode::Original, true, false, true}, - /* Forced alpha shading without culling or Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::None, true, false, true}, - /* Forced additive shading without culling or Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Original, - hecl::Backend::CullMode::None, true, false, true}, - /* Depth GEqual no Z-write */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, - hecl::Backend::ZTest::GEqual, hecl::Backend::CullMode::Backface, true, false, true}, - /* Disintegration */ - {2, DisintegrateTextures.data(), hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::InvSrcAlpha, - hecl::Backend::ZTest::LEqual, hecl::Backend::CullMode::Original, false, false, true, false, false, true}, - /* Forced additive shading without culling or Z-write and greater depth test */ - {0, nullptr, hecl::Backend::BlendFactor::SrcAlpha, hecl::Backend::BlendFactor::One, hecl::Backend::ZTest::Greater, - hecl::Backend::CullMode::None, true, false, true}, - /* Thermal cold shading */ - {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Original, false, false, true, false, false, false, true}, - /* Normal lit shading with alpha */ - {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface}, - /* Normal lit shading with alpha without Z-write or depth test */ - {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, hecl::Backend::ZTest::None, - hecl::Backend::CullMode::Backface, true}, - /* Normal lit shading with cube reflection */ - {0, nullptr, hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, - /* Normal lit shading with cube reflection and world shadow */ - {1, WorldShadowTextures.data(), hecl::Backend::BlendFactor::Original, hecl::Backend::BlendFactor::Original, - hecl::Backend::ZTest::Original, hecl::Backend::CullMode::Backface, false, false, true}, -}}; - -constexpr std::array ShaderMacros{ - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_THERMAL_MODEL", - "URDE_THERMAL_MODEL", - "URDE_THERMAL_STATIC", - "URDE_THERMAL_STATIC", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_SOLID", - "URDE_SOLID", - "URDE_SOLID", - "URDE_SOLID", - "URDE_SOLID", - "URDE_SOLID", - "URDE_MB_SHADOW", - "URDE_LIGHTING_SHADOW", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_DISINTEGRATE", - "URDE_LIGHTING", - "URDE_THERMAL_COLD", - "URDE_LIGHTING", - "URDE_LIGHTING", - "URDE_LIGHTING_CUBE_REFLECTION", - "URDE_LIGHTING_CUBE_REFLECTION_SHADOW", -}; +//constexpr std::array ShaderMacros{ +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_THERMAL_MODEL", +// "URDE_THERMAL_MODEL", +// "URDE_THERMAL_STATIC", +// "URDE_THERMAL_STATIC", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_SOLID", +// "URDE_SOLID", +// "URDE_SOLID", +// "URDE_SOLID", +// "URDE_SOLID", +// "URDE_SOLID", +// "URDE_MB_SHADOW", +// "URDE_LIGHTING_SHADOW", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_DISINTEGRATE", +// "URDE_LIGHTING", +// "URDE_THERMAL_COLD", +// "URDE_LIGHTING", +// "URDE_LIGHTING", +// "URDE_LIGHTING_CUBE_REFLECTION", +// "URDE_LIGHTING_CUBE_REFLECTION_SHADOW", +//}; void CModelShaders::Initialize() { - for (size_t i = 0; i < g_ExtensionSlots.size(); i++) { - g_ExtensionSlots[i].shaderMacro = ShaderMacros[i]; - } +// for (size_t i = 0; i < g_ExtensionSlots.size(); i++) { +// g_ExtensionSlots[i].shaderMacro = ShaderMacros[i]; +// } } -void CModelShaders::Shutdown() { g_ShaderPipelines.clear(); } - -CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Backend::ShaderTag& tag, - const Material& material) { - auto search = g_ShaderPipelines.find(tag.val64()); - if (search != g_ShaderPipelines.cend()) - return search->second; - - ShaderPipelines& newPipelines = g_ShaderPipelines[tag.val64()]; - newPipelines = std::make_shared(); - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - size_t idx = 0; - for (const auto& ext : g_ExtensionSlots) - (*newPipelines)[idx++] = hecl::conv->convert(ctx, Shader_CModelShaders(SModelShadersInfo(material, tag, ext))); - return true; - } BooTrace); - return newPipelines; +void CModelShaders::Shutdown() { +// g_ShaderPipelines.clear(); } +//CModelShaders::ShaderPipelines CModelShaders::BuildExtendedShader(const hecl::Backend::ShaderTag& tag, +// const Material& material) { +// auto search = g_ShaderPipelines.find(tag.val64()); +// if (search != g_ShaderPipelines.cend()) +// return search->second; +// +// ShaderPipelines& newPipelines = g_ShaderPipelines[tag.val64()]; +// newPipelines = std::make_shared(); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// size_t idx = 0; +// for (const auto& ext : g_ExtensionSlots) +// (*newPipelines)[idx++] = hecl::conv->convert(ctx, Shader_CModelShaders(SModelShadersInfo(material, tag, ext))); +// return true; +// } BooTrace); +// return newPipelines; +//} + } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CModelShaders.hpp b/Runtime/Graphics/Shaders/CModelShaders.hpp index 34f447b5f..190edfe3d 100644 --- a/Runtime/Graphics/Shaders/CModelShaders.hpp +++ b/Runtime/Graphics/Shaders/CModelShaders.hpp @@ -4,7 +4,7 @@ #include #include -#include "DataSpec/DNAMP1/CMDLMaterials.hpp" +//#include "DataSpec/DNAMP1/CMDLMaterials.hpp" #include "Runtime/Graphics/CGraphics.hpp" @@ -59,55 +59,55 @@ class CModelShaders { friend class CModel; public: - struct Light { - zeus::CVector3f pos; - zeus::CVector3f dir; - zeus::CColor color = zeus::skClear; - std::array linAtt{1.f, 0.f, 0.f}; - std::array angAtt{1.f, 0.f, 0.f}; - }; - - struct LightingUniform { - std::array lights; - zeus::CColor ambient; - std::array colorRegs; - zeus::CColor mulColor; - zeus::CColor addColor; - CGraphics::CFogState fog; - - void ActivateLights(const std::vector& lts); - }; - - struct ThermalUniform { - zeus::CColor mulColor; - zeus::CColor addColor; - }; - - struct SolidUniform { - zeus::CColor solidColor; - }; - - struct MBShadowUniform { - zeus::CVector4f shadowUp; - float shadowId; - }; - - struct OneTextureUniform { - zeus::CColor addColor; - CGraphics::CFogState fog; - }; +// struct Light { +// zeus::CVector3f pos; +// zeus::CVector3f dir; +// zeus::CColor color = zeus::skClear; +// std::array linAtt{1.f, 0.f, 0.f}; +// std::array angAtt{1.f, 0.f, 0.f}; +// }; +// +// struct LightingUniform { +// std::array lights; +// zeus::CColor ambient; +// std::array colorRegs; +// zeus::CColor mulColor; +// zeus::CColor addColor; +// CFogState fog; +// +// void ActivateLights(const std::vector& lts); +// }; +// +// struct ThermalUniform { +// zeus::CColor mulColor; +// zeus::CColor addColor; +// }; +// +// struct SolidUniform { +// zeus::CColor solidColor; +// }; +// +// struct MBShadowUniform { +// zeus::CVector4f shadowUp; +// float shadowId; +// }; +// +// struct OneTextureUniform { +// zeus::CColor addColor; +// CFogState fog; +// }; static void Initialize(); static void Shutdown(); - using ShaderPipelinesData = std::array, size_t(EExtendedShader::MAX)>; - using ShaderPipelines = std::shared_ptr; +// using ShaderPipelinesData = std::array, size_t(EExtendedShader::MAX)>; +// using ShaderPipelines = std::shared_ptr; - using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material; - static ShaderPipelines BuildExtendedShader(const hecl::Backend::ShaderTag& tag, const Material& material); +// using Material = DataSpec::DNAMP1::HMDLMaterialSet::Material; +// static ShaderPipelines BuildExtendedShader(const hecl::Backend::ShaderTag& tag, const Material& material); private: - static std::unordered_map g_ShaderPipelines; +// static std::unordered_map g_ShaderPipelines; }; } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp b/Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp index e33e3d7a1..ebc3fc54b 100644 --- a/Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp +++ b/Runtime/Graphics/Shaders/CParticleSwooshShaders.cpp @@ -5,56 +5,56 @@ #include "Runtime/Particle/CParticleSwoosh.hpp" #include "Runtime/Particle/CSwooshDescription.hpp" -#include +//#include namespace metaforce { -std::array, 2> CParticleSwooshShaders::m_texZWrite; -std::array, 2> CParticleSwooshShaders::m_texNoZWrite; -std::array, 2> CParticleSwooshShaders::m_texAdditiveZWrite; -std::array, 2> CParticleSwooshShaders::m_texAdditiveNoZWrite; - -std::array, 2> CParticleSwooshShaders::m_noTexZWrite; -std::array, 2> CParticleSwooshShaders::m_noTexNoZWrite; -std::array, 2> CParticleSwooshShaders::m_noTexAdditiveZWrite; -std::array, 2> CParticleSwooshShaders::m_noTexAdditiveNoZWrite; +//std::array, 2> CParticleSwooshShaders::m_texZWrite; +//std::array, 2> CParticleSwooshShaders::m_texNoZWrite; +//std::array, 2> CParticleSwooshShaders::m_texAdditiveZWrite; +//std::array, 2> CParticleSwooshShaders::m_texAdditiveNoZWrite; +// +//std::array, 2> CParticleSwooshShaders::m_noTexZWrite; +//std::array, 2> CParticleSwooshShaders::m_noTexNoZWrite; +//std::array, 2> CParticleSwooshShaders::m_noTexAdditiveZWrite; +//std::array, 2> CParticleSwooshShaders::m_noTexAdditiveNoZWrite; void CParticleSwooshShaders::Initialize() { - m_texZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderTexZWriteAWrite{})}; - m_texNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexNoZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderTexNoZWriteAWrite{})}; - m_texAdditiveZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveZWriteAWrite{})}; - m_texAdditiveNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveNoZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveNoZWriteAWrite{})}; - m_noTexZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderNoTexZWriteAWrite{})}; - m_noTexNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexNoZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderNoTexNoZWriteAWrite{})}; - m_noTexAdditiveZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveZWriteAWrite{})}; - m_noTexAdditiveNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveNoZWrite{}), - hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveNoZWriteAWrite{})}; +// m_texZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderTexZWriteAWrite{})}; +// m_texNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexNoZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderTexNoZWriteAWrite{})}; +// m_texAdditiveZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveZWriteAWrite{})}; +// m_texAdditiveNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveNoZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderTexAdditiveNoZWriteAWrite{})}; +// m_noTexZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderNoTexZWriteAWrite{})}; +// m_noTexNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexNoZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderNoTexNoZWriteAWrite{})}; +// m_noTexAdditiveZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveZWriteAWrite{})}; +// m_noTexAdditiveNoZWrite = {hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveNoZWrite{}), +// hecl::conv->convert(Shader_CParticleSwooshShaderNoTexAdditiveNoZWriteAWrite{})}; } void CParticleSwooshShaders::Shutdown() { - for (auto& s : m_texZWrite) - s.reset(); - for (auto& s : m_texNoZWrite) - s.reset(); - for (auto& s : m_texAdditiveZWrite) - s.reset(); - for (auto& s : m_texAdditiveNoZWrite) - s.reset(); - for (auto& s : m_noTexZWrite) - s.reset(); - for (auto& s : m_noTexNoZWrite) - s.reset(); - for (auto& s : m_noTexAdditiveZWrite) - s.reset(); - for (auto& s : m_noTexAdditiveNoZWrite) - s.reset(); +// for (auto& s : m_texZWrite) +// s.reset(); +// for (auto& s : m_texNoZWrite) +// s.reset(); +// for (auto& s : m_texAdditiveZWrite) +// s.reset(); +// for (auto& s : m_texAdditiveNoZWrite) +// s.reset(); +// for (auto& s : m_noTexZWrite) +// s.reset(); +// for (auto& s : m_noTexNoZWrite) +// s.reset(); +// for (auto& s : m_noTexAdditiveZWrite) +// s.reset(); +// for (auto& s : m_noTexAdditiveNoZWrite) +// s.reset(); } CParticleSwooshShaders::EShaderClass CParticleSwooshShaders::GetShaderClass(CParticleSwoosh& gen) { @@ -66,47 +66,47 @@ CParticleSwooshShaders::EShaderClass CParticleSwooshShaders::GetShaderClass(CPar return EShaderClass::NoTex; } -void CParticleSwooshShaders::BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CParticleSwoosh& gen) { +void CParticleSwooshShaders::BuildShaderDataBinding(CParticleSwoosh& gen) { CSwooshDescription* desc = gen.GetDesc(); - std::array, 2>* pipeline = nullptr; - - if (desc->x3c_TEXR) { - if (desc->x44_31_AALP) { - if (desc->x45_24_ZBUF) - pipeline = &m_texAdditiveZWrite; - else - pipeline = &m_texAdditiveNoZWrite; - } else { - if (desc->x45_24_ZBUF) - pipeline = &m_texZWrite; - else - pipeline = &m_texNoZWrite; - } - } else { - if (desc->x44_31_AALP) { - if (desc->x45_24_ZBUF) - pipeline = &m_noTexAdditiveZWrite; - else - pipeline = &m_noTexAdditiveNoZWrite; - } else { - if (desc->x45_24_ZBUF) - pipeline = &m_noTexZWrite; - else - pipeline = &m_noTexNoZWrite; - } - } - - const CUVElement* const texr = desc->x3c_TEXR.get(); - const std::array, 1> textures{ - texr ? texr->GetValueTexture(0).GetObj()->GetBooTexture() : nullptr, - }; - - const std::array, 1> uniforms{gen.m_uniformBuf.get()}; - for (size_t i = 0; i < gen.m_dataBind.size(); ++i) { - gen.m_dataBind[i] = - ctx.newShaderDataBinding((*pipeline)[i], gen.m_vertBuf.get(), nullptr, nullptr, uniforms.size(), - uniforms.data(), nullptr, texr ? 1 : 0, textures.data(), nullptr, nullptr); - } +// std::array, 2>* pipeline = nullptr; +// +// if (desc->x3c_TEXR) { +// if (desc->x44_31_AALP) { +// if (desc->x45_24_ZBUF) +// pipeline = &m_texAdditiveZWrite; +// else +// pipeline = &m_texAdditiveNoZWrite; +// } else { +// if (desc->x45_24_ZBUF) +// pipeline = &m_texZWrite; +// else +// pipeline = &m_texNoZWrite; +// } +// } else { +// if (desc->x44_31_AALP) { +// if (desc->x45_24_ZBUF) +// pipeline = &m_noTexAdditiveZWrite; +// else +// pipeline = &m_noTexAdditiveNoZWrite; +// } else { +// if (desc->x45_24_ZBUF) +// pipeline = &m_noTexZWrite; +// else +// pipeline = &m_noTexNoZWrite; +// } +// } +// +// const CUVElement* const texr = desc->x3c_TEXR.get(); +// const std::array, 1> textures{ +// texr ? texr->GetValueTexture(0).GetObj()->GetBooTexture() : nullptr, +// }; +// +// const std::array, 1> uniforms{gen.m_uniformBuf.get()}; +// for (size_t i = 0; i < gen.m_dataBind.size(); ++i) { +// gen.m_dataBind[i] = +// ctx.newShaderDataBinding((*pipeline)[i], gen.m_vertBuf.get(), nullptr, nullptr, uniforms.size(), +// uniforms.data(), nullptr, texr ? 1 : 0, textures.data(), nullptr, nullptr); +// } } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp b/Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp index bcdd8aae4..5b4211a12 100644 --- a/Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp +++ b/Runtime/Graphics/Shaders/CParticleSwooshShaders.hpp @@ -2,7 +2,7 @@ #include -#include +//#include #include #include @@ -22,21 +22,21 @@ public: }; private: - static std::array, 2> m_texZWrite; - static std::array, 2> m_texNoZWrite; - static std::array, 2> m_texAdditiveZWrite; - static std::array, 2> m_texAdditiveNoZWrite; - - static std::array, 2> m_noTexZWrite; - static std::array, 2> m_noTexNoZWrite; - static std::array, 2> m_noTexAdditiveZWrite; - static std::array, 2> m_noTexAdditiveNoZWrite; +// static std::array, 2> m_texZWrite; +// static std::array, 2> m_texNoZWrite; +// static std::array, 2> m_texAdditiveZWrite; +// static std::array, 2> m_texAdditiveNoZWrite; +// +// static std::array, 2> m_noTexZWrite; +// static std::array, 2> m_noTexNoZWrite; +// static std::array, 2> m_noTexAdditiveZWrite; +// static std::array, 2> m_noTexAdditiveNoZWrite; public: static void Initialize(); static void Shutdown(); static EShaderClass GetShaderClass(CParticleSwoosh& gen); - static void BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx, CParticleSwoosh& gen); + static void BuildShaderDataBinding(CParticleSwoosh& gen); }; } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CPhazonSuitFilter.cpp b/Runtime/Graphics/Shaders/CPhazonSuitFilter.cpp index 7316e32e3..fdabdcb07 100644 --- a/Runtime/Graphics/Shaders/CPhazonSuitFilter.cpp +++ b/Runtime/Graphics/Shaders/CPhazonSuitFilter.cpp @@ -2,11 +2,11 @@ #include -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include +//#include #include #include @@ -15,127 +15,128 @@ namespace metaforce { -static boo::ObjToken s_IndPipeline; -static boo::ObjToken s_Pipeline; -static boo::ObjToken s_BlurPipeline; +// static boo::ObjToken s_IndPipeline; +// static boo::ObjToken s_Pipeline; +// static boo::ObjToken s_BlurPipeline; void CPhazonSuitFilter::Initialize() { - s_IndPipeline = hecl::conv->convert(Shader_CPhazonSuitFilterInd{}); - s_Pipeline = hecl::conv->convert(Shader_CPhazonSuitFilterNoInd{}); - s_BlurPipeline = hecl::conv->convert(Shader_CPhazonSuitFilterBlur{}); + // s_IndPipeline = hecl::conv->convert(Shader_CPhazonSuitFilterInd{}); + // s_Pipeline = hecl::conv->convert(Shader_CPhazonSuitFilterNoInd{}); + // s_BlurPipeline = hecl::conv->convert(Shader_CPhazonSuitFilterBlur{}); } void CPhazonSuitFilter::Shutdown() { - s_IndPipeline.reset(); - s_Pipeline.reset(); - s_BlurPipeline.reset(); + // s_IndPipeline.reset(); + // s_Pipeline.reset(); + // s_BlurPipeline.reset(); } void CPhazonSuitFilter::drawBlurPasses(float radius, const CTexture* indTex) { SCOPED_GRAPHICS_DEBUG_GROUP("CPhazonSuitFilter::drawBlurPasses", zeus::skMagenta); - if (!m_dataBind || indTex != m_indTex) { - m_indTex = indTex; - CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - m_uniBufBlurX = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f), 1); - m_uniBufBlurY = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f), 1); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f) * 2, 1); - - struct BlurVert { - zeus::CVector3f pos; - zeus::CVector2f uv; - }; - const std::array blurVerts{{ - {{-1.f, 1.f, 0.f}, {0.f, 1.f}}, - {{-1.f, -1.f, 0.f}, {0.f, 0.f}}, - {{1.f, 1.f, 0.f}, {1.f, 1.f}}, - {{1.f, -1.f, 0.f}, {1.f, 0.f}}, - }}; - m_blurVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, blurVerts.data(), sizeof(BlurVert), blurVerts.size()); - - struct Vert { - zeus::CVector3f pos; - zeus::CVector2f screenUv; - zeus::CVector2f indUv; - zeus::CVector2f maskUv; - }; - const std::array verts{{ - {{-1.f, 1.f, 0.f}, {0.01f, 0.99f}, {0.f, 4.f}, {0.f, 1.f}}, - {{-1.f, -1.f, 0.f}, {0.01f, 0.01f}, {0.f, 0.f}, {0.f, 0.f}}, - {{1.f, 1.f, 0.f}, {0.99f, 0.99f}, {g_Viewport.aspect * 4.f, 4.f}, {1.f, 1.f}}, - {{1.f, -1.f, 0.f}, {0.99f, 0.01f}, {g_Viewport.aspect * 4.f, 0.f}, {1.f, 0.f}}, - }}; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); - - std::array, 1> bufs{m_uniBufBlurX.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - std::array, 4> texs; - std::array texBindIdxs; - - texs[0] = CGraphics::g_SpareTexture.get(); - texBindIdxs[0] = 1; - m_dataBindBlurX = - ctx.newShaderDataBinding(s_BlurPipeline, m_blurVbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, 1, texs.data(), texBindIdxs.data(), nullptr); - - bufs[0] = m_uniBufBlurY.get(); - texs[0] = CGraphics::g_SpareTexture.get(); - texBindIdxs[0] = 2; - m_dataBindBlurY = - ctx.newShaderDataBinding(s_BlurPipeline, m_blurVbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, 1, texs.data(), texBindIdxs.data(), nullptr); - - bufs[0] = m_uniBuf.get(); - size_t texCount; - if (m_indTex) { - texs[0] = CGraphics::g_SpareTexture.get(); - texBindIdxs[0] = 0; - texs[1] = m_indTex->GetBooTexture(); - texBindIdxs[1] = 0; - texs[2] = CGraphics::g_SpareTexture.get(); - texBindIdxs[2] = 1; - texs[3] = CGraphics::g_SpareTexture.get(); - texBindIdxs[3] = 2; - texCount = 4; - } else { - texs[0] = CGraphics::g_SpareTexture.get(); - texBindIdxs[0] = 0; - texs[1] = CGraphics::g_SpareTexture.get(); - texBindIdxs[1] = 1; - texs[2] = CGraphics::g_SpareTexture.get(); - texBindIdxs[2] = 2; - texCount = 3; - } - - m_dataBind = ctx.newShaderDataBinding(m_indTex ? s_IndPipeline : s_Pipeline, m_vbo.get(), nullptr, nullptr, - bufs.size(), bufs.data(), stages.data(), nullptr, nullptr, texCount, - texs.data(), texBindIdxs.data(), nullptr); - return true; - } BooTrace); - } + // if (!m_dataBind || indTex != m_indTex) { + // m_indTex = indTex; + // CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { + // m_uniBufBlurX = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f), 1); + // m_uniBufBlurY = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f), 1); + // m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CVector4f) * 2, 1); + // + // struct BlurVert { + // zeus::CVector3f pos; + // zeus::CVector2f uv; + // }; + // const std::array blurVerts{{ + // {{-1.f, 1.f, 0.f}, {0.f, 1.f}}, + // {{-1.f, -1.f, 0.f}, {0.f, 0.f}}, + // {{1.f, 1.f, 0.f}, {1.f, 1.f}}, + // {{1.f, -1.f, 0.f}, {1.f, 0.f}}, + // }}; + // m_blurVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, blurVerts.data(), sizeof(BlurVert), blurVerts.size()); + // + // struct Vert { + // zeus::CVector3f pos; + // zeus::CVector2f screenUv; + // zeus::CVector2f indUv; + // zeus::CVector2f maskUv; + // }; + // const std::array verts{{ + // {{-1.f, 1.f, 0.f}, {0.01f, 0.99f}, {0.f, 4.f}, {0.f, 1.f}}, + // {{-1.f, -1.f, 0.f}, {0.01f, 0.01f}, {0.f, 0.f}, {0.f, 0.f}}, + // {{1.f, 1.f, 0.f}, {0.99f, 0.99f}, {g_Viewport.aspect * 4.f, 4.f}, {1.f, 1.f}}, + // {{1.f, -1.f, 0.f}, {0.99f, 0.01f}, {g_Viewport.aspect * 4.f, 0.f}, {1.f, 0.f}}, + // }}; + // m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); + // + // std::array, 1> bufs{m_uniBufBlurX.get()}; + // constexpr std::array stages{boo::PipelineStage::Vertex}; + // std::array, 4> texs; + // std::array texBindIdxs; + // + // texs[0] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[0] = 1; + // m_dataBindBlurX = + // ctx.newShaderDataBinding(s_BlurPipeline, m_blurVbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), + // stages.data(), nullptr, nullptr, 1, texs.data(), texBindIdxs.data(), nullptr); + // + // bufs[0] = m_uniBufBlurY.get(); + // texs[0] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[0] = 2; + // m_dataBindBlurY = + // ctx.newShaderDataBinding(s_BlurPipeline, m_blurVbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), + // stages.data(), nullptr, nullptr, 1, texs.data(), texBindIdxs.data(), nullptr); + // + // bufs[0] = m_uniBuf.get(); + // size_t texCount; + // if (m_indTex) { + // texs[0] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[0] = 0; + // texs[1] = m_indTex->GetBooTexture(); + // texBindIdxs[1] = 0; + // texs[2] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[2] = 1; + // texs[3] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[3] = 2; + // texCount = 4; + // } else { + // texs[0] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[0] = 0; + // texs[1] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[1] = 1; + // texs[2] = CGraphics::g_SpareTexture.get(); + // texBindIdxs[2] = 2; + // texCount = 3; + // } + // + // m_dataBind = ctx.newShaderDataBinding(m_indTex ? s_IndPipeline : s_Pipeline, m_vbo.get(), nullptr, nullptr, + // bufs.size(), bufs.data(), stages.data(), nullptr, nullptr, texCount, + // texs.data(), texBindIdxs.data(), nullptr); + // return true; + // } BooTrace); + // } SClipScreenRect rect; - rect.x4_left = g_Viewport.x0_left; - rect.x8_top = g_Viewport.x4_top; - rect.xc_width = g_Viewport.x8_width; - rect.x10_height = g_Viewport.xc_height; + rect.x4_left = CGraphics::GetViewportLeft(); + rect.x8_top = CGraphics::GetViewportTop(); + rect.xc_width = CGraphics::GetViewportWidth(); + rect.x10_height = CGraphics::GetViewportTop(); constexpr float blurScale = 1.0f / 128.0f; /* X Pass */ - auto blurDir = zeus::CVector4f{g_Viewport.xc_height / float(g_Viewport.x8_width) * radius * blurScale, 0.f, 0.f, 0.f}; - m_uniBufBlurX->load(&blurDir, sizeof(zeus::CVector4f)); + auto blurDir = zeus::CVector4f{ + CGraphics::GetViewportHeight() / float(CGraphics::GetViewportWidth()) * radius * blurScale, 0.f, 0.f, 0.f}; + // m_uniBufBlurX->load(&blurDir, sizeof(zeus::CVector4f)); - CGraphics::SetShaderDataBinding(m_dataBindBlurX); - CGraphics::DrawArray(0, 4); - CGraphics::ResolveSpareTexture(rect, 2); + // CGraphics::SetShaderDataBinding(m_dataBindBlurX); + // CGraphics::DrawArray(0, 4); +// CGraphics::ResolveSpareTexture(rect, 2); /* Y Pass */ blurDir = zeus::CVector4f{0.f, radius * blurScale, 0.f, 0.f}; - m_uniBufBlurY->load(&blurDir, sizeof(zeus::CVector4f)); + // m_uniBufBlurY->load(&blurDir, sizeof(zeus::CVector4f)); - CGraphics::SetShaderDataBinding(m_dataBindBlurY); - CGraphics::DrawArray(0, 4); - CGraphics::ResolveSpareTexture(rect, 2); + // CGraphics::SetShaderDataBinding(m_dataBindBlurY); + // CGraphics::DrawArray(0, 4); +// CGraphics::ResolveSpareTexture(rect, 2); } void CPhazonSuitFilter::draw(const zeus::CColor& color, float indScale, float indOffX, float indOffY) { @@ -145,9 +146,9 @@ void CPhazonSuitFilter::draw(const zeus::CColor& color, float indScale, float in zeus::CVector4f indScaleOff; } uniform = {color, zeus::CVector4f(indScale, indScale, indOffX, indOffY)}; - m_uniBuf->load(&uniform, sizeof(Uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); + // m_uniBuf->load(&uniform, sizeof(Uniform)); + // CGraphics::SetShaderDataBinding(m_dataBind); + // CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CPhazonSuitFilter.hpp b/Runtime/Graphics/Shaders/CPhazonSuitFilter.hpp index d966356c4..c3e39a3d1 100644 --- a/Runtime/Graphics/Shaders/CPhazonSuitFilter.hpp +++ b/Runtime/Graphics/Shaders/CPhazonSuitFilter.hpp @@ -1,24 +1,24 @@ #pragma once -#include +//#include namespace zeus { class CColor; -} +} // namespace zeus namespace metaforce { class CTexture; class CPhazonSuitFilter { - boo::ObjToken m_uniBufBlurX; - boo::ObjToken m_uniBufBlurY; - boo::ObjToken m_uniBuf; - boo::ObjToken m_blurVbo; - boo::ObjToken m_vbo; +// boo::ObjToken m_uniBufBlurX; +// boo::ObjToken m_uniBufBlurY; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_blurVbo; +// boo::ObjToken m_vbo; const CTexture* m_indTex = nullptr; - boo::ObjToken m_dataBindBlurX; - boo::ObjToken m_dataBindBlurY; - boo::ObjToken m_dataBind; +// boo::ObjToken m_dataBindBlurX; +// boo::ObjToken m_dataBindBlurY; +// boo::ObjToken m_dataBind; public: static void Initialize(); diff --git a/Runtime/Graphics/Shaders/CRadarPaintShader.cpp b/Runtime/Graphics/Shaders/CRadarPaintShader.cpp index 2b153f55d..26dc50508 100644 --- a/Runtime/Graphics/Shaders/CRadarPaintShader.cpp +++ b/Runtime/Graphics/Shaders/CRadarPaintShader.cpp @@ -5,15 +5,19 @@ #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_Pipeline; -void CRadarPaintShader::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CRadarPaintShader{}); } +void CRadarPaintShader::Initialize() { +// s_Pipeline = hecl::conv->convert(Shader_CRadarPaintShader{}); +} -void CRadarPaintShader::Shutdown() { s_Pipeline.reset(); } +void CRadarPaintShader::Shutdown() { +// s_Pipeline.reset(); +} void CRadarPaintShader::draw(const std::vector& instances, const CTexture* tex) { if (!instances.size()) @@ -23,31 +27,31 @@ void CRadarPaintShader::draw(const std::vector& instances, const CText if (instances.size() > m_maxInsts) { m_maxInsts = instances.size(); m_tex = tex; - CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Instance), m_maxInsts); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CMatrix4f), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 1> texs{m_tex->GetBooTexture()}; - - m_dataBind = - ctx.newShaderDataBinding(s_Pipeline, nullptr, m_vbo.get(), nullptr, bufs.size(), bufs.data(), stages.data(), - nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, sizeof(Instance), m_maxInsts); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(zeus::CMatrix4f), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 1> texs{m_tex->GetBooTexture()}; +// +// m_dataBind = +// ctx.newShaderDataBinding(s_Pipeline, nullptr, m_vbo.get(), nullptr, bufs.size(), bufs.data(), stages.data(), +// nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); } - zeus::CMatrix4f uniMtx = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); - m_uniBuf->load(&uniMtx, sizeof(zeus::CMatrix4f)); + zeus::CMatrix4f uniMtx = CGraphics::GetPerspectiveProjectionMatrix(/*true*/) * CGraphics::g_GXModelView.toMatrix4f(); +// m_uniBuf->load(&uniMtx, sizeof(zeus::CMatrix4f)); size_t mapSz = sizeof(Instance) * instances.size(); - Instance* insts = reinterpret_cast(m_vbo->map(mapSz)); - memmove(insts, instances.data(), mapSz); - m_vbo->unmap(); +// Instance* insts = reinterpret_cast(m_vbo->map(mapSz)); +// memmove(insts, instances.data(), mapSz); +// m_vbo->unmap(); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawInstances(0, 4, instances.size()); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawInstances(0, 4, instances.size()); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CRadarPaintShader.hpp b/Runtime/Graphics/Shaders/CRadarPaintShader.hpp index fbf4e2335..eb8acbbef 100644 --- a/Runtime/Graphics/Shaders/CRadarPaintShader.hpp +++ b/Runtime/Graphics/Shaders/CRadarPaintShader.hpp @@ -3,7 +3,7 @@ #include #include -#include +//#include #include #include @@ -21,9 +21,9 @@ public: }; private: - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; const CTexture* m_tex = nullptr; size_t m_maxInsts = 0; diff --git a/Runtime/Graphics/Shaders/CRandomStaticFilter.cpp b/Runtime/Graphics/Shaders/CRandomStaticFilter.cpp index cc1e857ee..1751d3376 100644 --- a/Runtime/Graphics/Shaders/CRandomStaticFilter.cpp +++ b/Runtime/Graphics/Shaders/CRandomStaticFilter.cpp @@ -4,67 +4,67 @@ #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Camera/CCameraFilter.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_AlphaPipeline; -static boo::ObjToken s_AddPipeline; -static boo::ObjToken s_MultPipeline; -static boo::ObjToken s_CookieCutterPipeline; +//static boo::ObjToken s_AlphaPipeline; +//static boo::ObjToken s_AddPipeline; +//static boo::ObjToken s_MultPipeline; +//static boo::ObjToken s_CookieCutterPipeline; void CRandomStaticFilter::Initialize() { - s_AlphaPipeline = hecl::conv->convert(Shader_CRandomStaticFilterAlpha{}); - s_AddPipeline = hecl::conv->convert(Shader_CRandomStaticFilterAdd{}); - s_MultPipeline = hecl::conv->convert(Shader_CRandomStaticFilterMult{}); - s_CookieCutterPipeline = hecl::conv->convert(Shader_CRandomStaticFilterCookieCutter{}); +// s_AlphaPipeline = hecl::conv->convert(Shader_CRandomStaticFilterAlpha{}); +// s_AddPipeline = hecl::conv->convert(Shader_CRandomStaticFilterAdd{}); +// s_MultPipeline = hecl::conv->convert(Shader_CRandomStaticFilterMult{}); +// s_CookieCutterPipeline = hecl::conv->convert(Shader_CRandomStaticFilterCookieCutter{}); } void CRandomStaticFilter::Shutdown() { - s_AlphaPipeline.reset(); - s_AddPipeline.reset(); - s_MultPipeline.reset(); - s_CookieCutterPipeline.reset(); +// s_AlphaPipeline.reset(); +// s_AddPipeline.reset(); +// s_MultPipeline.reset(); +// s_CookieCutterPipeline.reset(); } -static boo::ObjToken SelectPipeline(EFilterType type) { - switch (type) { - case EFilterType::Blend: - return s_AlphaPipeline; - case EFilterType::Add: - return s_AddPipeline; - case EFilterType::Multiply: - return s_MultPipeline; - default: - return {}; - } -} +//static boo::ObjToken SelectPipeline(EFilterType type) { +// switch (type) { +// case EFilterType::Blend: +// return s_AlphaPipeline; +// case EFilterType::Add: +// return s_AddPipeline; +// case EFilterType::Multiply: +// return s_MultPipeline; +// default: +// return {}; +// } +//} CRandomStaticFilter::CRandomStaticFilter(EFilterType type, bool cookieCutter) : m_cookieCutter(cookieCutter) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - struct Vert { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - }; - const std::array verts{{ - {{-1.f, -1.f}, {0.f, 0.f}}, - {{-1.f, 1.f}, {0.f, 448.f}}, - {{1.f, -1.f}, {640.f, 0.f}}, - {{1.f, 1.f}, {640.f, 448.f}}, - }}; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 1> texs{g_Renderer->GetRandomStaticEntropyTex()}; - m_dataBind = ctx.newShaderDataBinding(m_cookieCutter ? s_CookieCutterPipeline : SelectPipeline(type), m_vbo.get(), - nullptr, nullptr, bufs.size(), bufs.data(), stages.data(), nullptr, nullptr, - texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// struct Vert { +// zeus::CVector2f m_pos; +// zeus::CVector2f m_uv; +// }; +// const std::array verts{{ +// {{-1.f, -1.f}, {0.f, 0.f}}, +// {{-1.f, 1.f}, {0.f, 448.f}}, +// {{1.f, -1.f}, {640.f, 0.f}}, +// {{1.f, 1.f}, {640.f, 448.f}}, +// }}; +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), sizeof(Vert), verts.size()); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 1> texs{g_Renderer->GetRandomStaticEntropyTex()}; +// m_dataBind = ctx.newShaderDataBinding(m_cookieCutter ? s_CookieCutterPipeline : SelectPipeline(type), m_vbo.get(), +// nullptr, nullptr, bufs.size(), bufs.data(), stages.data(), nullptr, nullptr, +// texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); } void CRandomStaticFilter::draw(const zeus::CColor& color, float t) { @@ -74,10 +74,10 @@ void CRandomStaticFilter::draw(const zeus::CColor& color, float t) { m_uniform.randOff = ROUND_UP_32(int64_t(rand()) * 32767 / RAND_MAX); m_uniform.discardThres = 1.f - t; - m_uniBuf->load(&m_uniform, sizeof(Uniform)); - - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// m_uniBuf->load(&m_uniform, sizeof(Uniform)); +// +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp b/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp index 8cf10f9a6..64a78a131 100644 --- a/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp +++ b/Runtime/Graphics/Shaders/CRandomStaticFilter.hpp @@ -2,7 +2,7 @@ #include "Runtime/CToken.hpp" -#include +//#include #include namespace metaforce { @@ -17,9 +17,9 @@ class CRandomStaticFilter { float randOff; float discardThres; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; bool m_cookieCutter; diff --git a/Runtime/Graphics/Shaders/CScanLinesFilter.cpp b/Runtime/Graphics/Shaders/CScanLinesFilter.cpp index 6dc980e44..2fb9f8a56 100644 --- a/Runtime/Graphics/Shaders/CScanLinesFilter.cpp +++ b/Runtime/Graphics/Shaders/CScanLinesFilter.cpp @@ -4,64 +4,64 @@ #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Camera/CCameraFilter.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_AlphaPipeline; -static boo::ObjToken s_AddPipeline; -static boo::ObjToken s_MultPipeline; +//static boo::ObjToken s_AlphaPipeline; +//static boo::ObjToken s_AddPipeline; +//static boo::ObjToken s_MultPipeline; void CScanLinesFilter::Initialize() { - s_AlphaPipeline = hecl::conv->convert(Shader_CScanLinesFilterAlpha{}); - s_AddPipeline = hecl::conv->convert(Shader_CScanLinesFilterAdd{}); - s_MultPipeline = hecl::conv->convert(Shader_CScanLinesFilterMult{}); +// s_AlphaPipeline = hecl::conv->convert(Shader_CScanLinesFilterAlpha{}); +// s_AddPipeline = hecl::conv->convert(Shader_CScanLinesFilterAdd{}); +// s_MultPipeline = hecl::conv->convert(Shader_CScanLinesFilterMult{}); } void CScanLinesFilter::Shutdown() { - s_AlphaPipeline.reset(); - s_AddPipeline.reset(); - s_MultPipeline.reset(); +// s_AlphaPipeline.reset(); +// s_AddPipeline.reset(); +// s_MultPipeline.reset(); } -static boo::ObjToken SelectPipeline(EFilterType type) { - switch (type) { - case EFilterType::Blend: - return s_AlphaPipeline; - case EFilterType::Add: - return s_AddPipeline; - case EFilterType::Multiply: - return s_MultPipeline; - default: - return {}; - } -} +//static boo::ObjToken SelectPipeline(EFilterType type) { +// switch (type) { +// case EFilterType::Blend: +// return s_AlphaPipeline; +// case EFilterType::Add: +// return s_AddPipeline; +// case EFilterType::Multiply: +// return s_MultPipeline; +// default: +// return {}; +// } +//} CScanLinesFilter::CScanLinesFilter(EFilterType type, bool even) : m_even(even) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - boo::ObjToken vbo = - m_even ? g_Renderer->GetScanLinesEvenVBO().get() : g_Renderer->GetScanLinesOddVBO().get(); - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - - m_dataBind = ctx.newShaderDataBinding(SelectPipeline(type), vbo, nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// boo::ObjToken vbo = +// m_even ? g_Renderer->GetScanLinesEvenVBO().get() : g_Renderer->GetScanLinesOddVBO().get(); +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// +// m_dataBind = ctx.newShaderDataBinding(SelectPipeline(type), vbo, nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); +// return true; +// } BooTrace); } void CScanLinesFilter::draw(const zeus::CColor& color) { SCOPED_GRAPHICS_DEBUG_GROUP("CScanLinesFilter::draw", zeus::skMagenta); m_uniform.color = color; - m_uniBuf->load(&m_uniform, sizeof(Uniform)); - - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 670); +// m_uniBuf->load(&m_uniform, sizeof(Uniform)); +// +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 670); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CScanLinesFilter.hpp b/Runtime/Graphics/Shaders/CScanLinesFilter.hpp index cdd048fd3..3b2b28f28 100644 --- a/Runtime/Graphics/Shaders/CScanLinesFilter.hpp +++ b/Runtime/Graphics/Shaders/CScanLinesFilter.hpp @@ -2,7 +2,7 @@ #include "Runtime/CToken.hpp" -#include +//#include #include namespace metaforce { @@ -15,8 +15,8 @@ class CScanLinesFilter { struct Uniform { zeus::CColor color; }; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; bool m_even; diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp index ec9478e41..0a8dcee46 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.cpp @@ -1,21 +1,25 @@ #include "Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include #define WARP_RAMP_RES 32 namespace metaforce { -static boo::ObjToken s_Pipeline; +// static boo::ObjToken s_Pipeline; -void CSpaceWarpFilter::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CSpaceWarpFilter{}); } +void CSpaceWarpFilter::Initialize() { + // s_Pipeline = hecl::conv->convert(Shader_CSpaceWarpFilter{}); +} -void CSpaceWarpFilter::Shutdown() { s_Pipeline.reset(); } +void CSpaceWarpFilter::Shutdown() { + // s_Pipeline.reset(); +} -void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& ctx) { +void CSpaceWarpFilter::GenerateWarpRampTex() { std::array, WARP_RAMP_RES + 1>, WARP_RAMP_RES + 1> data{}; const float halfRes = WARP_RAMP_RES / 2.f; for (int y = 0; y < WARP_RAMP_RES + 1; ++y) { @@ -31,40 +35,38 @@ void CSpaceWarpFilter::GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& c data[y][x][0] = data[y][x][1] = data[y][x][2]; } } - m_warpTex = - ctx.newStaticTexture(WARP_RAMP_RES + 1, WARP_RAMP_RES + 1, 1, boo::TextureFormat::RGBA8, - boo::TextureClampMode::Repeat, data.data(), (WARP_RAMP_RES + 1) * (WARP_RAMP_RES + 1) * 4) - .get(); + m_warpTex.emplace(ETexelFormat::RGBA8PC, WARP_RAMP_RES + 1, WARP_RAMP_RES + 1, 1, "Warp Ramp"); } CSpaceWarpFilter::CSpaceWarpFilter() { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - GenerateWarpRampTex(ctx); - - struct Vert { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - }; - const std::array verts{{ - {{-1.f, -1.f}, {0.f, 0.f}}, - {{-1.f, 1.f}, {0.f, 1.f}}, - {{1.f, -1.f}, {1.f, 0.f}}, - {{1.f, 1.f}, {1.f, 1.f}}, - }}; - - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 2> texs{ - CGraphics::g_SpareTexture.get(), - m_warpTex.get(), - }; - m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); + // CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { + // GenerateWarpRampTex(ctx); + // + // struct Vert { + // zeus::CVector2f m_pos; + // zeus::CVector2f m_uv; + // }; + // const std::array verts{{ + // {{-1.f, -1.f}, {0.f, 0.f}}, + // {{-1.f, 1.f}, {0.f, 1.f}}, + // {{1.f, -1.f}, {1.f, 0.f}}, + // {{1.f, 1.f}, {1.f, 1.f}}, + // }}; + // + // m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size()); + // m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); + // + // const std::array, 1> bufs{m_uniBuf.get()}; + // constexpr std::array stages{boo::PipelineStage::Vertex}; + // const std::array, 2> texs{ + // CGraphics::g_SpareTexture.get(), + // m_warpTex.get(), + // }; + // m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), + // stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, + // nullptr); + // return true; + // } BooTrace); } void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) { @@ -129,15 +131,15 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) { m_uniform.m_matrix[1][1] = clipRect.x10_height / vp.y(); m_uniform.m_matrix[3][0] = pt.x() + (1.f / vp.x()); m_uniform.m_matrix[3][1] = pt.y() + (1.f / vp.y()); - if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::OpenGL) { - m_uniform.m_matrix[3][2] = pt.z() * 2.f - 1.f; - } else if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::Vulkan) { - m_uniform.m_matrix[1][1] *= -1.f; - m_uniform.m_matrix[3][1] *= -1.f; - m_uniform.m_matrix[3][2] = pt.z(); - } else { - m_uniform.m_matrix[3][2] = pt.z(); - } + // if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::OpenGL) { + // m_uniform.m_matrix[3][2] = pt.z() * 2.f - 1.f; + // } else if (CGraphics::g_BooPlatform == boo::IGraphicsDataFactory::Platform::Vulkan) { + // m_uniform.m_matrix[1][1] *= -1.f; + // m_uniform.m_matrix[3][1] *= -1.f; + // m_uniform.m_matrix[3][2] = pt.z(); + // } else { + // m_uniform.m_matrix[3][2] = pt.z(); + // } if (clipRect.x4_left) { clipRect.x4_left -= 1; @@ -154,16 +156,16 @@ void CSpaceWarpFilter::draw(const zeus::CVector3f& pt) { clipRect.x4_left += CGraphics::g_CroppedViewport.x4_left; clipRect.x8_top += CGraphics::g_CroppedViewport.x8_top; - clipRect.x8_top = g_Viewport.xc_height - clipRect.x10_height - clipRect.x8_top; - CGraphics::ResolveSpareTexture(clipRect); + clipRect.x8_top = CGraphics::GetViewportHeight() - clipRect.x10_height - clipRect.x8_top; + // CGraphics::ResolveSpareTexture(clipRect); m_uniform.m_strength.x() = m_uniform.m_matrix[0][0] * m_strength * 0.5f * (clipRect.x10_height / float(clipRect.xc_width)); m_uniform.m_strength.y() = m_uniform.m_matrix[1][1] * m_strength * 0.5f; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); + // m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); + // CGraphics::SetShaderDataBinding(m_dataBind); + // CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp b/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp index ac5963b7c..a7c18a2b6 100644 --- a/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp +++ b/Runtime/Graphics/Shaders/CSpaceWarpFilter.hpp @@ -3,8 +3,8 @@ #include #include "Runtime/GCNTypes.hpp" - -#include +#include "Runtime/Graphics/CGraphics.hpp" +#include "Runtime/Graphics/CTexture.hpp" #include #include @@ -18,14 +18,14 @@ class CSpaceWarpFilter { zeus::CVector3f m_strength; }; std::array, 8>, 4> m_shiftTexture{}; - boo::ObjToken m_warpTex; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; + std::optional m_warpTex; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; float m_strength = 1.f; - void GenerateWarpRampTex(boo::IGraphicsDataFactory::Context& ctx); + void GenerateWarpRampTex(); public: static void Initialize(); diff --git a/Runtime/Graphics/Shaders/CTextSupportShader.cpp b/Runtime/Graphics/Shaders/CTextSupportShader.cpp index 9a0525c14..a00604956 100644 --- a/Runtime/Graphics/Shaders/CTextSupportShader.cpp +++ b/Runtime/Graphics/Shaders/CTextSupportShader.cpp @@ -3,42 +3,42 @@ #include "Runtime/GuiSys/CFontImageDef.hpp" #include "Runtime/GuiSys/CRasterFont.hpp" -#include +//#include namespace metaforce { -boo::ObjToken CTextSupportShader::s_TextAlphaPipeline; -boo::ObjToken CTextSupportShader::s_TextAddPipeline; -boo::ObjToken CTextSupportShader::s_TextAddOverdrawPipeline; - -boo::ObjToken CTextSupportShader::s_ImageAlphaPipeline; -boo::ObjToken CTextSupportShader::s_ImageAddPipeline; -boo::ObjToken CTextSupportShader::s_ImageAddOverdrawPipeline; - -hecl::VertexBufferPool CTextSupportShader::s_CharInsts; -hecl::VertexBufferPool CTextSupportShader::s_ImgInsts; -hecl::UniformBufferPool CTextSupportShader::s_Uniforms; +//boo::ObjToken CTextSupportShader::s_TextAlphaPipeline; +//boo::ObjToken CTextSupportShader::s_TextAddPipeline; +//boo::ObjToken CTextSupportShader::s_TextAddOverdrawPipeline; +// +//boo::ObjToken CTextSupportShader::s_ImageAlphaPipeline; +//boo::ObjToken CTextSupportShader::s_ImageAddPipeline; +//boo::ObjToken CTextSupportShader::s_ImageAddOverdrawPipeline; +// +//hecl::VertexBufferPool CTextSupportShader::s_CharInsts; +//hecl::VertexBufferPool CTextSupportShader::s_ImgInsts; +//hecl::UniformBufferPool CTextSupportShader::s_Uniforms; void CTextSupportShader::Initialize() { - s_TextAlphaPipeline = hecl::conv->convert(Shader_CTextSupportShaderAlpha{}); - s_TextAddPipeline = hecl::conv->convert(Shader_CTextSupportShaderAdd{}); - s_TextAddOverdrawPipeline = hecl::conv->convert(Shader_CTextSupportShaderAddOverdraw{}); - s_ImageAlphaPipeline = hecl::conv->convert(Shader_CTextSupportShaderImageAlpha{}); - s_ImageAddPipeline = hecl::conv->convert(Shader_CTextSupportShaderImageAdd{}); - s_ImageAddOverdrawPipeline = hecl::conv->convert(Shader_CTextSupportShaderImageAddOverdraw{}); +// s_TextAlphaPipeline = hecl::conv->convert(Shader_CTextSupportShaderAlpha{}); +// s_TextAddPipeline = hecl::conv->convert(Shader_CTextSupportShaderAdd{}); +// s_TextAddOverdrawPipeline = hecl::conv->convert(Shader_CTextSupportShaderAddOverdraw{}); +// s_ImageAlphaPipeline = hecl::conv->convert(Shader_CTextSupportShaderImageAlpha{}); +// s_ImageAddPipeline = hecl::conv->convert(Shader_CTextSupportShaderImageAdd{}); +// s_ImageAddOverdrawPipeline = hecl::conv->convert(Shader_CTextSupportShaderImageAddOverdraw{}); } void CTextSupportShader::Shutdown() { - s_TextAlphaPipeline.reset(); - s_TextAddPipeline.reset(); - s_TextAddOverdrawPipeline.reset(); - s_ImageAlphaPipeline.reset(); - s_ImageAddPipeline.reset(); - s_ImageAddOverdrawPipeline.reset(); - - s_CharInsts.doDestroy(); - s_ImgInsts.doDestroy(); - s_Uniforms.doDestroy(); +// s_TextAlphaPipeline.reset(); +// s_TextAddPipeline.reset(); +// s_TextAddOverdrawPipeline.reset(); +// s_ImageAlphaPipeline.reset(); +// s_ImageAddPipeline.reset(); +// s_ImageAddOverdrawPipeline.reset(); +// +// s_CharInsts.doDestroy(); +// s_ImgInsts.doDestroy(); +// s_Uniforms.doDestroy(); } void CTextSupportShader::CharacterInstance::SetMetrics(const CGlyph& glyph, const zeus::CVector2i& offset) { diff --git a/Runtime/Graphics/Shaders/CTextSupportShader.hpp b/Runtime/Graphics/Shaders/CTextSupportShader.hpp index 37ab564b1..580b29d73 100644 --- a/Runtime/Graphics/Shaders/CTextSupportShader.hpp +++ b/Runtime/Graphics/Shaders/CTextSupportShader.hpp @@ -4,8 +4,8 @@ #include "Runtime/GuiSys/CGuiWidget.hpp" -#include -#include +//#include +//#include #include #include @@ -21,13 +21,13 @@ class CTextRenderBuffer; class CTextSupportShader { friend class CTextRenderBuffer; - static boo::ObjToken s_TextAlphaPipeline; - static boo::ObjToken s_TextAddPipeline; - static boo::ObjToken s_TextAddOverdrawPipeline; - - static boo::ObjToken s_ImageAlphaPipeline; - static boo::ObjToken s_ImageAddPipeline; - static boo::ObjToken s_ImageAddOverdrawPipeline; +// static boo::ObjToken s_TextAlphaPipeline; +// static boo::ObjToken s_TextAddPipeline; +// static boo::ObjToken s_TextAddOverdrawPipeline; +// +// static boo::ObjToken s_ImageAlphaPipeline; +// static boo::ObjToken s_ImageAddPipeline; +// static boo::ObjToken s_ImageAddOverdrawPipeline; struct Uniform { zeus::CMatrix4f m_mvp; @@ -50,47 +50,47 @@ class CTextSupportShader { void SetMetrics(const CFontImageDef& imgDef, const zeus::CVector2i& offset); }; - static hecl::VertexBufferPool s_CharInsts; - static hecl::VertexBufferPool s_ImgInsts; - static hecl::UniformBufferPool s_Uniforms; +// static hecl::VertexBufferPool s_CharInsts; +// static hecl::VertexBufferPool s_ImgInsts; +// static hecl::UniformBufferPool s_Uniforms; public: - static boo::ObjToken SelectTextPipeline(CGuiWidget::EGuiModelDrawFlags df) { - switch (df) { - case CGuiWidget::EGuiModelDrawFlags::Shadeless: - case CGuiWidget::EGuiModelDrawFlags::Opaque: - case CGuiWidget::EGuiModelDrawFlags::Alpha: - case CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw: - return s_TextAlphaPipeline; - case CGuiWidget::EGuiModelDrawFlags::Additive: - return s_TextAddPipeline; - default: - return {}; - } - } - - static boo::ObjToken SelectImagePipeline(CGuiWidget::EGuiModelDrawFlags df) { - switch (df) { - case CGuiWidget::EGuiModelDrawFlags::Shadeless: - case CGuiWidget::EGuiModelDrawFlags::Opaque: - case CGuiWidget::EGuiModelDrawFlags::Alpha: - case CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw: - return s_ImageAlphaPipeline; - case CGuiWidget::EGuiModelDrawFlags::Additive: - return s_ImageAddPipeline; - default: - return {}; - } - } - - static boo::ObjToken GetTextAdditiveOverdrawPipeline() { return s_TextAddOverdrawPipeline; } - - static boo::ObjToken GetImageAdditiveOverdrawPipeline() { return s_ImageAddOverdrawPipeline; } +// static boo::ObjToken SelectTextPipeline(CGuiWidget::EGuiModelDrawFlags df) { +// switch (df) { +// case CGuiWidget::EGuiModelDrawFlags::Shadeless: +// case CGuiWidget::EGuiModelDrawFlags::Opaque: +// case CGuiWidget::EGuiModelDrawFlags::Alpha: +// case CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw: +// return s_TextAlphaPipeline; +// case CGuiWidget::EGuiModelDrawFlags::Additive: +// return s_TextAddPipeline; +// default: +// return {}; +// } +// } +// +// static boo::ObjToken SelectImagePipeline(CGuiWidget::EGuiModelDrawFlags df) { +// switch (df) { +// case CGuiWidget::EGuiModelDrawFlags::Shadeless: +// case CGuiWidget::EGuiModelDrawFlags::Opaque: +// case CGuiWidget::EGuiModelDrawFlags::Alpha: +// case CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw: +// return s_ImageAlphaPipeline; +// case CGuiWidget::EGuiModelDrawFlags::Additive: +// return s_ImageAddPipeline; +// default: +// return {}; +// } +// } +// +// static boo::ObjToken GetTextAdditiveOverdrawPipeline() { return s_TextAddOverdrawPipeline; } +// +// static boo::ObjToken GetImageAdditiveOverdrawPipeline() { return s_ImageAddOverdrawPipeline; } static void UpdateBuffers() { - s_CharInsts.updateBuffers(); - s_ImgInsts.updateBuffers(); - s_Uniforms.updateBuffers(); +// s_CharInsts.updateBuffers(); +// s_ImgInsts.updateBuffers(); +// s_Uniforms.updateBuffers(); } static void Initialize(); diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp index 7bbc857d1..f8c26e728 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp @@ -5,204 +5,204 @@ #include "Runtime/Camera/CCameraFilter.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include +//#include namespace metaforce { -static boo::ObjToken s_AlphaPipeline; -static boo::ObjToken s_AlphaGEqualPipeline; -static boo::ObjToken s_AlphaGEqualZWritePipeline; -static boo::ObjToken s_AlphaLEqualPipeline; -static boo::ObjToken s_AddPipeline; -static boo::ObjToken s_AddGEqualPipeline; -static boo::ObjToken s_AddGEqualZWritePipeline; -static boo::ObjToken s_AddLEqualPipeline; -static boo::ObjToken s_SubtractPipeline; -static boo::ObjToken s_SubtractGEqualPipeline; -static boo::ObjToken s_SubtractGEqualZWritePipeline; -static boo::ObjToken s_SubtractLEqualPipeline; -static boo::ObjToken s_MultPipeline; -static boo::ObjToken s_MultGEqualPipeline; -static boo::ObjToken s_MultGEqualZWritePipeline; -static boo::ObjToken s_MultLEqualPipeline; -static boo::ObjToken s_InvDstMultPipeline; -static boo::ObjToken s_InvDstMultGEqualPipeline; -static boo::ObjToken s_InvDstMultLEqualPipeline; - -static boo::ObjToken s_AAlphaPipeline; -static boo::ObjToken s_AAddPipeline; -static boo::ObjToken s_ASubtractPipeline; -static boo::ObjToken s_AMultPipeline; -static boo::ObjToken s_AInvDstMultPipeline; +//static boo::ObjToken s_AlphaPipeline; +//static boo::ObjToken s_AlphaGEqualPipeline; +//static boo::ObjToken s_AlphaGEqualZWritePipeline; +//static boo::ObjToken s_AlphaLEqualPipeline; +//static boo::ObjToken s_AddPipeline; +//static boo::ObjToken s_AddGEqualPipeline; +//static boo::ObjToken s_AddGEqualZWritePipeline; +//static boo::ObjToken s_AddLEqualPipeline; +//static boo::ObjToken s_SubtractPipeline; +//static boo::ObjToken s_SubtractGEqualPipeline; +//static boo::ObjToken s_SubtractGEqualZWritePipeline; +//static boo::ObjToken s_SubtractLEqualPipeline; +//static boo::ObjToken s_MultPipeline; +//static boo::ObjToken s_MultGEqualPipeline; +//static boo::ObjToken s_MultGEqualZWritePipeline; +//static boo::ObjToken s_MultLEqualPipeline; +//static boo::ObjToken s_InvDstMultPipeline; +//static boo::ObjToken s_InvDstMultGEqualPipeline; +//static boo::ObjToken s_InvDstMultLEqualPipeline; +// +//static boo::ObjToken s_AAlphaPipeline; +//static boo::ObjToken s_AAddPipeline; +//static boo::ObjToken s_ASubtractPipeline; +//static boo::ObjToken s_AMultPipeline; +//static boo::ObjToken s_AInvDstMultPipeline; void CTexturedQuadFilter::Initialize() { - s_AlphaPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlpha{}); - s_AlphaGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaGEqual{}); - s_AlphaGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaGEqualZWrite{}); - s_AlphaLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaLEqual{}); - s_AddPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAdd{}); - s_AddGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAddGEqual{}); - s_AddGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAddGEqualZWrite{}); - s_AddLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAddLEqual{}); - s_SubtractPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtract{}); - s_SubtractGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtractGEqual{}); - s_SubtractGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtractGEqualZWrite{}); - s_SubtractLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtractLEqual{}); - s_MultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMult{}); - s_MultGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMultGEqual{}); - s_MultGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMultGEqualZWrite{}); - s_MultLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMultLEqual{}); - s_InvDstMultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterInvDstMult{}); - s_InvDstMultGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterInvDstMultGEqual{}); - s_InvDstMultLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterInvDstMultLEqual{}); +// s_AlphaPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlpha{}); +// s_AlphaGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaGEqual{}); +// s_AlphaGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaGEqualZWrite{}); +// s_AlphaLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaLEqual{}); +// s_AddPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAdd{}); +// s_AddGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAddGEqual{}); +// s_AddGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAddGEqualZWrite{}); +// s_AddLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAddLEqual{}); +// s_SubtractPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtract{}); +// s_SubtractGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtractGEqual{}); +// s_SubtractGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtractGEqualZWrite{}); +// s_SubtractLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterSubtractLEqual{}); +// s_MultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMult{}); +// s_MultGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMultGEqual{}); +// s_MultGEqualZWritePipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMultGEqualZWrite{}); +// s_MultLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterMultLEqual{}); +// s_InvDstMultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterInvDstMult{}); +// s_InvDstMultGEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterInvDstMultGEqual{}); +// s_InvDstMultLEqualPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterInvDstMultLEqual{}); } void CTexturedQuadFilter::Shutdown() { - s_AlphaPipeline.reset(); - s_AlphaGEqualPipeline.reset(); - s_AlphaGEqualZWritePipeline.reset(); - s_AlphaLEqualPipeline.reset(); - s_AddPipeline.reset(); - s_AddGEqualPipeline.reset(); - s_AddGEqualZWritePipeline.reset(); - s_AddLEqualPipeline.reset(); - s_SubtractPipeline.reset(); - s_SubtractGEqualPipeline.reset(); - s_SubtractGEqualZWritePipeline.reset(); - s_SubtractLEqualPipeline.reset(); - s_MultPipeline.reset(); - s_MultGEqualPipeline.reset(); - s_MultGEqualZWritePipeline.reset(); - s_MultLEqualPipeline.reset(); - s_InvDstMultPipeline.reset(); - s_InvDstMultGEqualPipeline.reset(); - s_InvDstMultLEqualPipeline.reset(); +// s_AlphaPipeline.reset(); +// s_AlphaGEqualPipeline.reset(); +// s_AlphaGEqualZWritePipeline.reset(); +// s_AlphaLEqualPipeline.reset(); +// s_AddPipeline.reset(); +// s_AddGEqualPipeline.reset(); +// s_AddGEqualZWritePipeline.reset(); +// s_AddLEqualPipeline.reset(); +// s_SubtractPipeline.reset(); +// s_SubtractGEqualPipeline.reset(); +// s_SubtractGEqualZWritePipeline.reset(); +// s_SubtractLEqualPipeline.reset(); +// s_MultPipeline.reset(); +// s_MultGEqualPipeline.reset(); +// s_MultGEqualZWritePipeline.reset(); +// s_MultLEqualPipeline.reset(); +// s_InvDstMultPipeline.reset(); +// s_InvDstMultGEqualPipeline.reset(); +// s_InvDstMultLEqualPipeline.reset(); } void CTexturedQuadFilterAlpha::Initialize() { - s_AAlphaPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexAlpha{}); - s_AAddPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexAdd{}); - s_ASubtractPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexSubtract{}); - s_AMultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexMult{}); - s_AInvDstMultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexInvDstMult{}); +// s_AAlphaPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexAlpha{}); +// s_AAddPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexAdd{}); +// s_ASubtractPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexSubtract{}); +// s_AMultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexMult{}); +// s_AInvDstMultPipeline = hecl::conv->convert(Shader_CTexturedQuadFilterAlphaTexInvDstMult{}); } void CTexturedQuadFilterAlpha::Shutdown() { - s_AAlphaPipeline.reset(); - s_AAddPipeline.reset(); - s_ASubtractPipeline.reset(); - s_AMultPipeline.reset(); - s_AInvDstMultPipeline.reset(); +// s_AAlphaPipeline.reset(); +// s_AAddPipeline.reset(); +// s_ASubtractPipeline.reset(); +// s_AMultPipeline.reset(); +// s_AInvDstMultPipeline.reset(); } -static boo::ObjToken SelectPipeline(EFilterType type, CTexturedQuadFilter::ZTest zTest) { - switch (zTest) { - case CTexturedQuadFilter::ZTest::GEqual: - switch (type) { - case EFilterType::Blend: - return s_AlphaGEqualPipeline; - case EFilterType::Add: - return s_AddGEqualPipeline; - case EFilterType::Subtract: - return s_SubtractGEqualPipeline; - case EFilterType::Multiply: - return s_MultGEqualPipeline; - default: - break; - } - break; - case CTexturedQuadFilter::ZTest::GEqualZWrite: - switch (type) { - case EFilterType::Blend: - return s_AlphaGEqualZWritePipeline; - case EFilterType::Add: - return s_AddGEqualZWritePipeline; - case EFilterType::Subtract: - return s_SubtractGEqualZWritePipeline; - case EFilterType::Multiply: - return s_MultGEqualZWritePipeline; - default: - break; - } - break; - case CTexturedQuadFilter::ZTest::LEqual: - switch (type) { - case EFilterType::Blend: - return s_AlphaLEqualPipeline; - case EFilterType::Add: - return s_AddLEqualPipeline; - case EFilterType::Subtract: - return s_SubtractLEqualPipeline; - case EFilterType::Multiply: - return s_MultLEqualPipeline; - case EFilterType::InvDstMultiply: - return s_InvDstMultLEqualPipeline; - default: - break; - } - break; - default: - break; - } +//static boo::ObjToken SelectPipeline(EFilterType type, CTexturedQuadFilter::ZTest zTest) { +// switch (zTest) { +// case CTexturedQuadFilter::ZTest::GEqual: +// switch (type) { +// case EFilterType::Blend: +// return s_AlphaGEqualPipeline; +// case EFilterType::Add: +// return s_AddGEqualPipeline; +// case EFilterType::Subtract: +// return s_SubtractGEqualPipeline; +// case EFilterType::Multiply: +// return s_MultGEqualPipeline; +// default: +// break; +// } +// break; +// case CTexturedQuadFilter::ZTest::GEqualZWrite: +// switch (type) { +// case EFilterType::Blend: +// return s_AlphaGEqualZWritePipeline; +// case EFilterType::Add: +// return s_AddGEqualZWritePipeline; +// case EFilterType::Subtract: +// return s_SubtractGEqualZWritePipeline; +// case EFilterType::Multiply: +// return s_MultGEqualZWritePipeline; +// default: +// break; +// } +// break; +// case CTexturedQuadFilter::ZTest::LEqual: +// switch (type) { +// case EFilterType::Blend: +// return s_AlphaLEqualPipeline; +// case EFilterType::Add: +// return s_AddLEqualPipeline; +// case EFilterType::Subtract: +// return s_SubtractLEqualPipeline; +// case EFilterType::Multiply: +// return s_MultLEqualPipeline; +// case EFilterType::InvDstMultiply: +// return s_InvDstMultLEqualPipeline; +// default: +// break; +// } +// break; +// default: +// break; +// } +// +// switch (type) { +// case EFilterType::Blend: +// return s_AlphaPipeline; +// case EFilterType::Add: +// return s_AddPipeline; +// case EFilterType::Subtract: +// return s_SubtractPipeline; +// case EFilterType::Multiply: +// return s_MultPipeline; +// case EFilterType::InvDstMultiply: +// return s_InvDstMultPipeline; +// default: +// return {}; +// } +//} - switch (type) { - case EFilterType::Blend: - return s_AlphaPipeline; - case EFilterType::Add: - return s_AddPipeline; - case EFilterType::Subtract: - return s_SubtractPipeline; - case EFilterType::Multiply: - return s_MultPipeline; - case EFilterType::InvDstMultiply: - return s_InvDstMultPipeline; - default: - return {}; - } +//static boo::ObjToken SelectAlphaPipeline(EFilterType type) { +// switch (type) { +// case EFilterType::Blend: +// return s_AAlphaPipeline; +// case EFilterType::Add: +// return s_AAddPipeline; +// case EFilterType::Subtract: +// return s_ASubtractPipeline; +// case EFilterType::Multiply: +// return s_AMultPipeline; +// case EFilterType::InvDstMultiply: +// return s_AInvDstMultPipeline; +// default: +// return {}; +// } +//} + +CTexturedQuadFilter::CTexturedQuadFilter(const aurora::gfx::TextureHandle& tex) : m_booTex(tex) { + m_flipRect = true; // TODO? } -static boo::ObjToken SelectAlphaPipeline(EFilterType type) { - switch (type) { - case EFilterType::Blend: - return s_AAlphaPipeline; - case EFilterType::Add: - return s_AAddPipeline; - case EFilterType::Subtract: - return s_ASubtractPipeline; - case EFilterType::Multiply: - return s_AMultPipeline; - case EFilterType::InvDstMultiply: - return s_AInvDstMultPipeline; - default: - return {}; - } -} - -CTexturedQuadFilter::CTexturedQuadFilter(const boo::ObjToken& tex) : m_booTex(tex) { - m_flipRect = CGraphics::g_BooFactory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan; -} - -CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const boo::ObjToken& tex, ZTest ztest) +CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, const aurora::gfx::TextureHandle& tex, ERglEnum ztest) : m_booTex(tex), m_zTest(ztest) { - m_flipRect = CGraphics::g_BooFactory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan; - tex->setClampMode(boo::TextureClampMode::ClampToEdge); - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 16); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - const std::array stages{boo::PipelineStage::Vertex}; - const std::array, 1> texs{m_booTex.get()}; - m_dataBind = - ctx.newShaderDataBinding(SelectPipeline(type, m_zTest), m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); + m_flipRect = true; // TODO? +// tex->setClampMode(boo::TextureClampMode::ClampToEdge); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 16); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// const std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 1> texs{m_booTex.get()}; +// m_dataBind = +// ctx.newShaderDataBinding(SelectPipeline(type, m_zTest), m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); } -CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, TLockedToken tex, ZTest ztest) -: CTexturedQuadFilter(type, (tex ? tex->GetBooTexture() : nullptr), ztest) { - m_flipRect = CGraphics::g_BooFactory->platform() == boo::IGraphicsDataFactory::Platform::Vulkan; +CTexturedQuadFilter::CTexturedQuadFilter(EFilterType type, TLockedToken tex, ERglEnum ztest) +: CTexturedQuadFilter(type, aurora::gfx::TextureHandle{}, ztest) { + m_flipRect = true; // TODO? m_tex = tex; } @@ -215,7 +215,7 @@ void CTexturedQuadFilter::draw(const zeus::CColor& color, float uvScale, const z {{1.f, 0.f, z}, {uvScale, 0.f}}, {{1.f, 1.f, z}, {uvScale, uvScale}}, }}; - m_vbo->load(verts.data(), sizeof(verts)); +// m_vbo->load(verts.data(), sizeof(verts)); if (!m_flipRect) { m_uniform.m_matrix[0][0] = rect.size.x() * 2.f; @@ -229,19 +229,19 @@ void CTexturedQuadFilter::draw(const zeus::CColor& color, float uvScale, const z m_uniform.m_matrix[3][1] = rect.position.y() * -2.f + 1.f; } m_uniform.m_color = color; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } void CTexturedQuadFilter::drawCropped(const zeus::CColor& color, float uvScale) { SCOPED_GRAPHICS_DEBUG_GROUP("CTexturedQuadFilter::drawCropped", zeus::skMagenta); - const float xFac = CGraphics::g_CroppedViewport.xc_width / float(g_Viewport.x8_width); - const float yFac = CGraphics::g_CroppedViewport.x10_height / float(g_Viewport.xc_height); - const float xBias = CGraphics::g_CroppedViewport.x4_left / float(g_Viewport.x8_width); - const float yBias = CGraphics::g_CroppedViewport.x8_top / float(g_Viewport.xc_height); + const float xFac = CGraphics::GetCroppedViewportWidth() / float(CGraphics::GetViewportWidth()); + const float yFac = CGraphics::GetCroppedViewportHeight() / float(CGraphics::GetViewportHeight()); + const float xBias = CGraphics::GetCroppedViewportLeft() / float(CGraphics::GetViewportWidth()); + const float yBias = CGraphics::GetCroppedViewportTop() / float(CGraphics::GetViewportHeight()); const std::array verts{{ {{-1.f, -1.f, 0.f}, {xBias * uvScale, yBias * uvScale}}, @@ -249,27 +249,27 @@ void CTexturedQuadFilter::drawCropped(const zeus::CColor& color, float uvScale) {{1.f, -1.f, 0.f}, {(xBias + xFac) * uvScale, yBias * uvScale}}, {{1.f, 1.f, 0.f}, {(xBias + xFac) * uvScale, (yBias + yFac) * uvScale}}, }}; - m_vbo->load(verts.data(), sizeof(verts)); +// m_vbo->load(verts.data(), sizeof(verts)); m_uniform.m_color = color; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } void CTexturedQuadFilter::drawVerts(const zeus::CColor& color, std::array verts, float lod) { SCOPED_GRAPHICS_DEBUG_GROUP("CTexturedQuadFilter::drawVerts", zeus::skMagenta); - m_vbo->load(verts.data(), sizeof(Vert) * verts.size()); +// m_vbo->load(verts.data(), sizeof(Vert) * verts.size()); - m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(/*true*/) * CGraphics::g_GXModelView.toMatrix4f(); m_uniform.m_color = color; m_uniform.m_lod = lod; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, verts.size()); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, verts.size()); } void CTexturedQuadFilter::DrawFilter(EFilterShape shape, const zeus::CColor& color, float t) { @@ -278,9 +278,9 @@ void CTexturedQuadFilter::DrawFilter(EFilterShape shape, const zeus::CColor& col m_uniform.m_matrix = zeus::CMatrix4f(); m_uniform.m_lod = 0.f; m_uniform.m_color = color; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::SetShaderDataBinding(m_dataBind); if (shape == EFilterShape::FullscreenQuarters) { const std::array QuadVerts{{ @@ -305,11 +305,11 @@ void CTexturedQuadFilter::DrawFilter(EFilterShape shape, const zeus::CColor& col {{0.f, 1.f, 0.f}, {0.f, t}}, {{0.f, 0.f, 0.f}, {0.f, 0.f}}, }}; - m_vbo->load(QuadVerts.data(), sizeof(QuadVerts)); - CGraphics::DrawArray(0, 4); - CGraphics::DrawArray(4, 4); - CGraphics::DrawArray(8, 4); - CGraphics::DrawArray(12, 4); +// m_vbo->load(QuadVerts.data(), sizeof(QuadVerts)); +// CGraphics::DrawArray(0, 4); +// CGraphics::DrawArray(4, 4); +// CGraphics::DrawArray(8, 4); +// CGraphics::DrawArray(12, 4); } else { const std::array FullscreenVerts{{ {{-1.f, -1.f, 0.f}, {0.f, 0.f}}, @@ -317,29 +317,29 @@ void CTexturedQuadFilter::DrawFilter(EFilterShape shape, const zeus::CColor& col {{1.f, -1.f, 0.f}, {t, 0.f}}, {{1.f, 1.f, 0.f}, {t, t}}, }}; - m_vbo->load(FullscreenVerts.data(), sizeof(FullscreenVerts)); - CGraphics::DrawArray(0, FullscreenVerts.size()); +// m_vbo->load(FullscreenVerts.data(), sizeof(FullscreenVerts)); +// CGraphics::DrawArray(0, FullscreenVerts.size()); } } -CTexturedQuadFilterAlpha::CTexturedQuadFilterAlpha(EFilterType type, const boo::ObjToken& tex) +CTexturedQuadFilterAlpha::CTexturedQuadFilterAlpha(EFilterType type, const aurora::gfx::TextureHandle& tex) : CTexturedQuadFilter(tex) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 1> texs{m_booTex.get()}; - m_dataBind = - ctx.newShaderDataBinding(SelectAlphaPipeline(type), m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 32, 4); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 1> texs{m_booTex.get()}; +// m_dataBind = +// ctx.newShaderDataBinding(SelectAlphaPipeline(type), m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); } CTexturedQuadFilterAlpha::CTexturedQuadFilterAlpha(EFilterType type, TLockedToken tex) -: CTexturedQuadFilterAlpha(type, (tex ? tex->GetBooTexture() : nullptr)) { +: CTexturedQuadFilterAlpha(type, aurora::gfx::TextureHandle{}) { m_tex = tex; } diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp b/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp index 7bae3c3ce..1af3d9e8f 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp @@ -1,8 +1,7 @@ #pragma once #include "Runtime/CToken.hpp" - -#include +#include "Runtime/Graphics/CGraphics.hpp" #include #include @@ -18,7 +17,7 @@ enum class EFilterType; class CTexturedQuadFilter { public: - enum class ZTest { None, LEqual, GEqual, GEqualZWrite }; + enum class ZTest { Never, Less, Equal, LEqual, Greater, NEqual, GEqual, Always }; protected: struct Uniform { @@ -27,15 +26,15 @@ protected: float m_lod = 0.f; }; TLockedToken m_tex; - boo::ObjToken m_booTex; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; + aurora::gfx::TextureHandle m_booTex; + // boo::ObjToken m_vbo; + // boo::ObjToken m_uniBuf; + // boo::ObjToken m_dataBind; Uniform m_uniform; - ZTest m_zTest; + ERglEnum m_zTest; bool m_flipRect = false; - explicit CTexturedQuadFilter(const boo::ObjToken& tex); + explicit CTexturedQuadFilter(const aurora::gfx::TextureHandle& tex); public: struct Vert { @@ -45,8 +44,9 @@ public: static void Initialize(); static void Shutdown(); static constexpr zeus::CRectangle DefaultRect{0.f, 0.f, 1.f, 1.f}; - explicit CTexturedQuadFilter(EFilterType type, TLockedToken tex, ZTest zTest = ZTest::None); - explicit CTexturedQuadFilter(EFilterType type, const boo::ObjToken& tex, ZTest zTest = ZTest::None); + explicit CTexturedQuadFilter(EFilterType type, TLockedToken tex, ERglEnum zTest = ERglEnum::Never); + explicit CTexturedQuadFilter(EFilterType type, const aurora::gfx::TextureHandle& tex, + ERglEnum zTest = ERglEnum::Never); CTexturedQuadFilter(const CTexturedQuadFilter&) = delete; CTexturedQuadFilter& operator=(const CTexturedQuadFilter&) = delete; CTexturedQuadFilter(CTexturedQuadFilter&&) = default; @@ -56,7 +56,7 @@ public: void drawVerts(const zeus::CColor& color, std::array verts, float lod = 0.f); void DrawFilter(EFilterShape shape, const zeus::CColor& color, float t); const TLockedToken& GetTex() const { return m_tex; } - const boo::ObjToken& GetBooTex() const { return m_booTex; } + const aurora::gfx::TextureHandle& GetBooTex() const { return m_booTex; } }; class CTexturedQuadFilterAlpha : public CTexturedQuadFilter { @@ -64,7 +64,7 @@ public: static void Initialize(); static void Shutdown(); explicit CTexturedQuadFilterAlpha(EFilterType type, TLockedToken tex); - explicit CTexturedQuadFilterAlpha(EFilterType type, const boo::ObjToken& tex); + explicit CTexturedQuadFilterAlpha(EFilterType type, const aurora::gfx::TextureHandle& tex); }; } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp index 6aea09d9f..221f6be1c 100644 --- a/Runtime/Graphics/Shaders/CThermalColdFilter.cpp +++ b/Runtime/Graphics/Shaders/CThermalColdFilter.cpp @@ -1,46 +1,50 @@ #include "Runtime/Graphics/Shaders/CThermalColdFilter.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include #include namespace metaforce { -static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_Pipeline; -void CThermalColdFilter::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CThermalColdFilter{}); } +void CThermalColdFilter::Initialize() { +// s_Pipeline = hecl::conv->convert(Shader_CThermalColdFilter{}); +} -void CThermalColdFilter::Shutdown() { s_Pipeline.reset(); } +void CThermalColdFilter::Shutdown() { +// s_Pipeline.reset(); +} CThermalColdFilter::CThermalColdFilter() { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - struct Vert { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - zeus::CVector2f m_uvNoise; - }; - const std::array verts{{ - {{-1.f, -1.f}, {0.f, 0.f}, {0.f, 0.f}}, - {{-1.f, 1.f}, {0.f, 1.f}, {0.f, 448.f}}, - {{1.f, -1.f}, {1.f, 0.f}, {640.f, 0.f}}, - {{1.f, 1.f}, {1.f, 1.f}, {640.f, 448.f}}, - }}; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 48, verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 2> texs{ - CGraphics::g_SpareTexture.get(), - g_Renderer->GetRandomStaticEntropyTex(), - }; - m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// struct Vert { +// zeus::CVector2f m_pos; +// zeus::CVector2f m_uv; +// zeus::CVector2f m_uvNoise; +// }; +// const std::array verts{{ +// {{-1.f, -1.f}, {0.f, 0.f}, {0.f, 0.f}}, +// {{-1.f, 1.f}, {0.f, 1.f}, {0.f, 448.f}}, +// {{1.f, -1.f}, {1.f, 0.f}, {640.f, 0.f}}, +// {{1.f, 1.f}, {1.f, 1.f}, {640.f, 448.f}}, +// }}; +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 48, verts.size()); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 2> texs{ +// CGraphics::g_SpareTexture.get(), +// g_Renderer->GetRandomStaticEntropyTex(), +// }; +// m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); setNoiseOffset(0); setScale(0.f); @@ -49,10 +53,10 @@ CThermalColdFilter::CThermalColdFilter() { void CThermalColdFilter::draw() { SCOPED_GRAPHICS_DEBUG_GROUP("CThermalColdFilter::draw", zeus::skMagenta); - CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CThermalColdFilter.hpp b/Runtime/Graphics/Shaders/CThermalColdFilter.hpp index 122f60bc7..19c53dfaf 100644 --- a/Runtime/Graphics/Shaders/CThermalColdFilter.hpp +++ b/Runtime/Graphics/Shaders/CThermalColdFilter.hpp @@ -2,7 +2,7 @@ #include -#include +//#include #include #include @@ -15,9 +15,9 @@ class CThermalColdFilter { std::array m_colorRegs; float m_randOff = 0.f; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; public: diff --git a/Runtime/Graphics/Shaders/CThermalHotFilter.cpp b/Runtime/Graphics/Shaders/CThermalHotFilter.cpp index 02022b9cc..05eec49ce 100644 --- a/Runtime/Graphics/Shaders/CThermalHotFilter.cpp +++ b/Runtime/Graphics/Shaders/CThermalHotFilter.cpp @@ -1,56 +1,60 @@ #include "Runtime/Graphics/Shaders/CThermalHotFilter.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include #include namespace metaforce { -static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_Pipeline; -void CThermalHotFilter::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CThermalHotFilter{}); } +void CThermalHotFilter::Initialize() { +// s_Pipeline = hecl::conv->convert(Shader_CThermalHotFilter{}); +} -void CThermalHotFilter::Shutdown() { s_Pipeline.reset(); } +void CThermalHotFilter::Shutdown() { +// s_Pipeline.reset(); +} CThermalHotFilter::CThermalHotFilter() { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - struct Vert { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - }; - const std::array verts{{ - {{-1.0, -1.0}, {0.0, 0.0}}, - {{-1.0, 1.0}, {0.0, 1.0}}, - {{1.0, -1.0}, {1.0, 0.0}}, - {{1.0, 1.0}, {1.0, 1.0}}, - }}; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 2> texs{ - CGraphics::g_SpareTexture.get(), - g_Renderer->GetThermoPalette(), - }; - m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// struct Vert { +// zeus::CVector2f m_pos; +// zeus::CVector2f m_uv; +// }; +// const std::array verts{{ +// {{-1.0, -1.0}, {0.0, 0.0}}, +// {{-1.0, 1.0}, {0.0, 1.0}}, +// {{1.0, -1.0}, {1.0, 0.0}}, +// {{1.0, 1.0}, {1.0, 1.0}}, +// }}; +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size()); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 2> texs{ +// CGraphics::g_SpareTexture.get(), +// g_Renderer->GetThermoPalette(), +// }; +// m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); } void CThermalHotFilter::draw() { SCOPED_GRAPHICS_DEBUG_GROUP("CThermalHotFilter::draw", zeus::skMagenta); - CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); +// CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); // m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CThermalHotFilter.hpp b/Runtime/Graphics/Shaders/CThermalHotFilter.hpp index 2eb0d735b..74ba9416e 100644 --- a/Runtime/Graphics/Shaders/CThermalHotFilter.hpp +++ b/Runtime/Graphics/Shaders/CThermalHotFilter.hpp @@ -2,7 +2,7 @@ #include -#include +//#include #include @@ -12,9 +12,9 @@ class CThermalHotFilter { struct Uniform { std::array m_colorRegs; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; public: diff --git a/Runtime/Graphics/Shaders/CWorldShadowShader.cpp b/Runtime/Graphics/Shaders/CWorldShadowShader.cpp index 2004896ef..d5956ae53 100644 --- a/Runtime/Graphics/Shaders/CWorldShadowShader.cpp +++ b/Runtime/Graphics/Shaders/CWorldShadowShader.cpp @@ -5,42 +5,44 @@ #include "Runtime/Camera/CCameraFilter.hpp" #include "Runtime/Graphics/CGraphics.hpp" -#include +//#include #include namespace metaforce { -static boo::ObjToken s_Pipeline; -static boo::ObjToken s_ZPipeline; +//static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_ZPipeline; void CWorldShadowShader::Initialize() { - s_Pipeline = hecl::conv->convert(Shader_CWorldShadowShader{}); - s_ZPipeline = hecl::conv->convert(Shader_CWorldShadowShaderZ{}); +// s_Pipeline = hecl::conv->convert(Shader_CWorldShadowShader{}); +// s_ZPipeline = hecl::conv->convert(Shader_CWorldShadowShaderZ{}); } void CWorldShadowShader::Shutdown() { - s_Pipeline.reset(); - s_ZPipeline.reset(); +// s_Pipeline.reset(); +// s_ZPipeline.reset(); } CWorldShadowShader::CWorldShadowShader(u32 w, u32 h) : m_w(w), m_h(h) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 16, 4); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); - m_zDataBind = ctx.newShaderDataBinding(s_ZPipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); - - m_tex = ctx.newRenderTexture(m_w, m_h, boo::TextureClampMode::ClampToWhite, 1, 0); - return true; - } BooTrace); +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// m_vbo = ctx.newDynamicBuffer(boo::BufferUse::Vertex, 16, 4); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); +// m_zDataBind = ctx.newShaderDataBinding(s_ZPipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, 0, nullptr, nullptr, nullptr); +// +// m_tex = ctx.newRenderTexture(m_w, m_h, boo::TextureClampMode::ClampToWhite, 1, 0); +// return true; +// } BooTrace); } -void CWorldShadowShader::bindRenderTarget() { CGraphics::g_BooMainCommandQueue->setRenderTarget(m_tex); } +void CWorldShadowShader::bindRenderTarget() { +// CGraphics::g_BooMainCommandQueue->setRenderTarget(m_tex); +} void CWorldShadowShader::drawBase(float extent) { SCOPED_GRAPHICS_DEBUG_GROUP("CWorldShadowShader::drawBase", zeus::skMagenta); @@ -51,38 +53,38 @@ void CWorldShadowShader::drawBase(float extent) { {-extent, 0.f, -extent}, {extent, 0.f, -extent}, }}; - m_vbo->load(verts.data(), sizeof(verts)); +// m_vbo->load(verts.data(), sizeof(verts)); - m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(/*true*/) * CGraphics::g_GXModelView.toMatrix4f(); m_uniform.m_color = zeus::skWhite; - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - - CGraphics::SetShaderDataBinding(m_zDataBind); - CGraphics::DrawArray(0, 4); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// +// CGraphics::SetShaderDataBinding(m_zDataBind); +// CGraphics::DrawArray(0, 4); } void CWorldShadowShader::lightenShadow() { SCOPED_GRAPHICS_DEBUG_GROUP("CWorldShadowShader::lightenShadow", zeus::skMagenta); m_uniform.m_color = zeus::CColor(1.f, 0.25f); - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } void CWorldShadowShader::blendPreviousShadow() { SCOPED_GRAPHICS_DEBUG_GROUP("CWorldShadowShader::blendPreviousShadow", zeus::skMagenta); - if (!m_prevQuad) - m_prevQuad.emplace(EFilterType::Blend, m_tex.get()); - zeus::CRectangle rect(0.f, 1.f, 1.f, -1.f); - m_prevQuad->draw({1.f, 0.85f}, 1.f, rect); +// if (!m_prevQuad) +// m_prevQuad.emplace(EFilterType::Blend, m_tex); +// zeus::CRectangle rect(0.f, 1.f, 1.f, -1.f); +// m_prevQuad->draw({1.f, 0.85f}, 1.f, rect); } void CWorldShadowShader::resolveTexture() { - boo::SWindowRect rect = {0, 0, int(m_w), int(m_h)}; - CGraphics::g_BooMainCommandQueue->resolveBindTexture(m_tex, rect, false, 0, true, false, true); +// boo::SWindowRect rect = {0, 0, int(m_w), int(m_h)}; +// CGraphics::g_BooMainCommandQueue->resolveBindTexture(m_tex, rect, false, 0, true, false, true); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CWorldShadowShader.hpp b/Runtime/Graphics/Shaders/CWorldShadowShader.hpp index 98af3477c..4f649fa12 100644 --- a/Runtime/Graphics/Shaders/CWorldShadowShader.hpp +++ b/Runtime/Graphics/Shaders/CWorldShadowShader.hpp @@ -3,9 +3,8 @@ #include #include "Runtime/GCNTypes.hpp" -#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" -#include +//#include #include #include @@ -13,18 +12,18 @@ namespace metaforce { class CWorldShadowShader { - boo::ObjToken m_tex; - std::optional m_prevQuad; +// aurora::gfx::TextureHandle m_tex; +// std::optional m_prevQuad; u32 m_w, m_h; struct Uniform { zeus::CMatrix4f m_matrix; zeus::CColor m_color; }; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; - boo::ObjToken m_zDataBind; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; +// boo::ObjToken m_zDataBind; Uniform m_uniform; public: @@ -40,7 +39,7 @@ public: u32 GetWidth() const { return m_w; } u32 GetHeight() const { return m_h; } - const boo::ObjToken& GetTexture() const { return m_tex; } +// const aurora::gfx::TextureHandle& GetTexture() const { return m_tex; } }; } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp b/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp index bf39e9160..f34967fee 100644 --- a/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp +++ b/Runtime/Graphics/Shaders/CXRayBlurFilter.cpp @@ -4,48 +4,52 @@ #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include +//#include #include namespace metaforce { -static boo::ObjToken s_Pipeline; +//static boo::ObjToken s_Pipeline; -void CXRayBlurFilter::Initialize() { s_Pipeline = hecl::conv->convert(Shader_CXRayBlurFilter{}); } +void CXRayBlurFilter::Initialize() { +// s_Pipeline = hecl::conv->convert(Shader_CXRayBlurFilter{}); +} -void CXRayBlurFilter::Shutdown() { s_Pipeline.reset(); } +void CXRayBlurFilter::Shutdown() { +// s_Pipeline.reset(); +} -CXRayBlurFilter::CXRayBlurFilter(TLockedToken& tex) : m_paletteTex(tex), m_booTex(tex->GetPaletteTexture()) { - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - struct Vert { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - }; - const std::array verts{{ - {{-1.f, -1.f}, {0.f, 0.f}}, - {{-1.f, 1.f}, {0.f, 1.f}}, - {{1.f, -1.f}, {1.f, 0.f}}, - {{1.f, 1.f}, {1.f, 1.f}}, - }}; - m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size()); - m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); - - const std::array, 1> bufs{m_uniBuf.get()}; - constexpr std::array stages{boo::PipelineStage::Vertex}; - const std::array, 2> texs{ - CGraphics::g_SpareTexture.get(), - m_booTex, - }; - m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), - stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); - return true; - } BooTrace); +CXRayBlurFilter::CXRayBlurFilter(TLockedToken& tex) : m_paletteTex(tex) { // , m_booTex(tex->GetPaletteTexture()) +// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { +// struct Vert { +// zeus::CVector2f m_pos; +// zeus::CVector2f m_uv; +// }; +// const std::array verts{{ +// {{-1.f, -1.f}, {0.f, 0.f}}, +// {{-1.f, 1.f}, {0.f, 1.f}}, +// {{1.f, -1.f}, {1.f, 0.f}}, +// {{1.f, 1.f}, {1.f, 1.f}}, +// }}; +// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, verts.data(), 32, verts.size()); +// m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1); +// +// const std::array, 1> bufs{m_uniBuf.get()}; +// constexpr std::array stages{boo::PipelineStage::Vertex}; +// const std::array, 2> texs{ +// CGraphics::g_SpareTexture.get(), +// m_booTex, +// }; +// m_dataBind = ctx.newShaderDataBinding(s_Pipeline, m_vbo.get(), nullptr, nullptr, bufs.size(), bufs.data(), +// stages.data(), nullptr, nullptr, texs.size(), texs.data(), nullptr, nullptr); +// return true; +// } BooTrace); } void CXRayBlurFilter::draw(float amount) { SCOPED_GRAPHICS_DEBUG_GROUP("CXRayBlurFilter::draw", zeus::skMagenta); - CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); +// CGraphics::ResolveSpareTexture(CGraphics::g_CroppedViewport); const float blurL = amount * g_tweakGui->GetXrayBlurScaleLinear() * 0.25f; const float blurQ = amount * g_tweakGui->GetXrayBlurScaleQuadratic() * 0.25f; @@ -59,10 +63,10 @@ void CXRayBlurFilter::draw(float amount) { m_uniform.m_uv[i][3][0] = uvOffset; m_uniform.m_uv[i][3][1] = uvOffset; } - m_uniBuf->load(&m_uniform, sizeof(m_uniform)); - - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, 4); +// m_uniBuf->load(&m_uniform, sizeof(m_uniform)); +// +// CGraphics::SetShaderDataBinding(m_dataBind); +// CGraphics::DrawArray(0, 4); } } // namespace metaforce diff --git a/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp b/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp index 35104fa7b..86928529d 100644 --- a/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp +++ b/Runtime/Graphics/Shaders/CXRayBlurFilter.hpp @@ -3,8 +3,8 @@ #include #include "Runtime/CToken.hpp" +#include "Runtime/Graphics/CGraphics.hpp" -#include #include namespace metaforce { @@ -15,10 +15,10 @@ class CXRayBlurFilter { std::array m_uv; }; TLockedToken m_paletteTex; - boo::ObjToken m_booTex; - boo::ObjToken m_vbo; - boo::ObjToken m_uniBuf; - boo::ObjToken m_dataBind; +// aurora::gfx::TextureHandle m_booTex; +// boo::ObjToken m_vbo; +// boo::ObjToken m_uniBuf; +// boo::ObjToken m_dataBind; Uniform m_uniform; public: diff --git a/Runtime/GuiSys/CAuiEnergyBarT01.cpp b/Runtime/GuiSys/CAuiEnergyBarT01.cpp index e01285c93..f04696361 100644 --- a/Runtime/GuiSys/CAuiEnergyBarT01.cpp +++ b/Runtime/GuiSys/CAuiEnergyBarT01.cpp @@ -8,8 +8,9 @@ namespace metaforce { CAuiEnergyBarT01::CAuiEnergyBarT01(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId txtrId) : CGuiWidget(parms), xb8_txtrId(txtrId) { - if (g_GuiSys->GetUsageMode() != CGuiSys::EUsageMode::Two) + if (g_GuiSys->GetUsageMode() != CGuiSys::EUsageMode::Two) { xbc_tex = sp->GetObj(SObjectTag{FOURCC('TXTR'), xb8_txtrId}); + } } std::pair CAuiEnergyBarT01::DownloadBarCoordFunc(float t) { @@ -18,8 +19,9 @@ std::pair CAuiEnergyBarT01::DownloadBarCoordFu } void CAuiEnergyBarT01::Update(float dt) { - if (x100_shadowDrainDelayTimer > 0.f) + if (x100_shadowDrainDelayTimer > 0.f) { x100_shadowDrainDelayTimer = std::max(x100_shadowDrainDelayTimer - dt, 0.f); + } if (xf8_filledEnergy < xf4_setEnergy) { if (xf1_wrapping) { @@ -45,22 +47,24 @@ void CAuiEnergyBarT01::Update(float dt) { } } - if (xfc_shadowEnergy < xf8_filledEnergy) + if (xfc_shadowEnergy < xf8_filledEnergy) { xfc_shadowEnergy = xf8_filledEnergy; - else if (xfc_shadowEnergy > xf8_filledEnergy && x100_shadowDrainDelayTimer == 0.f) + } else if (xfc_shadowEnergy > xf8_filledEnergy && x100_shadowDrainDelayTimer == 0.f) { xfc_shadowEnergy = std::max(xf8_filledEnergy, xfc_shadowEnergy - dt * xe8_shadowSpeed); + } CGuiWidget::Update(dt); } void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) { - if (!xbc_tex || !xbc_tex.IsLoaded() || !xd8_coordFunc) { + CGraphics::SetModelMatrix(x34_worldXF); + if (!xbc_tex || !xbc_tex.IsLoaded() || xd8_coordFunc == nullptr) { return; } - SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CAuiEnergyBarT01::Draw {}"), m_name).c_str(), zeus::skCyan); - CGraphics::SetModelMatrix(x34_worldXF); - m_energyBarShader.updateModelMatrix(); + CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, false); + CGraphics::SetAmbientColor(zeus::skWhite); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear); const float filledT = xe0_maxEnergy > 0.f ? xf8_filledEnergy / xe0_maxEnergy : 0.f; const float shadowT = xe0_maxEnergy > 0.f ? xfc_shadowEnergy / xe0_maxEnergy : 0.f; @@ -77,60 +81,76 @@ void CAuiEnergyBarT01::Draw(const CGuiWidgetDrawParms& drawParms) { emptyColor.a() *= drawParms.x0_alphaMod; emptyColor *= xa8_color2; - for (size_t i = 0; i < m_verts.size(); ++i) { - std::vector& verts = m_verts[i]; - verts.clear(); - - float start; - float end; - switch (i) { - case 0: - default: - start = 0.f; - end = filledT; - break; - case 1: - start = filledT; - end = shadowT; - break; - case 2: - start = shadowT; - end = 1.f; - break; + zeus::CColor useCol = emptyColor; + for (u32 i = 0; i < 3; ++i) { + float barOffT; + if (i == 0) { + barOffT = 0.f; + } else if (i == 1) { + barOffT = filledT; + } else { + barOffT = shadowT; } - if (start == end) { - continue; + float barMaxT; + if (i == 0) { + barMaxT = filledT; + } else if (i == 1) { + barMaxT = shadowT; + } else { + barMaxT = 1.f; } - std::pair coords = xd8_coordFunc(start); - while (start < end) { - verts.push_back({coords.first, zeus::CVector2f(start, 0.f)}); - verts.push_back({coords.second, zeus::CVector2f(start, 1.f)}); - start += xdc_tesselation; - if (start >= end) { - coords = xd8_coordFunc(end); - verts.push_back({coords.first, zeus::CVector2f(end, 0.f)}); - verts.push_back({coords.second, zeus::CVector2f(end, 1.f)}); - } else { - coords = xd8_coordFunc(start); + if (i == 0) { + useCol = filledColor; + } else if (i == 1) { + useCol = shadowColor; + } else { + useCol = emptyColor; + } + + if (barOffT != barMaxT) { + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + xbc_tex->Load(GX_TEXMAP0, EClampMode::Repeat); + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamColor(useCol); + auto coords = xd8_coordFunc(barOffT); + while (barOffT < barMaxT) { + CGraphics::StreamTexcoord(barOffT, 0.f); + CGraphics::StreamVertex(coords.first); + CGraphics::StreamTexcoord(barOffT, 1.f); + CGraphics::StreamVertex(coords.second); + barOffT += xdc_tesselation; + if (barOffT < barMaxT) { + coords = xd8_coordFunc(barOffT); + } else { + coords = xd8_coordFunc(barMaxT); + CGraphics::StreamTexcoord(barMaxT, 0.f); + CGraphics::StreamVertex(coords.first); + CGraphics::StreamTexcoord(barMaxT, 1.f); + CGraphics::StreamVertex(coords.second); + } } + CGraphics::StreamEnd(); } } - - m_energyBarShader.draw(filledColor, m_verts[0], shadowColor, m_verts[1], emptyColor, m_verts[2], xbc_tex.GetObj()); + CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, true); } void CAuiEnergyBarT01::SetCurrEnergy(float e, ESetMode mode) { e = zeus::clamp(0.f, e, xe0_maxEnergy); - if (e == xf4_setEnergy) + if (e == xf4_setEnergy) { return; - if (xf0_alwaysResetDelayTimer || xf8_filledEnergy == xfc_shadowEnergy) + } + if (xf0_alwaysResetDelayTimer || xf8_filledEnergy == xfc_shadowEnergy) { x100_shadowDrainDelayTimer = xec_shadowDrainDelay; + } xf1_wrapping = mode == ESetMode::Wrapped; xf4_setEnergy = e; - if (mode == ESetMode::Insta) + if (mode == ESetMode::Insta) { xf8_filledEnergy = xf4_setEnergy; + } } void CAuiEnergyBarT01::SetMaxEnergy(float maxEnergy) { @@ -142,7 +162,7 @@ void CAuiEnergyBarT01::SetMaxEnergy(float maxEnergy) { std::shared_ptr CAuiEnergyBarT01::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - CAssetId tex = in.readUint32Big(); + auto tex = in.Get(); std::shared_ptr ret = std::make_shared(parms, sp, tex); ret->ParseBaseInfo(frame, in, parms); return ret; diff --git a/Runtime/GuiSys/CAuiEnergyBarT01.hpp b/Runtime/GuiSys/CAuiEnergyBarT01.hpp index 5c32ab1d7..2e5586eee 100644 --- a/Runtime/GuiSys/CAuiEnergyBarT01.hpp +++ b/Runtime/GuiSys/CAuiEnergyBarT01.hpp @@ -38,8 +38,6 @@ private: float xf8_filledEnergy = 0.f; float xfc_shadowEnergy = 0.f; float x100_shadowDrainDelayTimer = 0.f; - CEnergyBarShader m_energyBarShader; - std::array, 3> m_verts; public: CAuiEnergyBarT01(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId txtrId); diff --git a/Runtime/GuiSys/CAuiImagePane.cpp b/Runtime/GuiSys/CAuiImagePane.cpp index ed07313fb..870ca35fe 100644 --- a/Runtime/GuiSys/CAuiImagePane.cpp +++ b/Runtime/GuiSys/CAuiImagePane.cpp @@ -3,6 +3,7 @@ #include "Runtime/CSimplePool.hpp" #include "Runtime/Camera/CCameraFilter.hpp" #include "Runtime/Graphics/CTexture.hpp" +#include "Runtime/Graphics/CGX.hpp" #include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp" namespace metaforce { @@ -17,19 +18,19 @@ CAuiImagePane::CAuiImagePane(const CGuiWidgetParms& parms, CSimplePool* sp, CAss std::shared_ptr CAuiImagePane::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - in.readUint32Big(); - in.readUint32Big(); - in.readUint32Big(); - u32 coordCount = in.readUint32Big(); + in.ReadLong(); + in.ReadLong(); + in.ReadLong(); + u32 coordCount = in.ReadLong(); rstl::reserved_vector coords; for (u32 i = 0; i < coordCount; ++i) - coords.push_back(zeus::CVector3f::ReadBig(in)); - u32 uvCount = in.readUint32Big(); + coords.push_back(in.Get()); + u32 uvCount = in.ReadLong(); rstl::reserved_vector uvs; for (u32 i = 0; i < uvCount; ++i) - uvs.push_back(zeus::CVector2f::ReadBig(in)); + uvs.push_back(in.Get()); std::shared_ptr ret = - std::make_shared(parms, sp, -1, -1, std::move(coords), std::move(uvs), true); + std::make_shared(parms, sp, CAssetId(), CAssetId(), std::move(coords), std::move(uvs), true); ret->ParseBaseInfo(frame, in, parms); return ret; } @@ -51,53 +52,108 @@ void CAuiImagePane::Update(float dt) { CGuiWidget::Update(dt); } -CAuiImagePane::Filters::Filters(TLockedToken& tex) -: m_texId(tex.GetObjectTag()->id) -, m_darkenerQuad(EFilterType::Blend, tex) -, m_flashQuad{{CTexturedQuadFilterAlpha{EFilterType::Add, tex}, CTexturedQuadFilterAlpha{EFilterType::Add, tex}}} -, m_alphaQuad{{CTexturedQuadFilterAlpha{EFilterType::Blend, tex}, CTexturedQuadFilterAlpha{EFilterType::Blend, tex}}} -, m_addQuad{{CTexturedQuadFilterAlpha{EFilterType::Add, tex}, CTexturedQuadFilterAlpha{EFilterType::Add, tex}}} {} - -void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, const CTexture& tex, int frame, float alpha, bool noBlur, - CTexturedQuadFilterAlpha& quad) const { +void CAuiImagePane::DoDrawImagePane(const zeus::CColor& color, CTexture& tex, int frame, float alpha, + bool noBlur) const { zeus::CColor useColor = color; useColor.a() *= alpha; rstl::reserved_vector vec; const rstl::reserved_vector* useUVs; if (x138_tileSize != zeus::skZero2f) { - const zeus::CVector2f res(xb8_tex0Tok->GetWidth(), -xb8_tex0Tok->GetHeight()); + const zeus::CVector2f res(xb8_tex0Tok->GetWidth(), xb8_tex0Tok->GetHeight()); const zeus::CVector2f tmp = res / x138_tileSize; const zeus::CVector2f tmpRecip = x138_tileSize / res; const float x0 = tmpRecip.x() * static_cast(frame % static_cast(tmp.x())); const float x1 = x0 + tmpRecip.x(); const float y0 = tmpRecip.y() * static_cast(frame % static_cast(tmp.y())); - const float y1 = y0 + tmpRecip.y(); + const float y1 = y0 - tmpRecip.y(); vec.push_back(zeus::CVector2f(x0, y0)); vec.push_back(zeus::CVector2f(x0, y1)); - vec.push_back(zeus::CVector2f(x1, y1)); vec.push_back(zeus::CVector2f(x1, y0)); + vec.push_back(zeus::CVector2f(x1, y1)); useUVs = &vec; } else { useUVs = &x114_uvs; } - const std::array verts{{ - {xe0_coords[0], (*useUVs)[0] + xd0_uvBias0}, - {xe0_coords[1], (*useUVs)[1] + xd0_uvBias0}, - {xe0_coords[3], (*useUVs)[3] + xd0_uvBias0}, - {xe0_coords[2], (*useUVs)[2] + xd0_uvBias0}, - }}; + if (!noBlur) { + if ((x14c_deResFactor == 0.f && alpha == 1.f) || tex.GetNumberOfMipMaps() == 1) { + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + tex.LoadMipLevel(0, GX_TEXMAP0, EClampMode::Repeat); + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamColor(useColor); + for (u32 i = 0; i < useUVs->size(); ++i) { + CGraphics::StreamTexcoord((*useUVs)[i] + xd0_uvBias0); + CGraphics::StreamVertex(xe0_coords[i]); + } + CGraphics::StreamEnd(); + } else { + u32 mipCount = tex.GetNumberOfMipMaps() - 1; + float fadeFactor = (1.f - x14c_deResFactor) * alpha; + float fadeQ = -(fadeFactor * fadeFactor * fadeFactor - 1.f); + fadeFactor = fadeQ * static_cast(mipCount); + u32 mip1 = fadeFactor; + u32 mip2 = mip1; + if (fadeQ != static_cast(mip1 / mipCount)) { + mip2 = mip1 + 1; + } - if (noBlur) { - quad.drawVerts(useColor, verts); - } else if ((x14c_deResFactor == 0.f && alpha == 1.f) || tex.GetNumMips() == 1) { - quad.drawVerts(useColor, verts, 0.f); + float rgba1 = (fadeFactor - static_cast(mip1)); + float rgba2 = 1.f - rgba1; + tex.LoadMipLevel(mip1, GX_TEXMAP0, EClampMode::Repeat); + tex.LoadMipLevel(mip2, GX_TEXMAP1, EClampMode::Repeat); + std::array list{{ + {GX_VA_POS, GX_DIRECT}, + {GX_VA_TEX0, GX_DIRECT}, + {GX_VA_NULL, GX_NONE}, + }}; + + CGX::SetVtxDescv(list.data()); + CGX::SetNumChans(0); + CGX::SetNumTexGens(2); + CGX::SetNumTevStages(2); + GXTevStageID stage = GX_TEVSTAGE0; + while (stage < GX_TEVSTAGE2) { + GXTevColorArg colorD = stage == GX_TEVSTAGE0 ? GX_CC_ZERO : GX_CC_CPREV; + CGX::SetTevColorIn(stage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, colorD); + GXTevAlphaArg alphaD = stage == GX_TEVSTAGE0 ? GX_CA_ZERO : GX_CA_APREV; + CGX::SetTevAlphaIn(stage, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, alphaD); + CGX::SetTevColorOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + CGX::SetTevAlphaOp(stage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); + stage = static_cast(stage + GX_TEVSTAGE1); + } + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + CGX::SetTevKAlphaSel(GX_TEVSTAGE1, GX_TEV_KASEL_K1_A); + CGX::SetTevKColorSel(GX_TEVSTAGE1, GX_TEV_KCSEL_K1); + zeus::CColor col1 = useColor * zeus::CColor(rgba2, rgba2, rgba2, rgba2); + zeus::CColor col2 = useColor * zeus::CColor(rgba1, rgba1, rgba1, rgba1); + CGX::SetTevKColor(GX_KCOLOR0, col1); + CGX::SetTevKColor(GX_KCOLOR1, col2); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR_NULL); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); + for (u32 idx = 0; const auto& coord : xe0_coords) { + GXPosition3f32(coord); + GXTexCoord2f32((*useUVs)[idx] + xd0_uvBias0); + ++idx; + } + CGX::End(); + } } else { - const float tmp = (1.f - x14c_deResFactor) * alpha; - const float tmp3 = 1.f - tmp * tmp * tmp; - const float mip = tmp3 * static_cast(tex.GetNumMips() - 1); - quad.drawVerts(useColor, verts, mip); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulateAlpha); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + tex.Load(GX_TEXMAP0, EClampMode::Repeat); + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamColor(useColor); + for (u32 i = 0; i < useUVs->size(); ++i) { + CGraphics::StreamTexcoord((*useUVs)[i]); + CGraphics::StreamVertex(xe0_coords[i] + xd0_uvBias0); + } + CGraphics::StreamEnd(); } } @@ -108,13 +164,11 @@ void CAuiImagePane::Draw(const CGuiWidgetDrawParms& params) { } SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CAuiImagePane::Draw {}"), m_name).c_str(), zeus::skCyan); GetIsFinishedLoadingWidgetSpecific(); - if (!m_filters || m_filters->m_texId != xb8_tex0Tok.GetObjectTag()->id) { - m_filters.emplace(xb8_tex0Tok); - } - Filters& filters = *m_filters; zeus::CColor color = xa8_color2; color.a() *= params.x0_alphaMod; - // SetZUpdate(xac_drawFlags == EGuiModelDrawFlags::Shadeless || xac_drawFlags == EGuiModelDrawFlags::Opaque); + CGraphics::SetDepthWriteMode(true, ERglEnum::LEqual, + xac_drawFlags == EGuiModelDrawFlags::Shadeless || + xac_drawFlags == EGuiModelDrawFlags::Opaque); float blur0 = 1.f; float blur1 = 0.f; const int frame0 = static_cast(x144_frameTimer); @@ -130,46 +184,62 @@ void CAuiImagePane::Draw(const CGuiWidgetDrawParms& params) { } // Alpha blend - DoDrawImagePane(color * zeus::CColor(0.f, 0.5f), *xb8_tex0Tok, frame0, 1.f, true, filters.m_darkenerQuad); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + DoDrawImagePane(color * zeus::CColor(0.f, 0.5f), *xb8_tex0Tok, frame0, 1.f, true); if (x150_flashFactor > 0.f) { // Additive blend zeus::CColor color2 = xa8_color2; color2.a() = x150_flashFactor; - DoDrawImagePane(color2, *xb8_tex0Tok, frame0, blur0, false, filters.m_flashQuad[0]); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear); + DoDrawImagePane(color2, *xb8_tex0Tok, frame0, blur0, false); if (blur1 > 0.f) - DoDrawImagePane(color2, *xb8_tex0Tok, frame1, blur1, false, filters.m_flashQuad[1]); + DoDrawImagePane(color2, *xb8_tex0Tok, frame1, blur1, false); } switch (xac_drawFlags) { case EGuiModelDrawFlags::Shadeless: case EGuiModelDrawFlags::Opaque: // Opaque blend - DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false, filters.m_alphaQuad[0]); - if (blur1 > 0.f) - DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false, filters.m_alphaQuad[1]); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false); + if (blur1 > 0.f) { + DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false); + } break; case EGuiModelDrawFlags::Alpha: // Alpha blend - DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false, filters.m_alphaQuad[0]); - if (blur1 > 0.f) - DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false, filters.m_alphaQuad[1]); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false); + if (blur1 > 0.f) { + DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false); + } break; case EGuiModelDrawFlags::Additive: // Additive blend - DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false, filters.m_addQuad[0]); - if (blur1 > 0.f) - DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false, filters.m_addQuad[1]); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear); + DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false); + if (blur1 > 0.f) { + DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false); + } break; case EGuiModelDrawFlags::AlphaAdditiveOverdraw: // Alpha blend - DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false, filters.m_alphaQuad[0]); - if (blur1 > 0.f) - DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false, filters.m_alphaQuad[1]); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false); + if (blur1 > 0.f) { + DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false); + } // Full additive blend - DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false, filters.m_addQuad[0]); - if (blur1 > 0.f) - DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false, filters.m_addQuad[1]); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::One, ERglLogicOp::Clear); + DoDrawImagePane(color, *xb8_tex0Tok, frame0, blur0, false); + if (blur1 > 0.f) { + DoDrawImagePane(color, *xb8_tex0Tok, frame1, blur1, false); + } break; default: break; diff --git a/Runtime/GuiSys/CAuiImagePane.hpp b/Runtime/GuiSys/CAuiImagePane.hpp index a27a44500..6f256bbc7 100644 --- a/Runtime/GuiSys/CAuiImagePane.hpp +++ b/Runtime/GuiSys/CAuiImagePane.hpp @@ -4,7 +4,6 @@ #include "Runtime/CToken.hpp" #include "Runtime/rstl.hpp" -#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" #include "Runtime/GuiSys/CGuiWidget.hpp" #include @@ -32,17 +31,7 @@ class CAuiImagePane : public CGuiWidget { float x148_fadeDuration = 0.f; float x14c_deResFactor = 0.f; float x150_flashFactor = 0.f; - struct Filters { - CAssetId m_texId; - CTexturedQuadFilterAlpha m_darkenerQuad; - std::array m_flashQuad; - std::array m_alphaQuad; - std::array m_addQuad; - explicit Filters(TLockedToken& tex); - }; - std::optional m_filters; - void DoDrawImagePane(const zeus::CColor& color, const CTexture& tex, int frame, float blurAmt, bool noBlur, - CTexturedQuadFilterAlpha& quad) const; + void DoDrawImagePane(const zeus::CColor& color, CTexture& tex, int frame, float blurAmt, bool noBlur) const; public: CAuiImagePane(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId, CAssetId, diff --git a/Runtime/GuiSys/CAuiMeter.cpp b/Runtime/GuiSys/CAuiMeter.cpp index 5addf96dd..68e4c08d8 100644 --- a/Runtime/GuiSys/CAuiMeter.cpp +++ b/Runtime/GuiSys/CAuiMeter.cpp @@ -89,10 +89,10 @@ bool CAuiMeter::AddWorkerWidget(CGuiWidget* worker) { std::shared_ptr CAuiMeter::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - in.readBool(); - bool noRoundUp = in.readBool(); - u32 maxCapacity = in.readUint32Big(); - u32 workerCount = in.readUint32Big(); + in.ReadBool(); + bool noRoundUp = in.ReadBool(); + u32 maxCapacity = in.ReadLong(); + u32 workerCount = in.ReadLong(); std::shared_ptr ret = std::make_shared(parms, noRoundUp, maxCapacity, workerCount); ret->ParseBaseInfo(frame, in, parms); return ret; diff --git a/Runtime/GuiSys/CCompoundTargetReticle.cpp b/Runtime/GuiSys/CCompoundTargetReticle.cpp index fb3c972f7..f19fbb48b 100644 --- a/Runtime/GuiSys/CCompoundTargetReticle.cpp +++ b/Runtime/GuiSys/CCompoundTargetReticle.cpp @@ -70,15 +70,15 @@ CCompoundTargetReticle::CCompoundTargetReticle(const CStateManager& mgr) } CCompoundTargetReticle::SScanReticuleRenderer::SScanReticuleRenderer() { - CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { - for (size_t i = 0; i < m_lineRenderers.size(); ++i) { - m_lineRenderers[i].emplace(ctx, CLineRenderer::EPrimitiveMode::Lines, 8, nullptr, true, true); - for (auto& stripRenderer : m_stripRenderers[i]) { - stripRenderer.emplace(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true, true); - } - } - return true; - } BooTrace); +// CGraphics::CommitResources([this](boo::IGraphicsDataFactory::Context& ctx) { +// for (size_t i = 0; i < m_lineRenderers.size(); ++i) { +// m_lineRenderers[i].emplace(CLineRenderer::EPrimitiveMode::Lines, 8, {}, true, true); +// for (auto& stripRenderer : m_stripRenderers[i]) { +// stripRenderer.emplace(CLineRenderer::EPrimitiveMode::LineStrip, 4, {}, true, true); +// } +// } +// return true; +// } BooTrace); } CCompoundTargetReticle::EReticleState CCompoundTargetReticle::GetDesiredReticleState(const CStateManager& mgr) const { @@ -502,7 +502,7 @@ void CCompoundTargetReticle::Draw(const CStateManager& mgr, bool hideLockon) { } void CCompoundTargetReticle::DrawGrapplePoint(const CScriptGrapplePoint& point, float t, const CStateManager& mgr, - const zeus::CMatrix3f& rot, bool zEqual) const { + const zeus::CMatrix3f& rot, bool zEqual) { zeus::CVector3f orbitPos = point.GetOrbitPosition(mgr); zeus::CColor color; @@ -524,7 +524,7 @@ void CCompoundTargetReticle::DrawGrapplePoint(const CScriptGrapplePoint& point, } void CCompoundTargetReticle::DrawGrappleGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr, - bool hideLockon) const { + bool hideLockon) { if (x28_noDrawTicks > 0) { return; } @@ -569,7 +569,7 @@ void CCompoundTargetReticle::DrawGrappleGroup(const zeus::CMatrix3f& rot, const } } -void CCompoundTargetReticle::DrawCurrLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) const { +void CCompoundTargetReticle::DrawCurrLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) { if (x28_noDrawTicks > 0) { return; } @@ -677,7 +677,7 @@ void CCompoundTargetReticle::DrawCurrLockOnGroup(const zeus::CMatrix3f& rot, con 1.f / x10c_currGroupInterp.GetFactor() * g_tweakTargeting->GetOuterBeamSquaresScale()); zeus::CMatrix3f outerBeamXf = rot * scale; for (int i = 0; i < 9; ++i) { - const SOuterItemInfo& info = xe0_outerBeamIconSquares[i]; + SOuterItemInfo& info = xe0_outerBeamIconSquares[i]; if (info.x0_model.IsLoaded()) { zeus::CTransform modelXf(lockBreakXf * outerBeamXf * zeus::CMatrix3f::RotateY(info.x10_rotAng), x10c_currGroupInterp.GetTargetPositionWorld()); @@ -925,7 +925,7 @@ void CCompoundTargetReticle::DrawNextLockOnGroup(const zeus::CMatrix3f& rot, con } } -void CCompoundTargetReticle::DrawOrbitZoneGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) const { +void CCompoundTargetReticle::DrawOrbitZoneGroup(const zeus::CMatrix3f& rot, const CStateManager& mgr) { if (x28_noDrawTicks > 0) { return; } diff --git a/Runtime/GuiSys/CCompoundTargetReticle.hpp b/Runtime/GuiSys/CCompoundTargetReticle.hpp index 6742e7eb8..5273d69fa 100644 --- a/Runtime/GuiSys/CCompoundTargetReticle.hpp +++ b/Runtime/GuiSys/CCompoundTargetReticle.hpp @@ -133,7 +133,7 @@ private: SScanReticuleRenderer m_scanRetRenderer; void DrawGrapplePoint(const CScriptGrapplePoint& point, float t, const CStateManager& mgr, const zeus::CMatrix3f& rot, - bool zEqual) const; + bool zEqual); public: explicit CCompoundTargetReticle(const CStateManager&); @@ -146,10 +146,10 @@ public: void UpdateNextLockOnGroup(float, const CStateManager&); void UpdateOrbitZoneGroup(float, const CStateManager&); void Draw(const CStateManager&, bool hideLockon); - void DrawGrappleGroup(const zeus::CMatrix3f& rot, const CStateManager&, bool) const; - void DrawCurrLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager&) const; + void DrawGrappleGroup(const zeus::CMatrix3f& rot, const CStateManager&, bool); + void DrawCurrLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager&); void DrawNextLockOnGroup(const zeus::CMatrix3f& rot, const CStateManager&); - void DrawOrbitZoneGroup(const zeus::CMatrix3f& rot, const CStateManager&) const; + void DrawOrbitZoneGroup(const zeus::CMatrix3f& rot, const CStateManager&); void UpdateTargetParameters(CTargetReticleRenderState&, const CStateManager&); float CalculateRadiusWorld(const CActor&, const CStateManager&) const; zeus::CVector3f CalculatePositionWorld(const CActor&, const CStateManager&) const; diff --git a/Runtime/GuiSys/CGuiCamera.cpp b/Runtime/GuiSys/CGuiCamera.cpp index b5ade0c7f..5bc971cec 100644 --- a/Runtime/GuiSys/CGuiCamera.cpp +++ b/Runtime/GuiSys/CGuiCamera.cpp @@ -18,8 +18,8 @@ zeus::CVector3f CGuiCamera::ConvertToScreenSpace(const zeus::CVector3f& vec) con if (local.isZero()) return {-1.f, -1.f, 1.f}; - zeus::CMatrix4f mat = CGraphics::CalculatePerspectiveMatrix(m_proj.xbc_fov, m_proj.xc0_aspect, m_proj.xc4_znear, - m_proj.xc8_zfar, false); + zeus::CMatrix4f mat = + CGraphics::CalculatePerspectiveMatrix(m_proj.xbc_fov, m_proj.xc0_aspect, m_proj.xc4_znear, m_proj.xc8_zfar); local = zeus::CVector3f(local.x(), local.z(), -local.y()); return mat.multiplyOneOverW(local); } @@ -38,24 +38,24 @@ void CGuiCamera::Draw(const CGuiWidgetDrawParms& parms) { std::shared_ptr CGuiCamera::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - EProjection proj = EProjection(in.readUint32Big()); + EProjection proj = EProjection(in.ReadLong()); std::shared_ptr ret = {}; switch (proj) { case EProjection::Perspective: { - float fov = in.readFloatBig(); - float aspect = in.readFloatBig(); - float znear = in.readFloatBig(); - float zfar = in.readFloatBig(); + float fov = in.ReadFloat(); + float aspect = in.ReadFloat(); + float znear = in.ReadFloat(); + float zfar = in.ReadFloat(); ret = std::make_shared(parms, fov, aspect, znear, zfar); break; } case EProjection::Orthographic: { - float left = in.readFloatBig(); - float right = in.readFloatBig(); - float top = in.readFloatBig(); - float bottom = in.readFloatBig(); - float znear = in.readFloatBig(); - float zfar = in.readFloatBig(); + float left = in.ReadFloat(); + float right = in.ReadFloat(); + float top = in.ReadFloat(); + float bottom = in.ReadFloat(); + float znear = in.ReadFloat(); + float zfar = in.ReadFloat(); ret = std::make_shared(parms, left, right, top, bottom, znear, zfar); break; } diff --git a/Runtime/GuiSys/CGuiFrame.cpp b/Runtime/GuiSys/CGuiFrame.cpp index e7186b17e..f8c6d98ef 100644 --- a/Runtime/GuiSys/CGuiFrame.cpp +++ b/Runtime/GuiSys/CGuiFrame.cpp @@ -44,43 +44,34 @@ void CGuiFrame::SortDrawOrder() { }); } -void CGuiFrame::EnableLights(u32 lights, CBooModel& model) const { - std::vector lightsOut; - lightsOut.reserve(m_indexedLights.size() + 1); +void CGuiFrame::EnableLights(ERglLight lights) const { CGraphics::DisableAllLights(); zeus::CColor ambColor(zeus::skBlack); - ERglLight lightId = ERglLight::Zero; - int idx = 0; + ERglLight lightId = 0; + int enabledLights = 0; for (CGuiLight* light : m_indexedLights) { - if (!light || !light->GetIsVisible()) { - ++reinterpret_cast&>(lightId); - ++idx; + if (light == nullptr || !light->GetIsVisible()) { + ++lightId; continue; } - if ((lights & (1 << idx)) != 0) { - // const zeus::CColor& geomCol = light->GetGeometryColor(); - // if (geomCol.r || geomCol.g || geomCol.b) - //{ - // CGraphics::LoadLight(lightId, light->BuildLight()); - lightsOut.push_back(light->BuildLight()); - CGraphics::EnableLight(lightId); - //} + if ((lights & (1 << lightId)) != 0) { + const auto& geomCol = light->GetGeometryColor(); + if (geomCol.r() != 0.f || geomCol.g() != 0.f || geomCol.b() != 0.f) { + CGraphics::LoadLight(lightId, light->BuildLight()); + CGraphics::EnableLight(lightId); + } // accumulate ambient color ambColor += light->GetAmbientLightColor(); + ++enabledLights; } - ++reinterpret_cast&>(lightId); - ++idx; + ++lightId; } - if (lightsOut.empty()) { - // CGraphics::SetAmbientColor(zeus::skWhite); - lightsOut.push_back(CLight::BuildLocalAmbient(zeus::skZero3f, zeus::skWhite)); + if (enabledLights == 0) { + CGraphics::SetAmbientColor(zeus::skWhite); } else { - // CGraphics::SetAmbientColor(ambColor); - lightsOut.push_back(CLight::BuildLocalAmbient(zeus::skZero3f, ambColor)); + CGraphics::SetAmbientColor(ambColor); } - - model.ActivateLights(lightsOut); } void CGuiFrame::DisableLights() const { CGraphics::DisableAllLights(); } @@ -133,10 +124,11 @@ void CGuiFrame::Update(float dt) { xc_headWidget->Update(dt); } void CGuiFrame::Draw(const CGuiWidgetDrawParms& parms) const { SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CGuiFrame::Draw FRME_{}"), x0_id).c_str(), zeus::skMagenta); CGraphics::SetCullMode(ERglCullMode::None); + CGraphics::ResetGfxStates(); CGraphics::SetAmbientColor(zeus::skWhite); DisableLights(); x14_camera->Draw(parms); - // Set one-stage modulate + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear); @@ -149,7 +141,7 @@ void CGuiFrame::Draw(const CGuiWidgetDrawParms& parms) const { CGuiWidget* CGuiFrame::BestCursorHit(const zeus::CVector2f& point, const CGuiWidgetDrawParms& parms) const { x14_camera->Draw(parms); - zeus::CMatrix4f vp = CGraphics::GetPerspectiveProjectionMatrix(false) * CGraphics::g_CameraMatrix.toMatrix4f(); + zeus::CMatrix4f vp = CGraphics::GetPerspectiveProjectionMatrix() * CGraphics::g_CameraMatrix.toMatrix4f(); CGuiWidget* ret = nullptr; for (const auto& widget : x2c_widgets) if (widget->GetMouseActive() && widget->TestCursorHit(vp, point)) @@ -163,15 +155,14 @@ void CGuiFrame::Initialize() { xc_headWidget->DispatchInitialize(); } -void CGuiFrame::LoadWidgetsInGame(CInputStream& in, CSimplePool* sp) { - u32 count = in.readUint32Big(); +void CGuiFrame::LoadWidgetsInGame(CInputStream& in, CSimplePool* sp, u32 version) { + u32 count = in.ReadLong(); x2c_widgets.reserve(count); for (u32 i = 0; i < count; ++i) { - DataSpec::DNAFourCC type; - type.read(in); - std::shared_ptr widget = CGuiSys::CreateWidgetInGame(type, in, this, sp); - type = widget->GetWidgetTypeID(); - switch (type.toUint32()) { + FourCC type; + in.Get(reinterpret_cast(&type), 4); + std::shared_ptr widget = CGuiSys::CreateWidgetInGame(type.toUint32(), in, this, sp, version); + switch (widget->GetWidgetTypeID().toUint32()) { case SBIG('CAMR'): case SBIG('LITE'): case SBIG('BGND'): @@ -217,7 +208,7 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw m_lastMouseOverWidget = hit; } if (hit && hit->m_lastScroll) { - boo::SScrollDelta delta = kbm->m_accumScroll - *hit->m_lastScroll; + SScrollDelta delta = kbm->m_accumScroll - *hit->m_lastScroll; hit->m_lastScroll.emplace(kbm->m_accumScroll); if (!delta.isZero()) { hit->m_integerScroll += delta; @@ -227,7 +218,7 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw hit->m_integerScroll.delta[1] -= std::trunc(hit->m_integerScroll.delta[1]); } } - if (!m_inMouseDown && kbm->m_mouseButtons[size_t(boo::EMouseButton::Primary)]) { + if (!m_inMouseDown && kbm->m_mouseButtons[size_t(EMouseButton::Primary)]) { m_inMouseDown = true; m_inCancel = false; m_mouseDownWidget = hit; @@ -235,7 +226,7 @@ bool CGuiFrame::ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDraw m_mouseDownCb(hit, false); if (hit) return true; - } else if (m_inMouseDown && !kbm->m_mouseButtons[size_t(boo::EMouseButton::Primary)]) { + } else if (m_inMouseDown && !kbm->m_mouseButtons[size_t(EMouseButton::Primary)]) { m_inMouseDown = false; m_inCancel = false; if (m_mouseDownWidget == m_lastMouseOverWidget) { @@ -264,13 +255,13 @@ void CGuiFrame::ResetMouseState() { } std::unique_ptr CGuiFrame::CreateFrame(CAssetId frmeId, CGuiSys& sys, CInputStream& in, CSimplePool* sp) { - in.readInt32Big(); - int a = in.readInt32Big(); - int b = in.readInt32Big(); - int c = in.readInt32Big(); + u32 version = in.ReadLong(); + int a = in.ReadLong(); + int b = in.ReadLong(); + int c = in.ReadLong(); std::unique_ptr ret = std::make_unique(frmeId, sys, a, b, c, sp); - ret->LoadWidgetsInGame(in, sp); + ret->LoadWidgetsInGame(in, sp, version); return ret; } diff --git a/Runtime/GuiSys/CGuiFrame.hpp b/Runtime/GuiSys/CGuiFrame.hpp index 12c32bce7..2482a440c 100644 --- a/Runtime/GuiSys/CGuiFrame.hpp +++ b/Runtime/GuiSys/CGuiFrame.hpp @@ -9,11 +9,9 @@ #include "Runtime/GuiSys/CGuiHeadWidget.hpp" #include "Runtime/GuiSys/CGuiWidgetIdDB.hpp" #include "Runtime/GuiSys/CGuiWidget.hpp" - -#include +#include "Runtime/Graphics/CGraphics.hpp" namespace metaforce { -class CBooModel; class CGuiCamera; class CGuiLight; class CGuiSys; @@ -54,7 +52,7 @@ private: std::function m_mouseOverChangeCb; std::function m_mouseDownCb; std::function m_mouseUpCb; - std::function m_mouseScrollCb; + std::function m_mouseScrollCb; public: CGuiFrame(CAssetId id, CGuiSys& sys, int a, int b, int c, CSimplePool* sp); @@ -72,7 +70,7 @@ public: void SetHeadWidget(std::shared_ptr&& hwig) { xc_headWidget = std::move(hwig); } CGuiHeadWidget* GetHeadWidget() const { return xc_headWidget.get(); } void SortDrawOrder(); - void EnableLights(u32 lights, CBooModel& model) const; + void EnableLights(ERglLight lights) const; void DisableLights() const; void RemoveLight(CGuiLight* light); void AddLight(CGuiLight* light); @@ -87,7 +85,7 @@ public: } void SetMouseDownCallback(std::function&& cb) { m_mouseDownCb = std::move(cb); } void SetMouseUpCallback(std::function&& cb) { m_mouseUpCb = std::move(cb); } - void SetMouseScrollCallback(std::function&& cb) { + void SetMouseScrollCallback(std::function&& cb) { m_mouseScrollCb = std::move(cb); } @@ -96,7 +94,7 @@ public: void Draw(const CGuiWidgetDrawParms& parms) const; CGuiWidget* BestCursorHit(const zeus::CVector2f& point, const CGuiWidgetDrawParms& parms) const; void Initialize(); - void LoadWidgetsInGame(CInputStream& in, CSimplePool* sp); + void LoadWidgetsInGame(CInputStream& in, CSimplePool* sp, u32 version); void ProcessUserInput(const CFinalInput& input) const; bool ProcessMouseInput(const CFinalInput& input, const CGuiWidgetDrawParms& parms); void ResetMouseState(); diff --git a/Runtime/GuiSys/CGuiGroup.cpp b/Runtime/GuiSys/CGuiGroup.cpp index 105387c3d..ac8e31d8a 100644 --- a/Runtime/GuiSys/CGuiGroup.cpp +++ b/Runtime/GuiSys/CGuiGroup.cpp @@ -43,8 +43,8 @@ void CGuiGroup::OnActiveChange() { std::shared_ptr CGuiGroup::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - s16 defaultWorker = in.readInt16Big(); - bool b = in.readBool(); + s16 defaultWorker = in.ReadInt16(); + bool b = in.ReadBool(); std::shared_ptr ret = std::make_shared(parms, defaultWorker, b); ret->ParseBaseInfo(frame, in, parms); return ret; diff --git a/Runtime/GuiSys/CGuiLight.cpp b/Runtime/GuiSys/CGuiLight.cpp index c65166b55..d326f027e 100644 --- a/Runtime/GuiSys/CGuiLight.cpp +++ b/Runtime/GuiSys/CGuiLight.cpp @@ -50,19 +50,19 @@ void CGuiLight::SetIsVisible(bool vis) { std::shared_ptr CGuiLight::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - ELightType tp = ELightType(in.readUint32Big()); - float distC = in.readFloatBig(); - float distL = in.readFloatBig(); - float distQ = in.readFloatBig(); - float angC = in.readFloatBig(); - float angL = in.readFloatBig(); - float angQ = in.readFloatBig(); - u32 lightId = in.readUint32Big(); + ELightType tp = ELightType(in.ReadLong()); + float distC = in.ReadFloat(); + float distL = in.ReadFloat(); + float distQ = in.ReadFloat(); + float angC = in.ReadFloat(); + float angL = in.ReadFloat(); + float angQ = in.ReadFloat(); + u32 lightId = in.ReadLong(); std::shared_ptr ret = {}; switch (tp) { case ELightType::Spot: { - float cutoff = in.readFloatBig(); + float cutoff = in.ReadFloat(); CLight lt = CLight::BuildSpot(zeus::skZero3f, zeus::skZero3f, parms.x10_color, cutoff); lt.SetAttenuation(distC, distL, distQ); lt.SetAngleAttenuation(angC, angL, angQ); diff --git a/Runtime/GuiSys/CGuiModel.cpp b/Runtime/GuiSys/CGuiModel.cpp index 8ea304413..b23ac59ab 100644 --- a/Runtime/GuiSys/CGuiModel.cpp +++ b/Runtime/GuiSys/CGuiModel.cpp @@ -10,9 +10,9 @@ namespace metaforce { CGuiModel::CGuiModel(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId modelId, u32 lightMask, bool flag) : CGuiWidget(parms), xc8_modelId(modelId), xcc_lightMask(lightMask) { - if (!flag || !modelId.IsValid() || parms.x0_frame->GetGuiSys().GetUsageMode() == CGuiSys::EUsageMode::Two) + if (!flag || !modelId.IsValid() || parms.x0_frame->GetGuiSys().GetUsageMode() == CGuiSys::EUsageMode::Two) { return; - + } xb8_model = sp->GetObj({SBIG('CMDL'), modelId}); } @@ -23,18 +23,14 @@ bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() { if (!xb8_model.IsLoaded()) { return false; } - xb8_model->GetInstance().Touch(0); + xb8_model->Touch(0); return xb8_model->IsLoaded(0); } void CGuiModel::Touch() { - CModel* const model = xb8_model.GetObj(); - - if (model == nullptr) { - return; + if (CModel* const model = xb8_model.GetObj()) { + model->Touch(0); } - - model->GetInstance().Touch(0); } void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) { @@ -46,7 +42,7 @@ void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) { return; } CModel* const model = xb8_model.GetObj(); - if (!model) { + if (model == nullptr) { return; } @@ -54,58 +50,48 @@ void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) { SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(FMT_STRING("CGuiModel::Draw {}"), m_name).c_str(), zeus::skCyan); zeus::CColor moduCol = xa8_color2; moduCol.a() *= parms.x0_alphaMod; - xb0_frame->EnableLights(xcc_lightMask, model->GetInstance()); - // if (xb6_29_cullFaces) - // CGraphics::SetCullMode(ERglCullMode::Front); + xb0_frame->EnableLights(xcc_lightMask); + if (xb6_29_cullFaces) { + CGraphics::SetCullMode(ERglCullMode::Front); + } switch (xac_drawFlags) { case EGuiModelDrawFlags::Shadeless: { - CModelFlags flags(0, 0, 3, zeus::skWhite); - flags.m_extendedShader = EExtendedShader::Flat; + constexpr CModelFlags flags(0, 0, 3, zeus::skWhite); model->Draw(flags); break; } case EGuiModelDrawFlags::Opaque: { CModelFlags flags(1, 0, 3, moduCol); - flags.m_extendedShader = EExtendedShader::Lighting; model->Draw(flags); break; } case EGuiModelDrawFlags::Alpha: { CModelFlags flags(5, 0, (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest), moduCol); - flags.m_noCull = !xb6_29_cullFaces; - flags.m_noZWrite = !xb7_24_depthWrite; model->Draw(flags); break; } case EGuiModelDrawFlags::Additive: { CModelFlags flags(7, 0, (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest), moduCol); - flags.m_noCull = !xb6_29_cullFaces; - flags.m_noZWrite = !xb7_24_depthWrite; - flags.m_depthGreater = xb6_30_depthGreater; model->Draw(flags); break; } case EGuiModelDrawFlags::AlphaAdditiveOverdraw: { - CModelFlags flags(5, 0, xb6_31_depthTest, moduCol); - flags.m_noCull = !xb6_29_cullFaces; - flags.m_noZWrite = !xb7_24_depthWrite; + const CModelFlags flags(5, 0, (u32(xb6_30_depthGreater) << 4) | u32(xb6_31_depthTest), moduCol); model->Draw(flags); - flags.x0_blendMode = 7; - flags.x1_matSetIdx = 0; - flags.x2_flags = (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest); - flags.x4_color = moduCol; - flags.m_noCull = !xb6_29_cullFaces; - model->Draw(flags); + const CModelFlags overdrawFlags( + 8, 0, (u32(xb6_30_depthGreater) << 4) | (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest), moduCol); + model->Draw(overdrawFlags); break; } default: break; } - // if (xb6_29_cullFaces) - // CGraphics::SetCullMode(ERglCullMode::None); + if (xb6_29_cullFaces) { + CGraphics::SetCullMode(ERglCullMode::None); + } xb0_frame->DisableLights(); } @@ -113,17 +99,18 @@ void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) { } bool CGuiModel::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const { - if (!xb8_model || !xb8_model.IsLoaded()) + if (!xb8_model || !xb8_model.IsLoaded()) { return false; + } return xb8_model->GetAABB().projectedPointTest(vp * x34_worldXF.toMatrix4f(), point); } std::shared_ptr CGuiModel::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - CAssetId model = in.readUint32Big(); - in.readUint32Big(); - u32 lightMask = in.readUint32Big(); + auto model = in.Get(); + in.ReadLong(); + u32 lightMask = in.ReadLong(); std::shared_ptr ret = std::make_shared(parms, sp, model, lightMask, true); ret->ParseBaseInfo(frame, in, parms); diff --git a/Runtime/GuiSys/CGuiPane.cpp b/Runtime/GuiSys/CGuiPane.cpp index fcee45b6d..f9640f03b 100644 --- a/Runtime/GuiSys/CGuiPane.cpp +++ b/Runtime/GuiSys/CGuiPane.cpp @@ -1,4 +1,7 @@ #include "Runtime/GuiSys/CGuiPane.hpp" +#include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp" + +#include "Runtime/Graphics/CGraphics.hpp" namespace metaforce { @@ -7,40 +10,52 @@ CGuiPane::CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, con CGuiPane::InitializeBuffers(); } +void CGuiPane::Draw(const CGuiWidgetDrawParms& parms) { + CGraphics::SetModelMatrix(x34_worldXF * zeus::CTransform::Translate(xc8_scaleCenter)); + if (GetIsVisible()) { + auto col = xa8_color2; + col.a() = parms.x0_alphaMod * xa8_color2.a(); + + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvPassthru); + CGraphics::DrawPrimitive(GX_TRIANGLESTRIP, xc0_verts.data(), skDefaultNormal, col, xc0_verts.size()); + } + CGuiWidget::Draw(parms); +} void CGuiPane::ScaleDimensions(const zeus::CVector3f& scale) { InitializeBuffers(); - - for (TexShaderVert& v : xc0_verts) { - v.m_pos -= xc8_scaleCenter; - v.m_pos *= scale; - v.m_pos += xc8_scaleCenter; + for (auto& vert : xc0_verts) { + vert -= xc8_scaleCenter; + vert *= scale; + vert += xc8_scaleCenter; } } -void CGuiPane::SetDimensions(const zeus::CVector2f& dim, bool initVBO) { +void CGuiPane::SetDimensions(const zeus::CVector2f& dim, bool initBuffers) { xb8_dim = dim; - if (initVBO) + if (initBuffers) InitializeBuffers(); } zeus::CVector2f CGuiPane::GetDimensions() const { return xb8_dim; } void CGuiPane::InitializeBuffers() { - if (xc0_verts.size() < 4) - xc0_verts.resize(4); - - xc0_verts[0].m_pos.assign(-xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f); - xc0_verts[1].m_pos.assign(-xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f); - xc0_verts[2].m_pos.assign(xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f); - xc0_verts[3].m_pos.assign(xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f); +#if 0 + if (xc0_verts == nullptr) { + xc0_verts = new float[3 * 4]; + } +#endif + xc0_verts[0].assign(-xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f); + xc0_verts[1].assign(-xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f); + xc0_verts[2].assign(xb8_dim.x() * 0.5f, 0.f, xb8_dim.y() * 0.5f); + xc0_verts[3].assign(xb8_dim.x() * 0.5f, 0.f, -xb8_dim.y() * 0.5f); } void CGuiPane::WriteData(COutputStream& out, bool flag) const {} std::shared_ptr CGuiPane::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - zeus::CVector2f dim = zeus::CVector2f::ReadBig(in); - zeus::CVector3f scaleCenter = zeus::CVector3f::ReadBig(in); + zeus::CVector2f dim = in.Get(); + zeus::CVector3f scaleCenter = in.Get(); std::shared_ptr ret = std::make_shared(parms, dim, scaleCenter); ret->ParseBaseInfo(frame, in, parms); return ret; diff --git a/Runtime/GuiSys/CGuiPane.hpp b/Runtime/GuiSys/CGuiPane.hpp index 4b054bf31..c2ec2333e 100644 --- a/Runtime/GuiSys/CGuiPane.hpp +++ b/Runtime/GuiSys/CGuiPane.hpp @@ -11,16 +11,12 @@ namespace metaforce { class CGuiPane : public CGuiWidget { + static constexpr zeus::CVector3f skDefaultNormal{0.f, -1.f, 0.f}; protected: zeus::CVector2f xb8_dim; - struct TexShaderVert { - zeus::CVector3f m_pos; - zeus::CVector2f m_uv; - }; /* Originally a vert-buffer pointer for GX */ - std::vector xc0_verts; - // u32 x104_ = 4; /* vert count */ + std::array xc0_verts; zeus::CVector3f xc8_scaleCenter; @@ -28,6 +24,7 @@ public: CGuiPane(const CGuiWidgetParms& parms, const zeus::CVector2f& dim, const zeus::CVector3f& scaleCenter); FourCC GetWidgetTypeID() const override { return FOURCC('PANE'); } + void Draw(const CGuiWidgetDrawParms& parms) override; virtual void ScaleDimensions(const zeus::CVector3f& scale); virtual void SetDimensions(const zeus::CVector2f& dim, bool initVBO); virtual zeus::CVector2f GetDimensions() const; diff --git a/Runtime/GuiSys/CGuiSliderGroup.cpp b/Runtime/GuiSys/CGuiSliderGroup.cpp index df7aef83c..19893e594 100644 --- a/Runtime/GuiSys/CGuiSliderGroup.cpp +++ b/Runtime/GuiSys/CGuiSliderGroup.cpp @@ -67,9 +67,9 @@ bool CGuiSliderGroup::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVect } void CGuiSliderGroup::ProcessUserInput(const CFinalInput& input) { - if (input.DMouseButton(boo::EMouseButton::Primary) && m_mouseInside) + if (input.DMouseButton(EMouseButton::Primary) && m_mouseInside) m_mouseDown = true; - else if (!input.DMouseButton(boo::EMouseButton::Primary)) + else if (!input.DMouseButton(EMouseButton::Primary)) m_mouseDown = false; if (input.DLALeft()) { StartDecreasing(); @@ -158,10 +158,10 @@ CGuiWidget* CGuiSliderGroup::GetWorkerWidget(int id) const { std::shared_ptr CGuiSliderGroup::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - float min = in.readFloatBig(); - float max = in.readFloatBig(); - float cur = in.readFloatBig(); - float increment = in.readFloatBig(); + float min = in.ReadFloat(); + float max = in.ReadFloat(); + float cur = in.ReadFloat(); + float increment = in.ReadFloat(); std::shared_ptr ret = std::make_shared(parms, min, max, cur, increment); ret->ParseBaseInfo(frame, in, parms); diff --git a/Runtime/GuiSys/CGuiSys.cpp b/Runtime/GuiSys/CGuiSys.cpp index 6010d6527..452b7f2b6 100644 --- a/Runtime/GuiSys/CGuiSys.cpp +++ b/Runtime/GuiSys/CGuiSys.cpp @@ -25,7 +25,7 @@ CTextExecuteBuffer* g_TextExecuteBuf = nullptr; CTextParser* g_TextParser = nullptr; std::shared_ptr CGuiSys::CreateWidgetInGame(FourCC type, CInputStream& in, CGuiFrame* frame, - CSimplePool* sp) { + CSimplePool* sp, u32 version) { switch (type.toUint32()) { case SBIG('BWIG'): return CGuiWidget::Create(frame, in, sp); @@ -50,7 +50,7 @@ std::shared_ptr CGuiSys::CreateWidgetInGame(FourCC type, CInputStrea case SBIG('SLGP'): return CGuiSliderGroup::Create(frame, in, sp); case SBIG('TXPN'): - return CGuiTextPane::Create(frame, in, sp); + return CGuiTextPane::Create(frame, in, sp, version); case SBIG('ENRG'): return CAuiEnergyBarT01::Create(frame, in, sp); default: @@ -76,17 +76,18 @@ void CGuiSys::OnViewportResize() { void CGuiSys::ViewportResizeFrame(CGuiFrame* frame) { if (frame->m_aspectConstraint > 0.f) { float hPad, vPad; - if (g_Viewport.aspect >= frame->m_aspectConstraint) { - hPad = frame->m_aspectConstraint / g_Viewport.aspect; + if (CGraphics::GetViewportAspect() >= frame->m_aspectConstraint) { + hPad = frame->m_aspectConstraint / CGraphics::GetViewportAspect(); vPad = frame->m_aspectConstraint / 1.38f; } else { hPad = 1.f; - vPad = g_Viewport.aspect / 1.38f; + vPad = CGraphics::GetViewportAspect() / 1.38f; } frame->m_aspectTransform = zeus::CTransform::Scale({hPad, 1.f, vPad}); } else if (frame->m_maxAspect > 0.f) { - if (g_Viewport.aspect > frame->m_maxAspect) - frame->m_aspectTransform = zeus::CTransform::Scale({frame->m_maxAspect / g_Viewport.aspect, 1.f, 1.f}); + if (CGraphics::GetViewportAspect() > frame->m_maxAspect) + frame->m_aspectTransform = + zeus::CTransform::Scale({frame->m_maxAspect / CGraphics::GetViewportAspect(), 1.f, 1.f}); else frame->m_aspectTransform = zeus::CTransform(); } diff --git a/Runtime/GuiSys/CGuiSys.hpp b/Runtime/GuiSys/CGuiSys.hpp index 5ce5036d8..ea0e217f4 100644 --- a/Runtime/GuiSys/CGuiSys.hpp +++ b/Runtime/GuiSys/CGuiSys.hpp @@ -5,11 +5,9 @@ #include #include -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/GuiSys/CSaveableState.hpp" -#include - namespace metaforce { class CGuiFrame; class CGuiObject; @@ -36,7 +34,7 @@ private: std::unordered_set m_registeredFrames; static std::shared_ptr CreateWidgetInGame(FourCC type, CInputStream& in, CGuiFrame* frame, - CSimplePool* sp); + CSimplePool* sp, u32 version); public: CGuiSys(IFactory& resFactory, CSimplePool& resStore, EUsageMode mode); diff --git a/Runtime/GuiSys/CGuiTableGroup.cpp b/Runtime/GuiSys/CGuiTableGroup.cpp index 671188df9..4bb4593bb 100644 --- a/Runtime/GuiSys/CGuiTableGroup.cpp +++ b/Runtime/GuiSys/CGuiTableGroup.cpp @@ -32,9 +32,9 @@ CGuiTableGroup::CGuiTableGroup(const CGuiWidgetParms& parms, int elementCount, i , xd0_selectWraparound(selectWraparound) {} void CGuiTableGroup::ProcessUserInput(const CFinalInput& input) { - if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter)) { + if (input.PA() || input.PSpecialKey(ESpecialKey::Enter)) { DoAdvance(); - } else if (input.PB() || input.PSpecialKey(boo::ESpecialKey::Esc)) { + } else if (input.PB() || input.PSpecialKey(ESpecialKey::Esc)) { DoCancel(); } else { bool decrement; @@ -207,21 +207,21 @@ void CGuiTableGroup::DoIncrement() { std::shared_ptr CGuiTableGroup::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - int elementCount = in.readInt16Big(); - in.readInt16Big(); - in.readUint32Big(); - int defaultSel = in.readInt16Big(); - in.readInt16Big(); - bool selectWraparound = in.readBool(); - in.readBool(); - in.readFloatBig(); - in.readFloatBig(); - in.readBool(); - in.readFloatBig(); - in.readInt16Big(); - in.readInt16Big(); - in.readInt16Big(); - in.readInt16Big(); + int elementCount = in.ReadInt16(); + in.ReadInt16(); + in.ReadLong(); + int defaultSel = in.ReadInt16(); + in.ReadInt16(); + bool selectWraparound = in.ReadBool(); + in.ReadBool(); + in.ReadFloat(); + in.ReadFloat(); + in.ReadBool(); + in.ReadFloat(); + in.ReadInt16(); + in.ReadInt16(); + in.ReadInt16(); + in.ReadInt16(); std::shared_ptr ret = std::make_shared(parms, elementCount, defaultSel, selectWraparound); ret->ParseBaseInfo(frame, in, parms); diff --git a/Runtime/GuiSys/CGuiTextPane.cpp b/Runtime/GuiSys/CGuiTextPane.cpp index 6ec8effe6..b87e079d2 100644 --- a/Runtime/GuiSys/CGuiTextPane.cpp +++ b/Runtime/GuiSys/CGuiTextPane.cpp @@ -17,16 +17,17 @@ constexpr std::array NormalPoints{{ {1.f, 0.f, 0.f}, {0.f, 0.f, 0.f}, }}; - bool testProjectedLine(const zeus::CVector2f& a, const zeus::CVector2f& b, const zeus::CVector2f& point) { const zeus::CVector2f normal = (b - a).perpendicularVector().normalized(); return point.dot(normal) >= a.dot(normal); } } // Anonymous namespace +bool CGuiTextPane::sDrawPaneRects = false; CGuiTextPane::CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const zeus::CVector2f& dim, const zeus::CVector3f& vec, CAssetId fontId, const CGuiTextProperties& props, - const zeus::CColor& fontCol, const zeus::CColor& outlineCol, s32 extentX, s32 extentY) + const zeus::CColor& fontCol, const zeus::CColor& outlineCol, s32 extentX, s32 extentY, + CAssetId jpFontId, s32 jpExtentX, s32 jpExtentY) : CGuiPane(parms, dim, vec) , xd4_textSupport(fontId, props, fontCol, outlineCol, zeus::skWhite, extentX, extentY, sp, xac_drawFlags) {} @@ -46,6 +47,10 @@ void CGuiTextPane::SetDimensions(const zeus::CVector2f& dim, bool initVBO) { void CGuiTextPane::ScaleDimensions(const zeus::CVector3f& scale) {} void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) { + if (sDrawPaneRects) { + CGuiPane::Draw({0.2f * parms.x0_alphaMod, parms.x4_cameraOffset}); + } + if (!GetIsVisible()) { return; } @@ -53,19 +58,19 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) { zeus::CVector2f dims = GetDimensions(); - if (xd4_textSupport.x34_extentX) { + if (xd4_textSupport.x34_extentX != 0) { dims.x() /= float(xd4_textSupport.x34_extentX); } else { dims.x() = 0.f; } - if (xd4_textSupport.x38_extentY) { + if (xd4_textSupport.x38_extentY != 0) { dims.y() /= float(xd4_textSupport.x38_extentY); } else { dims.y() = 0.f; } - const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * + const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front() + xc8_scaleCenter) * zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); CGraphics::SetModelMatrix(x34_worldXF * local); @@ -73,45 +78,37 @@ void CGuiTextPane::Draw(const CGuiWidgetDrawParms& parms) { geomCol.a() *= parms.x0_alphaMod; xd4_textSupport.SetGeometryColor(geomCol); -#if 0 - CGraphics::SetDepthWriteMode(xb6_31_depthTest, ERglEnum::LEqual, xb7_24_depthWrite); + CGraphics::SetDepthWriteMode(xb6_31_depthTest, ERglEnum::LEqual, xb7_24_depthWrite); - switch (xac_drawFlags) - { - case EGuiModelDrawFlags::Shadeless: - case EGuiModelDrawFlags::Opaque: - CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, - ERglBlendFactor::Zero, ERglLogicOp::Clear); - xd4_textSupport.Render(); - break; - case EGuiModelDrawFlags::Alpha: - CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, - ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear); - xd4_textSupport.Render(); - break; - case EGuiModelDrawFlags::Additive: - CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, - ERglBlendFactor::One, ERglLogicOp::Clear); - xd4_textSupport.Render(); - break; - case EGuiModelDrawFlags::AlphaAdditiveOverdraw: - CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, - ERglBlendFactor::InvSrcAlpha, ERglLogicOp::Clear); - xd4_textSupport.Render(); - xd4_textSupport.SetGeometryColor(geomCol * zeus::CColor(geomCol.a, geomCol.a, geomCol.a, 1.f)); - CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, - ERglBlendFactor::One, ERglLogicOp::Clear); - xd4_textSupport.Render(); - break; - } -#else - xd4_textSupport.Render(); -#endif + switch (xac_drawFlags) { + case EGuiModelDrawFlags::Shadeless: + case EGuiModelDrawFlags::Opaque: + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::Zero, ERglLogicOp::Clear); + xd4_textSupport.Render(); + break; + case EGuiModelDrawFlags::Alpha: + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + xd4_textSupport.Render(); + break; + case EGuiModelDrawFlags::Additive: + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::One, ERglLogicOp::Clear); + xd4_textSupport.Render(); + break; + case EGuiModelDrawFlags::AlphaAdditiveOverdraw: + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::SrcAlpha, ERglBlendFactor::InvSrcAlpha, + ERglLogicOp::Clear); + xd4_textSupport.Render(); + xd4_textSupport.SetGeometryColor(geomCol * zeus::CColor(geomCol.a(), 1.f)); + CGraphics::SetBlendMode(ERglBlendMode::Blend, ERglBlendFactor::One, ERglBlendFactor::One, ERglLogicOp::Clear); + xd4_textSupport.Render(); + break; + } } bool CGuiTextPane::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const { const zeus::CVector2f dims = GetDimensions(); - const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front().m_pos + xc8_scaleCenter) * + const zeus::CTransform local = zeus::CTransform::Translate(xc0_verts.front() + xc8_scaleCenter) * zeus::CTransform::Scale(dims.x(), 1.f, dims.y()); const zeus::CMatrix4f mvp = vp * (x34_worldXF * local).toMatrix4f(); @@ -129,23 +126,30 @@ bool CGuiTextPane::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2 return j == 3 && testProjectedLine(projPoints[3], projPoints[0], point); } -std::shared_ptr CGuiTextPane::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) { +std::shared_ptr CGuiTextPane::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp, u32 version) { const CGuiWidgetParms parms = ReadWidgetHeader(frame, in); - const zeus::CVector2f dim = zeus::CVector2f::ReadBig(in); - const zeus::CVector3f vec = zeus::CVector3f::ReadBig(in); - const u32 fontId = in.readUint32Big(); - const bool wordWrap = in.readBool(); - const bool horizontal = in.readBool(); - const auto justification = EJustification(in.readUint32Big()); - const auto vJustification = EVerticalJustification(in.readUint32Big()); + const zeus::CVector2f dim = in.Get(); + const zeus::CVector3f vec = in.Get(); + const CAssetId fontId = in.Get(); + const bool wordWrap = in.ReadBool(); + const bool horizontal = in.ReadBool(); + const auto justification = EJustification(in.ReadLong()); + const auto vJustification = EVerticalJustification(in.ReadLong()); const CGuiTextProperties props(wordWrap, horizontal, justification, vJustification); - zeus::CColor fontCol; - fontCol.readRGBABig(in); - zeus::CColor outlineCol; - outlineCol.readRGBABig(in); - const int extentX = static_cast(in.readFloatBig()); - const int extentY = static_cast(in.readFloatBig()); - auto ret = std::make_shared(parms, sp, dim, vec, fontId, props, fontCol, outlineCol, extentX, extentY); + const zeus::CColor fontCol = in.Get(); + const zeus::CColor outlineCol = in.Get(); + const int extentX = static_cast(in.ReadFloat()); + const int extentY = static_cast(in.ReadFloat()); + int jpExtentX = extentX; + int jpExtentY = extentY; + CAssetId jpFontId = fontId; + if (version != 0) { + jpFontId = in.Get(); + jpExtentX = in.ReadLong(); + jpExtentY = in.ReadLong(); + } + auto ret = std::make_shared(parms, sp, dim, vec, fontId, props, fontCol, outlineCol, extentX, extentY, + jpFontId, jpExtentY, jpExtentY); ret->ParseBaseInfo(frame, in, parms); ret->InitializeBuffers(); ret->TextSupport().SetText(u""); diff --git a/Runtime/GuiSys/CGuiTextPane.hpp b/Runtime/GuiSys/CGuiTextPane.hpp index d304e5316..0a15ca1d4 100644 --- a/Runtime/GuiSys/CGuiTextPane.hpp +++ b/Runtime/GuiSys/CGuiTextPane.hpp @@ -9,12 +9,13 @@ namespace metaforce { class CGuiTextPane : public CGuiPane { + static bool sDrawPaneRects; CGuiTextSupport xd4_textSupport; public: CGuiTextPane(const CGuiWidgetParms& parms, CSimplePool* sp, const zeus::CVector2f& dim, const zeus::CVector3f& vec, CAssetId fontId, const CGuiTextProperties& props, const zeus::CColor& col1, const zeus::CColor& col2, - s32 padX, s32 padY); + s32 padX, s32 padY, CAssetId jpFontId, s32 jpExtentX, s32 jpExtentY); FourCC GetWidgetTypeID() const override { return FOURCC('TXPN'); } CGuiTextSupport& TextSupport() { return xd4_textSupport; } @@ -27,7 +28,7 @@ public: void Draw(const CGuiWidgetDrawParms& parms) override; bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const override; - static std::shared_ptr Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp); + static std::shared_ptr Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp, u32 version); }; } // namespace metaforce diff --git a/Runtime/GuiSys/CGuiTextSupport.cpp b/Runtime/GuiSys/CGuiTextSupport.cpp index e72cc7a93..3feda7dab 100644 --- a/Runtime/GuiSys/CGuiTextSupport.cpp +++ b/Runtime/GuiSys/CGuiTextSupport.cpp @@ -10,6 +10,7 @@ #include "Runtime/GuiSys/CRasterFont.hpp" #include "Runtime/GuiSys/CTextExecuteBuffer.hpp" #include "Runtime/GuiSys/CTextParser.hpp" +#include "Runtime/CStringExtras.hpp" namespace metaforce { @@ -69,7 +70,7 @@ float CGuiTextSupport::GetCurrentAnimationOverAge() const { float ret = 0.f; if (const CTextRenderBuffer* buf = GetCurrentPageRenderBuffer()) { if (x50_typeEnable) { - if (x40_primStartTimes.size()) { + if (!x40_primStartTimes.empty()) { const auto& lastTime = x40_primStartTimes.back(); ret = std::max(ret, (buf->GetPrimitiveCount() - lastTime.second) / x58_chRate + lastTime.first); } else { @@ -127,7 +128,7 @@ void CGuiTextSupport::SetTypeWriteEffectOptions(bool enable, float chFadeTime, f break; } - buf->SetPrimitiveOpacity(i, std::min(std::max(0.f, (x3c_curTime - chStartTime) / x54_chFadeTime), 1.f)); + //buf->SetPrimitiveOpacity(i, std::min(std::max(0.f, (x3c_curTime - chStartTime) / x54_chFadeTime), 1.f)); chStartTime += 1.f / x58_chRate; } } @@ -148,8 +149,11 @@ void CGuiTextSupport::Update(float dt) { break; } - buf->SetPrimitiveOpacity(i, std::min(std::max(0.f, (x3c_curTime - chStartTime) / x54_chFadeTime), 1.f)); + auto primitive = buf->GetPrimitive(i); + float alpha = std::clamp((x3c_curTime - chStartTime) / x54_chFadeTime, 0.f, 1.f); chStartTime += 1.f / x58_chRate; + primitive.x0_color1 = zeus::CColor{alpha, alpha}; + buf->SetPrimitive(primitive, i); } } x3c_curTime += dt; @@ -183,9 +187,11 @@ void CGuiTextSupport::CheckAndRebuildTextBuffer() { } bool CGuiTextSupport::CheckAndRebuildRenderBuffer() { - if (x308_multipageFlag || x60_renderBuf) - if (!x308_multipageFlag || x2ec_renderBufferPages.size()) + if (x308_multipageFlag || x60_renderBuf) { + if (!x308_multipageFlag || x2ec_renderBufferPages.size()) { return true; + } + } CheckAndRebuildTextBuffer(); x2bc_assets = g_TextExecuteBuf->GetAssets(); @@ -271,7 +277,9 @@ void CGuiTextSupport::SetText(std::u16string_view str, bool multipage) { x304_pageCounter = 0; } -void CGuiTextSupport::SetText(std::string_view str, bool multipage) { SetText(hecl::UTF8ToChar16(str), multipage); } +void CGuiTextSupport::SetText(std::string_view str, bool multipage) { + SetText(CStringExtras::ConvertToUNICODE(str), multipage); +} bool CGuiTextSupport::_GetIsTextSupportFinishedLoading() { for (CToken& tok : x2bc_assets) { diff --git a/Runtime/GuiSys/CGuiTextSupport.hpp b/Runtime/GuiSys/CGuiTextSupport.hpp index 02dc0b22e..34254908a 100644 --- a/Runtime/GuiSys/CGuiTextSupport.hpp +++ b/Runtime/GuiSys/CGuiTextSupport.hpp @@ -78,6 +78,8 @@ class CGuiTextSupport { zeus::CColor x28_outlineColor; zeus::CColor x2c_geometryColor; bool x30_imageBaseline = false; + s32 x30_; // new in PAL/JP + s32 x34_; // "" s32 x34_extentX; s32 x38_extentY; float x3c_curTime = 0.f; diff --git a/Runtime/GuiSys/CGuiWidget.cpp b/Runtime/GuiSys/CGuiWidget.cpp index c3859f312..b13a9d33e 100644 --- a/Runtime/GuiSys/CGuiWidget.cpp +++ b/Runtime/GuiSys/CGuiWidget.cpp @@ -1,3 +1,4 @@ +#include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/GuiSys/CGuiWidget.hpp" #include "Runtime/GuiSys/CGuiFrame.hpp" @@ -23,18 +24,17 @@ CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms) } CGuiWidget::CGuiWidgetParms CGuiWidget::ReadWidgetHeader(CGuiFrame* frame, CInputStream& in) { - std::string name = in.readString(-1); + std::string name = in.Get(); s16 selfId = frame->GetWidgetIdDB().AddWidget(name); - std::string parent = in.readString(-1); + std::string parent = in.Get(); s16 parentId = frame->GetWidgetIdDB().AddWidget(parent); - bool useAnimController = in.readBool(); - bool defaultVis = in.readBool(); - bool defaultActive = in.readBool(); - bool cullFaces = in.readBool(); - zeus::CColor color; - color.readRGBABig(in); - EGuiModelDrawFlags df = EGuiModelDrawFlags(in.readUint32Big()); + bool useAnimController = in.ReadBool(); + bool defaultVis = in.ReadBool(); + bool defaultActive = in.ReadBool(); + bool cullFaces = in.ReadBool(); + zeus::CColor color = in.Get(); + EGuiModelDrawFlags df = EGuiModelDrawFlags(in.ReadLong()); return CGuiWidget::CGuiWidgetParms(frame, useAnimController, selfId, parentId, defaultVis, defaultActive, cullFaces, color, df, true, false, std::move(name)); @@ -51,17 +51,17 @@ void CGuiWidget::Initialize() {} void CGuiWidget::ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms) { CGuiWidget* parent = frame->FindWidget(parms.x8_parentId); - bool isWorker = in.readBool(); + bool isWorker = in.ReadBool(); if (isWorker) - xb4_workerId = in.readInt16Big(); - zeus::CVector3f trans = zeus::CVector3f::ReadBig(in); - zeus::CMatrix3f orient = zeus::CMatrix3f::ReadBig(in); + xb4_workerId = in.ReadInt16(); + zeus::CVector3f trans = in.Get(); + zeus::CMatrix3f orient = in.Get(); x74_transform = zeus::CTransform(orient, trans); m_initTransform = x74_transform; ReapplyXform(); - (void)zeus::CVector3f::ReadBig(in); // Unused - in.readUint32Big(); - in.readUint16Big(); + in.Get(); // Unused + in.ReadLong(); + in.ReadShort(); if (isWorker) { if (!parent->AddWorkerWidget(this)) { Log.report(logvisor::Warning, @@ -111,7 +111,7 @@ void CGuiWidget::Update(float dt) { sib->Update(dt); } -void CGuiWidget::Draw(const CGuiWidgetDrawParms&) {} +void CGuiWidget::Draw(const CGuiWidgetDrawParms& parms) {} void CGuiWidget::ProcessUserInput(const CFinalInput& input) {} void CGuiWidget::Touch() {} diff --git a/Runtime/GuiSys/CGuiWidget.hpp b/Runtime/GuiSys/CGuiWidget.hpp index add4c810a..f7e07e812 100644 --- a/Runtime/GuiSys/CGuiWidget.hpp +++ b/Runtime/GuiSys/CGuiWidget.hpp @@ -5,10 +5,9 @@ #include #include "Runtime/GCNTypes.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/GuiSys/CGuiObject.hpp" - -#include +#include "Runtime/Input/CKeyboardMouseController.hpp" #include #include @@ -84,8 +83,8 @@ protected: bool xb7_25_ : 1 = true; bool m_mouseActive : 1 = false; - std::optional m_lastScroll; - boo::SScrollDelta m_integerScroll; + std::optional m_lastScroll; + SScrollDelta m_integerScroll; std::string m_name; diff --git a/Runtime/GuiSys/CHudDecoInterface.cpp b/Runtime/GuiSys/CHudDecoInterface.cpp index cbc572a9c..5e0291b7a 100644 --- a/Runtime/GuiSys/CHudDecoInterface.cpp +++ b/Runtime/GuiSys/CHudDecoInterface.cpp @@ -322,8 +322,9 @@ void CHudDecoInterfaceScan::Update(float dt, const CStateManager& stateMgr) { } void CHudDecoInterfaceScan::Draw() { + SCOPED_GRAPHICS_DEBUG_GROUP("CHudDecoInterfaceScan::Draw", zeus::skGreen); x18_scanDisplay.Draw(); - if (x10_loadedScanHudFlat) { + if (x10_loadedScanHudFlat != nullptr) { x10_loadedScanHudFlat->Draw(CGuiWidgetDrawParms::Default()); } } diff --git a/Runtime/GuiSys/CHudEnergyInterface.cpp b/Runtime/GuiSys/CHudEnergyInterface.cpp index abfeab6bd..f1587be8f 100644 --- a/Runtime/GuiSys/CHudEnergyInterface.cpp +++ b/Runtime/GuiSys/CHudEnergyInterface.cpp @@ -37,8 +37,8 @@ CHudEnergyInterface::CHudEnergyInterface(CGuiFrame& selHud, float tankEnergy, in x2c_energybart01_energybar->SetCoordFunc(CoordFuncs[size_t(hudType)]); x2c_energybart01_energybar->SetTesselation(Tesselations[size_t(hudType)]); - ITweakGuiColors::VisorEnergyBarColors barColors = g_tweakGuiColors->GetVisorEnergyBarColors(int(hudType)); - ITweakGuiColors::VisorEnergyInitColors initColors = g_tweakGuiColors->GetVisorEnergyInitColors(int(hudType)); + ITweakGuiColors::SVisorEnergyBarColors barColors = g_tweakGuiColors->GetVisorEnergyBarColors(int(hudType)); + ITweakGuiColors::SVisorEnergyInitColors initColors = g_tweakGuiColors->GetVisorEnergyInitColors(int(hudType)); x20_textpane_energydigits->TextSupport().SetFontColor(initColors.digitsFont); x20_textpane_energydigits->TextSupport().SetOutlineColor(initColors.digitsOutline); @@ -100,7 +100,7 @@ void CHudEnergyInterface::Update(float dt, float energyLowPulse) { x20_textpane_energydigits->TextSupport().SetText(string); } - ITweakGuiColors::VisorEnergyBarColors barColors = g_tweakGuiColors->GetVisorEnergyBarColors(int(x0_hudType)); + ITweakGuiColors::SVisorEnergyBarColors barColors = g_tweakGuiColors->GetVisorEnergyBarColors(int(x0_hudType)); zeus::CColor emptyColor = x1c_27_energyLow ? g_tweakGuiColors->GetEnergyBarEmptyLowEnergy() : barColors.empty; zeus::CColor filledColor = x1c_27_energyLow ? g_tweakGuiColors->GetEnergyBarFilledLowEnergy() : barColors.filled; zeus::CColor shadowColor = x1c_27_energyLow ? g_tweakGuiColors->GetEnergyBarShadowLowEnergy() : barColors.shadow; diff --git a/Runtime/GuiSys/CHudRadarInterface.cpp b/Runtime/GuiSys/CHudRadarInterface.cpp index 110caf4f7..45b8fe9bb 100644 --- a/Runtime/GuiSys/CHudRadarInterface.cpp +++ b/Runtime/GuiSys/CHudRadarInterface.cpp @@ -5,7 +5,7 @@ #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Camera/CGameCamera.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/GuiSys/CGuiCamera.hpp" #include "Runtime/GuiSys/CGuiFrame.hpp" #include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp" @@ -26,19 +26,19 @@ CHudRadarInterface::CHudRadarInterface(CGuiFrame& baseHud, CStateManager& stateM x40_BaseWidget_RadarStuff->SetColor(g_tweakGuiColors->GetRadarStuffColor()); } -void CHudRadarInterface::DoDrawRadarPaint(const zeus::CVector3f& translate, float radius, const zeus::CColor& color) { +void CHudRadarInterface::DoDrawRadarPaint(float radius) { radius *= 4.f; - CRadarPaintShader::Instance& inst = m_paintInsts.emplace_back(); - inst.pos[0] = translate + zeus::CVector3f(-radius, 0.f, radius); - inst.uv[0].assign(0.f, 1.f); - inst.pos[1] = translate + zeus::CVector3f(-radius, 0.f, -radius); - inst.uv[1].assign(0.f, 0.f); - inst.pos[2] = translate + zeus::CVector3f(radius, 0.f, radius); - inst.uv[2].assign(1.f, 1.f); - inst.pos[3] = translate + zeus::CVector3f(radius, 0.f, -radius); - inst.uv[3].assign(1.f, 0.f); - inst.color = color; + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamTexcoord(0.f, 1.f); + CGraphics::StreamVertex(-radius, 0.f, radius); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex(-radius, 0.f, -radius); + CGraphics::StreamTexcoord(1.f, 1.f); + CGraphics::StreamVertex(radius, 0.f, radius); + CGraphics::StreamTexcoord(1.f, 0.f); + CGraphics::StreamVertex(radius, 0.f, -radius); + CGraphics::StreamEnd(); } void CHudRadarInterface::DrawRadarPaint(const zeus::CVector3f& enemyPos, float radius, float alpha, @@ -55,10 +55,15 @@ void CHudRadarInterface::DrawRadarPaint(const zeus::CVector3f& enemyPos, float r } const zeus::CVector2f scopeScaled = playerToEnemy * parms.x70_scopeScalar; + g_Renderer->SetModelMatrix( + parms.x3c_postTranslate * + zeus::CTransform::Translate(parms.xc_preTranslate * zeus::CVector3f(scopeScaled.x(), 0.f, scopeScaled.y()))); + zeus::CColor color = g_tweakGuiColors->GetRadarEnemyPaintColor(); color.a() *= alpha; color.a() *= parms.x74_alpha; - DoDrawRadarPaint(parms.xc_preTranslate * zeus::CVector3f(scopeScaled.x(), 0.f, scopeScaled.y()), radius, color); + CGraphics::StreamColor(color); + DoDrawRadarPaint(radius); } void CHudRadarInterface::SetIsVisibleGame(bool v) { @@ -115,13 +120,17 @@ void CHudRadarInterface::Draw(const CStateManager& mgr, float alpha) { drawParms.x3c_postTranslate = x40_BaseWidget_RadarStuff->GetWorldTransform(); const float enemyRadius = g_tweakGui->GetRadarEnemyPaintRadius(); - m_paintInsts.clear(); x44_camera->Draw(CGuiWidgetDrawParms{0.f, zeus::CVector3f{}}); - CGraphics::SetModelMatrix(drawParms.x3c_postTranslate); + g_Renderer->SetModelMatrix(drawParms.x3c_postTranslate); + g_Renderer->SetBlendMode_AdditiveAlpha(); + x0_txtrRadarPaint->Load(GX_TEXMAP0, EClampMode::Repeat); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + g_Renderer->SetDepthReadWrite(false, false); zeus::CColor playerColor = g_tweakGuiColors->GetRadarPlayerPaintColor(); playerColor.a() *= alpha; - DoDrawRadarPaint(zeus::skZero3f, g_tweakGui->GetRadarPlayerPaintRadius(), playerColor); + CGraphics::StreamColor(playerColor); + DoDrawRadarPaint(g_tweakGui->GetRadarPlayerPaintRadius()); const zeus::CAABox radarBounds( player.GetTranslation().x() - drawParms.x78_xyRadius, player.GetTranslation().y() - drawParms.x78_xyRadius, @@ -156,7 +165,7 @@ void CHudRadarInterface::Draw(const CStateManager& mgr, float alpha) { } } - m_paintShader.draw(m_paintInsts, x0_txtrRadarPaint.GetObj()); + g_Renderer->SetDepthReadWrite(true, true); } } // namespace metaforce diff --git a/Runtime/GuiSys/CHudRadarInterface.hpp b/Runtime/GuiSys/CHudRadarInterface.hpp index 05bc01caf..b0243fcd4 100644 --- a/Runtime/GuiSys/CHudRadarInterface.hpp +++ b/Runtime/GuiSys/CHudRadarInterface.hpp @@ -4,7 +4,6 @@ #include "Runtime/CToken.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include "Runtime/Graphics/Shaders/CRadarPaintShader.hpp" #include #include @@ -33,9 +32,8 @@ class CHudRadarInterface { bool x3c_25_visibleDebug : 1 = true; CGuiWidget* x40_BaseWidget_RadarStuff; CGuiCamera* x44_camera; - CRadarPaintShader m_paintShader; - std::vector m_paintInsts; - void DoDrawRadarPaint(const zeus::CVector3f& translate, float radius, const zeus::CColor& color); + + void DoDrawRadarPaint(float radius); void DrawRadarPaint(const zeus::CVector3f& enemyPos, float radius, float alpha, const SRadarPaintDrawParms& parms); public: diff --git a/Runtime/GuiSys/COrbitPointMarker.cpp b/Runtime/GuiSys/COrbitPointMarker.cpp index c65226029..f1ac2b7d3 100644 --- a/Runtime/GuiSys/COrbitPointMarker.cpp +++ b/Runtime/GuiSys/COrbitPointMarker.cpp @@ -4,7 +4,7 @@ #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Camera/CGameCamera.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/World/CPlayer.hpp" #include @@ -66,17 +66,18 @@ void COrbitPointMarker::Update(float dt, const CStateManager& mgr) { } } -void COrbitPointMarker::Draw(const CStateManager& mgr) const { +void COrbitPointMarker::Draw(const CStateManager& mgr) { if ((x1c_lastFreeOrbit || x20_interpTimer > 0.f) && g_tweakTargeting->DrawOrbitPoint() && x28_orbitPointModel.IsLoaded()) { SCOPED_GRAPHICS_DEBUG_GROUP("COrbitPointMarker::Draw", zeus::skCyan); const CGameCamera* curCam = mgr.GetCameraManager()->GetCurrentCamera(mgr); zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); CGraphics::SetViewPointMatrix(camXf); - zeus::CFrustum frustum = mgr.SetupDrawFrustum(g_Viewport); - frustum.updatePlanes(camXf, zeus::SProjPersp(zeus::degToRad(curCam->GetFov()), g_Viewport.aspect, 1.f, 100.f)); + zeus::CFrustum frustum = mgr.SetupDrawFrustum(CGraphics::g_Viewport); + frustum.updatePlanes( + camXf, zeus::SProjPersp(zeus::degToRad(curCam->GetFov()), CGraphics::GetViewportAspect(), 1.f, 100.f)); g_Renderer->SetClippingPlanes(frustum); - g_Renderer->SetPerspective(curCam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, + g_Renderer->SetPerspective(curCam->GetFov(), CGraphics::GetViewportWidth(), CGraphics::GetViewportHeight(), curCam->GetNearClipDistance(), curCam->GetFarClipDistance()); float scale; if (x1c_lastFreeOrbit) diff --git a/Runtime/GuiSys/COrbitPointMarker.hpp b/Runtime/GuiSys/COrbitPointMarker.hpp index 593e432e2..839cfb5c9 100644 --- a/Runtime/GuiSys/COrbitPointMarker.hpp +++ b/Runtime/GuiSys/COrbitPointMarker.hpp @@ -24,6 +24,6 @@ public: COrbitPointMarker(); bool CheckLoadComplete() const; void Update(float dt, const CStateManager& mgr); - void Draw(const CStateManager& mgr) const; + void Draw(const CStateManager& mgr); }; } // namespace metaforce diff --git a/Runtime/GuiSys/CRasterFont.cpp b/Runtime/GuiSys/CRasterFont.cpp index 53e1d46b4..ca46e667c 100644 --- a/Runtime/GuiSys/CRasterFont.cpp +++ b/Runtime/GuiSys/CRasterFont.cpp @@ -3,6 +3,7 @@ #include #include "Runtime/CSimplePool.hpp" +#include "Runtime/Graphics/CGX.hpp" #include "Runtime/Graphics/CTexture.hpp" #include "Runtime/GuiSys/CDrawStringOptions.hpp" #include "Runtime/GuiSys/CTextRenderBuffer.hpp" @@ -10,61 +11,61 @@ namespace metaforce { CRasterFont::CRasterFont(metaforce::CInputStream& in, metaforce::IObjectStore& store) { u32 magic = 0; - in.readBytesToBuf(&magic, 4); + in.Get(reinterpret_cast(&magic), 4); if (magic != SBIG('FONT')) return; - u32 version = in.readUint32Big(); - x4_monoWidth = in.readUint32Big(); - x8_monoHeight = in.readUint32Big(); + u32 version = in.ReadLong(); + x4_monoWidth = in.ReadLong(); + x8_monoHeight = in.ReadLong(); if (version >= 1) - x8c_baseline = in.readUint32Big(); + x8c_baseline = in.ReadLong(); else x8c_baseline = x8_monoHeight; if (version >= 2) - x90_lineMargin = in.readUint32Big(); + x90_lineMargin = in.ReadLong(); - bool tmp1 = in.readBool(); - bool tmp2 = in.readBool(); + bool tmp1 = in.ReadBool(); + bool tmp2 = in.ReadBool(); - u32 tmp3 = in.readUint32Big(); - u32 tmp4 = in.readUint32Big(); - std::string name = in.readString(); - u32 txtrId = (version == 5 ? in.readUint64Big() : in.readUint32Big()); + u32 tmp3 = in.ReadLong(); + u32 tmp4 = in.ReadLong(); + std::string name = in.Get(); + u32 txtrId = (version == 5 ? in.ReadLongLong() : in.ReadLong()); x30_fontInfo = CFontInfo(tmp1, tmp2, tmp3, tmp4, name.c_str()); x80_texture = store.GetObj({FOURCC('TXTR'), txtrId}); - x2c_mode = CTexture::EFontType(in.readUint32Big()); + x2c_mode = CTexture::EFontType(in.ReadLong()); - u32 glyphCount = in.readUint32Big(); + u32 glyphCount = in.ReadLong(); xc_glyphs.reserve(glyphCount); for (u32 i = 0; i < glyphCount; ++i) { - char16_t chr = in.readUint16Big(); - float startU = in.readFloatBig(); - float startV = in.readFloatBig(); - float endU = in.readFloatBig(); - float endV = in.readFloatBig(); + char16_t chr = in.ReadShort(); + float startU = in.ReadFloat(); + float startV = in.ReadFloat(); + float endU = in.ReadFloat(); + float endV = in.ReadFloat(); s32 layer = 0; s32 a, b, c, cellWidth, cellHeight, baseline, kernStart; if (version < 4) { - a = in.readInt32Big(); - b = in.readInt32Big(); - c = in.readInt32Big(); - cellWidth = in.readInt32Big(); - cellHeight = in.readInt32Big(); - baseline = in.readInt32Big(); - kernStart = in.readInt32Big(); + a = in.ReadInt32(); + b = in.ReadInt32(); + c = in.ReadInt32(); + cellWidth = in.ReadInt32(); + cellHeight = in.ReadInt32(); + baseline = in.ReadInt32(); + kernStart = in.ReadInt32(); } else { - layer = in.readByte(); - a = in.readByte(); - b = in.readByte(); - c = in.readByte(); - cellWidth = in.readByte(); - cellHeight = in.readByte(); - baseline = in.readByte(); - kernStart = in.readInt16Big(); + layer = in.ReadInt8(); + a = in.ReadInt8(); + b = in.ReadInt8(); + c = in.ReadInt8(); + cellWidth = in.ReadInt8(); + cellHeight = in.ReadInt8(); + baseline = in.ReadInt8(); + kernStart = in.ReadInt16(); } xc_glyphs.emplace_back( chr, CGlyph(a, b, c, startU, startV, endU, endV, cellWidth, cellHeight, baseline, kernStart, layer)); @@ -72,13 +73,13 @@ CRasterFont::CRasterFont(metaforce::CInputStream& in, metaforce::IObjectStore& s std::sort(xc_glyphs.begin(), xc_glyphs.end(), [=](auto& a, auto& b) -> bool { return a.first < b.first; }); - u32 kernCount = in.readUint32Big(); + u32 kernCount = in.ReadLong(); x1c_kerning.reserve(kernCount); for (u32 i = 0; i < kernCount; ++i) { - char16_t first = in.readUint16Big(); - char16_t second = in.readUint16Big(); - s32 howMuch = in.readInt32Big(); + char16_t first = in.ReadShort(); + char16_t second = in.ReadShort(); + s32 howMuch = in.ReadInt32(); x1c_kerning.emplace_back(first, second, howMuch); } @@ -151,17 +152,15 @@ void CRasterFont::DrawString(const CDrawStringOptions& opts, int x, int y, int& if (!x0_initialized) return; - if (renderBuf) { - /* CGraphicsPalette pal = CGraphicsPalette::CGraphcisPalette(2, 4); */ - /* zeus::CColor color = zeus::CColor(0.f, 0.f, 0.f, 0.f) */ - /* tmp = color.ToRGB5A3(); */ - /* tmp2 = opts.x8_.ToRGB5A3(); */ - /* tmp3 = opts.xc_.ToRGB5A3(); */ - /* tmp4 = zeus::CColor(0.f, 0.f, 0.f, 0.f); */ - /* tmp5 = tmp4.ToRGBA5A3(); */ - /* pal.UnLock(); */ - /* renderBuf->AddPaletteChange(pal); */ - renderBuf->AddPaletteChange(opts.x4_colors[0], opts.x4_colors[1]); + if (renderBuf != nullptr) { + CGraphicsPalette pal(EPaletteFormat::RGB5A3, 4); + u16* data = pal.Lock(); + data[0] = bswap16(zeus::CColor(0.f, 0.f, 0.f, 0.f).toRGB5A3()); + data[1] = bswap16(opts.x4_colors[0].toRGB5A3()); + data[2] = bswap16(opts.x4_colors[1].toRGB5A3()); + data[3] = bswap16(zeus::CColor(0.f, 0.f, 0.f, 0.f).toRGB5A3()); + pal.UnLock(); + renderBuf->AddPaletteChange(pal); } SinglePassDrawString(opts, x, y, xout, yout, renderBuf, str, len); @@ -210,6 +209,28 @@ bool CRasterFont::IsFinishedLoading() const { return true; } +void CRasterFont::SetupRenderState() { + constexpr std::array skDescList = { + GXVtxDescList{GX_VA_POS, GX_DIRECT}, + GXVtxDescList{GX_VA_TEX0, GX_DIRECT}, + GXVtxDescList{GX_VA_NULL, GX_NONE}, + }; + + x80_texture->Load(GX_TEXMAP0, EClampMode::Clamp); + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + CGX::SetTevDirect(GX_TEVSTAGE0); + CGX::SetVtxDescv(skDescList.data()); + CGX::SetNumChans(0); + CGX::SetNumTexGens(1); + CGX::SetNumTevStages(1); + CGX::SetNumIndStages(0); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); +} std::unique_ptr FRasterFontFactory([[maybe_unused]] const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, [[maybe_unused]] CObjectReference* selfRef) { CSimplePool* sp = vparms.GetOwnedObj(); diff --git a/Runtime/GuiSys/CRasterFont.hpp b/Runtime/GuiSys/CRasterFont.hpp index 45b0dcf04..990dcd5e5 100644 --- a/Runtime/GuiSys/CRasterFont.hpp +++ b/Runtime/GuiSys/CRasterFont.hpp @@ -6,7 +6,7 @@ #include "Runtime/CToken.hpp" #include "Runtime/GCNTypes.hpp" -#include "Runtime/IOStreams.hpp" +#include "Runtime/Streams/IOStreams.hpp" #include "Runtime/Graphics/CTexture.hpp" #include @@ -148,9 +148,11 @@ public: const char16_t* str, int len) const; const CGlyph* GetGlyph(char16_t chr) const { return InternalGetGlyph(chr); } void GetSize(const CDrawStringOptions& opts, int& width, int& height, const char16_t* str, int len) const; - const boo::ObjToken& GetTexture() { return x80_texture->GetFontTexture(x2c_mode); } + CTexture& GetTexture() { return *x80_texture; } bool IsFinishedLoading() const; + + void SetupRenderState(); }; std::unique_ptr FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms, diff --git a/Runtime/GuiSys/CScanDisplay.cpp b/Runtime/GuiSys/CScanDisplay.cpp index 2be7f62c0..37b909c72 100644 --- a/Runtime/GuiSys/CScanDisplay.cpp +++ b/Runtime/GuiSys/CScanDisplay.cpp @@ -3,7 +3,7 @@ #include "Runtime/CSimplePool.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Audio/CSfxManager.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/GuiSys/CAuiImagePane.hpp" #include "Runtime/GuiSys/CGuiCamera.hpp" @@ -36,23 +36,25 @@ void CScanDisplay::CDataDot::Update(float dt) { } void CScanDisplay::CDataDot::Draw(const zeus::CColor& col, float radius) { - if (x24_alpha == 0.f) { + if (x24_alpha == 0.f || x0_dotState == EDotState::Hidden) { return; } - if (x0_dotState != EDotState::Hidden) { - const zeus::CTransform xf = zeus::CTransform::Translate(xc_curPos.x(), 0.f, xc_curPos.y()); - CGraphics::SetModelMatrix(xf); - zeus::CColor useColor = col; - useColor.a() *= x24_alpha; - const std::array verts{{ - {{-radius, 0.f, radius}, {0.f, 1.f}}, - {{-radius, 0.f, -radius}, {0.f, 0.f}}, - {{radius, 0.f, radius}, {1.f, 1.f}}, - {{radius, 0.f, -radius}, {1.f, 0.f}}, - }}; - m_quad.drawVerts(useColor, verts); - } + const zeus::CTransform xf = zeus::CTransform::Translate(xc_curPos.x(), 0.f, xc_curPos.y()); + g_Renderer->SetModelMatrix(xf); + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + zeus::CColor useColor = col; + useColor.a() *= x24_alpha; + CGraphics::StreamColor(useColor); + CGraphics::StreamTexcoord(0.f, 1.f); + CGraphics::StreamVertex(-radius, 0.f, radius); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex(-radius, 0.f, -radius); + CGraphics::StreamTexcoord(1.f, 1.f); + CGraphics::StreamVertex(radius, 0.f, radius); + CGraphics::StreamTexcoord(1.f, 0.f); + CGraphics::StreamVertex(radius, 0.f, -radius); + CGraphics::StreamEnd(); } void CScanDisplay::CDataDot::StartTransitionTo(const zeus::CVector2f& vec, float dur) { @@ -82,7 +84,7 @@ void CScanDisplay::ProcessInput(const CFinalInput& input) { return; if (xc_state == EScanState::DownloadComplete && x1a4_xAlpha == 0.f) { - if (input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary)) { + if (input.PA() || input.PSpecialKey(ESpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)) { if (xa8_message->TextSupport().GetCurTime() < xa8_message->TextSupport().GetTotalAnimationTime()) { xa8_message->TextSupport().SetCurTime(xa8_message->TextSupport().GetTotalAnimationTime()); } else { @@ -94,7 +96,7 @@ void CScanDisplay::ProcessInput(const CFinalInput& input) { } else if (xc_state == EScanState::ViewingScan) { int oldCounter = x1ac_pageCounter; int totalPages = xac_scrollMessage->TextSupport().GetTotalPageCount(); - if ((input.PA() || input.PSpecialKey(boo::ESpecialKey::Enter) || input.PMouseButton(boo::EMouseButton::Primary)) && + if ((input.PA() || input.PSpecialKey(ESpecialKey::Enter) || input.PMouseButton(EMouseButton::Primary)) && totalPages != -1) { CGuiTextSupport& supp = !x1ac_pageCounter ? xa8_message->TextSupport() : xac_scrollMessage->TextSupport(); if (supp.GetCurTime() < supp.GetTotalAnimationTime()) @@ -381,7 +383,7 @@ void CScanDisplay::Update(float dt, float scanningTime) { case CDataDot::EDotState::Hold: { float tmp = dot.GetTransitionFactor(); if (tmp == 0.f) { - float vpRatio = g_Viewport.xc_height / 480.f; + float vpRatio = CGraphics::GetViewportHeight() / 480.f; float posRand = g_tweakGui->GetScanDataDotPosRandMagnitude() * vpRatio; float durMin = dot.GetDotState() == CDataDot::EDotState::Hold ? g_tweakGui->GetScanDataDotHoldDurationMin() : g_tweakGui->GetScanDataDotSeekDurationMin(); @@ -403,8 +405,8 @@ void CScanDisplay::Update(float dt, float scanningTime) { case CDataDot::EDotState::Done: { const zeus::CVector3f& panePos = x170_paneStates[i].second->GetWorldPosition(); zeus::CVector3f screenPos = xa0_selHud.GetFrameCamera()->ConvertToScreenSpace(panePos); - zeus::CVector2f viewportCoords(screenPos.x() * g_Viewport.x8_width * 0.5f, - screenPos.y() * g_Viewport.xc_height * 0.5f); + zeus::CVector2f viewportCoords(screenPos.x() * CGraphics::GetViewportWidth() * 0.5f, + screenPos.y() * CGraphics::GetViewportHeight() * 0.5f); dot.SetDestPosition(viewportCoords); break; } @@ -444,12 +446,15 @@ void CScanDisplay::Draw() { if (!x0_dataDot.IsLoaded()) { return; } + SCOPED_GRAPHICS_DEBUG_GROUP("CScanDisplay::Draw", zeus::skGreen); - // No Z-test or write + g_Renderer->SetDepthReadWrite(false, false); g_Renderer->SetViewportOrtho(true, -4096.f, 4096.f); - // Additive alpha + g_Renderer->SetBlendMode_AdditiveAlpha(); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + x0_dataDot->Load(GX_TEXMAP0, EClampMode::Repeat); - const float vpRatio = g_Viewport.xc_height / 480.f; + const float vpRatio = CGraphics::GetViewportHeight() / 480.f; for (CDataDot& dot : xbc_dataDots) { dot.Draw(g_tweakGuiColors->GetScanDataDotColor(), g_tweakGui->GetScanDataDotRadius() * vpRatio); } diff --git a/Runtime/GuiSys/CScanDisplay.hpp b/Runtime/GuiSys/CScanDisplay.hpp index 8d116e081..10949c491 100644 --- a/Runtime/GuiSys/CScanDisplay.hpp +++ b/Runtime/GuiSys/CScanDisplay.hpp @@ -8,7 +8,6 @@ #include "Runtime/rstl.hpp" #include "Runtime/Camera/CCameraFilter.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" #include #include @@ -40,10 +39,9 @@ public: float x20_remTime = 0.f; float x24_alpha = 0.f; float x28_desiredAlpha = 0.f; - CTexturedQuadFilter m_quad; public: - explicit CDataDot(const TLockedToken& dataDotTex) : m_quad(EFilterType::Add, dataDotTex) {} + explicit CDataDot(const TLockedToken& dataDotTex) {} void Update(float dt); void Draw(const zeus::CColor& color, float radius); float GetTransitionFactor() const { return x1c_transDur > 0.f ? x20_remTime / x1c_transDur : 0.f; } diff --git a/Runtime/GuiSys/CSplashScreen.cpp b/Runtime/GuiSys/CSplashScreen.cpp index a1c93f089..834cfbf69 100644 --- a/Runtime/GuiSys/CSplashScreen.cpp +++ b/Runtime/GuiSys/CSplashScreen.cpp @@ -1,27 +1,23 @@ #include "Runtime/GuiSys/CSplashScreen.hpp" -#include - -#include "Runtime/CArchitectureMessage.hpp" -#include "Runtime/CArchitectureQueue.hpp" -#include "Runtime/CSimplePool.hpp" -#include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/Camera/CCameraFilter.hpp" +#include "CArchitectureMessage.hpp" +#include "CArchitectureQueue.hpp" +#include "CSimplePool.hpp" +#include "GameGlobalObjects.hpp" +#include "Graphics/CCubeRenderer.hpp" namespace metaforce { constexpr std::array SplashTextures{"TXTR_NintendoLogo"sv, "TXTR_RetroLogo"sv, "TXTR_DolbyLogo"sv}; CSplashScreen::CSplashScreen(ESplashScreen which) -: CIOWin("SplashScreen") -, x14_which(which) -, m_quad(EFilterType::Blend, g_SimplePool->GetObj(SplashTextures[size_t(which)])) {} +: CIOWin("SplashScreen"), x14_which(which), x28_texture(g_SimplePool->GetObj(SplashTextures[size_t(which)])) {} CIOWin::EMessageReturn CSplashScreen::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) { switch (msg.GetType()) { case EArchMsgType::TimerTick: { if (!x25_textureLoaded) { - if (!m_quad.GetTex().IsLoaded()) + if (!x28_texture.IsLoaded()) return EMessageReturn::Exit; x25_textureLoaded = true; } @@ -56,7 +52,7 @@ void CSplashScreen::Draw() { } SCOPED_GRAPHICS_DEBUG_GROUP("CSplashScreen::Draw", zeus::skGreen); - zeus::CColor color; + zeus::CColor color = zeus::skWhite; if (x14_which == ESplashScreen::Nintendo) { color = zeus::CColor{0.86f, 0.f, 0.f, 1.f}; } @@ -67,13 +63,39 @@ void CSplashScreen::Draw() { color.a() = x18_splashTimeout * 2.f; } - zeus::CRectangle rect; - rect.size.x() = m_quad.GetTex()->GetWidth() / (480.f * g_Viewport.aspect); - rect.size.y() = m_quad.GetTex()->GetHeight() / 480.f; - rect.position.x() = 0.5f - rect.size.x() / 2.f; - rect.position.y() = 0.5f - rect.size.y() / 2.f; + CGraphics::SetAlphaCompare(ERglAlphaFunc::Always, 0, ERglAlphaOp::And, ERglAlphaFunc::Always, 0); + g_Renderer->SetModelMatrix({}); + CGraphics::SetViewPointMatrix({}); + CGraphics::SetTevOp(ERglTevStage::Stage0, CTevCombiners::kEnvModulate); + CGraphics::SetTevOp(ERglTevStage::Stage1, CTevCombiners::kEnvPassthru); + g_Renderer->SetBlendMode_AlphaBlended(); + auto& tex = *x28_texture.GetObj(); + const auto width = tex.GetWidth(); + const auto height = tex.GetHeight(); + tex.Load(GX_TEXMAP0, EClampMode::Clamp); + if (x14_which == ESplashScreen::Nintendo || x14_which == ESplashScreen::Retro) { + const auto x = static_cast(133 - (width - 376) / 2); + const auto y = static_cast(170 - (height - 104) / 2); + CGraphics::SetOrtho(-10.f, 650.f, -5.5f, 484.5f, -1.f, 1.f); + CGraphics::SetCullMode(ERglCullMode::None); + CGraphics::StreamBegin(GX_TRIANGLESTRIP); + CGraphics::StreamColor(color); + CGraphics::StreamTexcoord(0.f, 0.f); + CGraphics::StreamVertex({x, 0.f, y + static_cast(height)}); + CGraphics::StreamTexcoord(0.f, 1.f); + CGraphics::StreamVertex({x, 0.f, y}); + CGraphics::StreamTexcoord(1.f, 0.f); + CGraphics::StreamVertex({x + static_cast(width), 0.f, y + static_cast(height)}); + CGraphics::StreamTexcoord(1.f, 1.f); + CGraphics::StreamVertex({x + static_cast(width), 0.f, y}); + CGraphics::StreamEnd(); + CGraphics::SetCullMode(ERglCullMode::Front); + } else { + // TODO originally uses CGraphics viewport, but Render2D needs scaling fix + CGraphics::Render2D(tex, 0, 0, 640, 448, color); + } - m_quad.draw(color, 1.f, rect); + // Progressive scan options omitted } } // namespace metaforce diff --git a/Runtime/GuiSys/CSplashScreen.hpp b/Runtime/GuiSys/CSplashScreen.hpp index f1feaabcd..996f0a133 100644 --- a/Runtime/GuiSys/CSplashScreen.hpp +++ b/Runtime/GuiSys/CSplashScreen.hpp @@ -3,7 +3,6 @@ #include "Runtime/CIOWin.hpp" #include "Runtime/CToken.hpp" #include "Runtime/Graphics/CTexture.hpp" -#include "Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp" namespace metaforce { @@ -19,7 +18,7 @@ private: // EProgressivePhase x20_progressivePhase = EProgressivePhase::Before; // bool x24_progressiveSelection = true; bool x25_textureLoaded = false; - CTexturedQuadFilterAlpha m_quad; + TLockedToken x28_texture; public: explicit CSplashScreen(ESplashScreen); diff --git a/Runtime/GuiSys/CStringTable.cpp b/Runtime/GuiSys/CStringTable.cpp index 2874e052c..8857670ba 100644 --- a/Runtime/GuiSys/CStringTable.cpp +++ b/Runtime/GuiSys/CStringTable.cpp @@ -1,9 +1,11 @@ #include "Runtime/GuiSys/CStringTable.hpp" -#include - +#include "Runtime/CBasics.hpp" +#include "Runtime/Streams/CInputStream.hpp" #include "Runtime/CToken.hpp" +#include + namespace metaforce { namespace { constexpr std::array languages{ @@ -16,14 +18,15 @@ FourCC CStringTable::mCurrentLanguage = languages[0]; CStringTable::CStringTable(CInputStream& in) { LoadStringTable(in); } void CStringTable::LoadStringTable(CInputStream& in) { - in.readUint32Big(); - in.readUint32Big(); - u32 langCount = in.readUint32Big(); - x0_stringCount = in.readUint32Big(); + in.ReadLong(); + in.ReadLong(); + u32 langCount = in.ReadLong(); + x0_stringCount = in.ReadLong(); std::vector> langOffsets; for (u32 i = 0; i < langCount; ++i) { - FourCC fcc(in.readUint32()); - u32 off = in.readUint32Big(); + FourCC fcc; + in.Get(reinterpret_cast(&fcc), 4); + u32 off = in.ReadLong(); langOffsets.emplace_back(fcc, off); } @@ -45,21 +48,26 @@ void CStringTable::LoadStringTable(CInputStream& in) { if (offset == UINT32_MAX) offset = langOffsets[0].second; - in.seek(offset); + for (u32 i = 0; i < offset; ++i) { + in.ReadChar(); + } - u32 dataLen = in.readUint32Big(); + u32 dataLen = in.ReadLong(); m_bufLen = dataLen; x4_data.reset(new u8[dataLen]); - in.readUBytesToBuf(x4_data.get(), dataLen); + in.Get(x4_data.get(), dataLen); +#if METAFORCE_TARGET_BYTE_ORDER == __ORDER_LITTLE_ENDIAN__ u32* off = reinterpret_cast(x4_data.get()); - for (u32 i = 0; i < x0_stringCount; ++i, ++off) - *off = hecl::SBig(*off); + for (u32 i = 0; i < x0_stringCount; ++i, ++off) { + *off = CBasics::SwapBytes(*off); + } for (u32 i = x0_stringCount * 4; i < dataLen; i += 2) { u16* chr = reinterpret_cast(x4_data.get() + i); - *chr = hecl::SBig(*chr); + *chr = CBasics::SwapBytes(*chr); } +#endif } const char16_t* CStringTable::GetString(s32 str) const { diff --git a/Runtime/GuiSys/CStringTable.hpp b/Runtime/GuiSys/CStringTable.hpp index d122958d3..d500270da 100644 --- a/Runtime/GuiSys/CStringTable.hpp +++ b/Runtime/GuiSys/CStringTable.hpp @@ -10,7 +10,7 @@ class CStringTable { static FourCC mCurrentLanguage; u32 x0_stringCount = 0; std::unique_ptr x4_data; - u32 m_bufLen; + u32 m_bufLen = 0; public: explicit CStringTable(CInputStream& in); diff --git a/Runtime/GuiSys/CTargetingManager.cpp b/Runtime/GuiSys/CTargetingManager.cpp index 1dd481f8c..fa3bd85c8 100644 --- a/Runtime/GuiSys/CTargetingManager.cpp +++ b/Runtime/GuiSys/CTargetingManager.cpp @@ -3,7 +3,7 @@ #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Camera/CGameCamera.hpp" -#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Graphics/CCubeRenderer.hpp" namespace metaforce { @@ -26,10 +26,11 @@ void CTargetingManager::Draw(const CStateManager& mgr, bool hideLockon) { zeus::CTransform camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr); CGraphics::SetViewPointMatrix(camXf); zeus::CFrustum frustum; - frustum.updatePlanes(camXf, zeus::SProjPersp(zeus::degToRad(curCam->GetFov()), g_Viewport.aspect, 1.f, 100.f)); + frustum.updatePlanes(camXf, + zeus::SProjPersp(zeus::degToRad(curCam->GetFov()), CGraphics::GetViewportAspect(), 1.f, 100.f)); g_Renderer->SetClippingPlanes(frustum); - g_Renderer->SetPerspective(curCam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height, curCam->GetNearClipDistance(), - curCam->GetFarClipDistance()); + g_Renderer->SetPerspective(curCam->GetFov(), CGraphics::GetViewportWidth(), CGraphics::GetViewportHeight(), + curCam->GetNearClipDistance(), curCam->GetFarClipDistance()); x0_targetReticule.Draw(mgr, hideLockon); } diff --git a/Runtime/GuiSys/CTextExecuteBuffer.cpp b/Runtime/GuiSys/CTextExecuteBuffer.cpp index bf40e7ea9..3e2ebf0ee 100644 --- a/Runtime/GuiSys/CTextExecuteBuffer.cpp +++ b/Runtime/GuiSys/CTextExecuteBuffer.cpp @@ -12,7 +12,7 @@ namespace metaforce { CTextRenderBuffer CTextExecuteBuffer::BuildRenderBuffer(CGuiWidget::EGuiModelDrawFlags df) const { - CTextRenderBuffer ret(CTextRenderBuffer::EMode::AllocTally, df); + CTextRenderBuffer ret(CTextRenderBuffer::EMode::AllocTally);//, df); { CFontRenderState rendState; @@ -35,7 +35,7 @@ CTextRenderBuffer CTextExecuteBuffer::BuildRenderBufferPage(InstList::const_iter InstList::const_iterator pgStart, InstList::const_iterator pgEnd, CGuiWidget::EGuiModelDrawFlags df) const { - CTextRenderBuffer ret(CTextRenderBuffer::EMode::AllocTally, df); + CTextRenderBuffer ret(CTextRenderBuffer::EMode::AllocTally);//, df); { CFontRenderState rendState; @@ -71,7 +71,7 @@ std::list CTextExecuteBuffer::BuildRenderBufferPages(const ze std::list ret; for (auto it = x0_instList.begin(); it != x0_instList.end();) { - CTextRenderBuffer rbuf(CTextRenderBuffer::EMode::AllocTally, df); + CTextRenderBuffer rbuf(CTextRenderBuffer::EMode::AllocTally);//, df); { CFontRenderState rstate; diff --git a/Runtime/GuiSys/CTextRenderBuffer.cpp b/Runtime/GuiSys/CTextRenderBuffer.cpp index 385cf38d5..8b300d31d 100644 --- a/Runtime/GuiSys/CTextRenderBuffer.cpp +++ b/Runtime/GuiSys/CTextRenderBuffer.cpp @@ -1,5 +1,6 @@ #include "Runtime/GuiSys/CTextRenderBuffer.hpp" +#include "Runtime/Graphics/CGX.hpp" #include "Runtime/Graphics/CGraphics.hpp" #include "Runtime/Graphics/CGraphicsPalette.hpp" #include "Runtime/Graphics/CTexture.hpp" @@ -12,274 +13,344 @@ namespace metaforce { -struct CTextRenderBuffer::BooFontCharacters { - TLockedToken m_font; - hecl::VertexBufferPool::Token m_instBuf; - boo::ObjToken m_dataBinding; - boo::ObjToken m_dataBinding2; - std::vector m_charData; - u32 m_charCount = 0; - bool m_dirty = true; - - BooFontCharacters(const CToken& token) : m_font(token) {} -}; - -struct CTextRenderBuffer::BooImage { - CFontImageDef m_imageDef; - hecl::VertexBufferPool::Token m_instBuf; - std::vector> m_dataBinding; - std::vector> m_dataBinding2; - CTextSupportShader::ImageInstance m_imageData; - bool m_dirty = true; - - BooImage(const CFontImageDef& imgDef, const zeus::CVector2i& offset) : m_imageDef(imgDef) { - m_imageData.SetMetrics(imgDef, offset); - } -}; - -struct CTextRenderBuffer::BooPrimitiveMark { - Command m_cmd; - u32 m_bindIdx; - u32 m_instIdx; - - void SetOpacity(CTextRenderBuffer& rb, float opacity) { - switch (m_cmd) { - case Command::CharacterRender: { - BooFontCharacters& fc = rb.m_fontCharacters[m_bindIdx]; - CTextSupportShader::CharacterInstance& inst = fc.m_charData[m_instIdx]; - inst.m_mulColor.a() = opacity; - fc.m_dirty = true; - break; - } - case Command::ImageRender: { - BooImage& img = rb.m_images[m_bindIdx]; - img.m_imageData.m_color.a() = opacity; - img.m_dirty = true; - break; - } - default: - break; - } - } -}; - CTextRenderBuffer::CTextRenderBuffer(CTextRenderBuffer&&) noexcept = default; -CTextRenderBuffer::CTextRenderBuffer(EMode mode, CGuiWidget::EGuiModelDrawFlags df) : x0_mode(mode), m_drawFlags(df) {} +CTextRenderBuffer::CTextRenderBuffer(EMode mode) : x0_mode(mode) {} CTextRenderBuffer::~CTextRenderBuffer() = default; CTextRenderBuffer& CTextRenderBuffer::operator=(CTextRenderBuffer&&) noexcept = default; -void CTextRenderBuffer::CommitResources() { - if (m_committed) - return; - m_committed = true; +void CTextRenderBuffer::SetPrimitive(const Primitive& prim, s32 idx) { + CMemoryStreamOut out(reinterpret_cast(x34_bytecode.data() + x24_primOffsets[idx]), + x44_blobSize - x24_primOffsets[idx]); + if (prim.x4_command == Command::ImageRender) { + out.WriteUint8(static_cast(Command::ImageRender)); + out.Put(prim.x8_xPos); + out.Put(prim.xa_zPos); + out.Put(prim.xe_imageIndex); + out.Put(prim.x0_color1.toRGBA()); + } else if (prim.x4_command == Command::CharacterRender) { + out.WriteUint8(static_cast(Command::CharacterRender)); + out.Put(prim.x8_xPos); + out.Put(prim.xa_zPos); + out.Put(u16(prim.xc_glyph)); + out.Put(prim.x0_color1.toRGBA()); + } +} - /* Ensure font textures are ready outside transaction */ - for (BooFontCharacters& chs : m_fontCharacters) - chs.m_font->GetTexture(); +CTextRenderBuffer::Primitive CTextRenderBuffer::GetPrimitive(s32 idx) const { + CMemoryInStream in(reinterpret_cast(x34_bytecode.data() + x24_primOffsets[idx]), + x44_blobSize - x24_primOffsets[idx]); + auto cmd = Command(in.ReadChar()); + if (cmd == Command::ImageRender) { + s16 xPos = in.ReadShort(); + s16 zPos = in.ReadShort(); + u8 imageIndex = in.ReadChar(); + CTextColor color(in.ReadUint32()); + return {color, Command::ImageRender, xPos, zPos, u'\0', imageIndex}; + } - CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) { - m_uniBuf = CTextSupportShader::s_Uniforms.allocateBlock(CGraphics::g_BooFactory); - auto uBufInfo = m_uniBuf.getBufferInfo(); - decltype(uBufInfo) uBufInfo2; - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - m_uniBuf2 = CTextSupportShader::s_Uniforms.allocateBlock(CGraphics::g_BooFactory); - uBufInfo2 = m_uniBuf2.getBufferInfo(); + if (cmd == Command::CharacterRender) { + s16 xPos = in.ReadShort(); + s16 zPos = in.ReadShort(); + char16_t glyph = in.ReadUint16(); + CTextColor color(in.ReadUint32()); + + return {color, Command::CharacterRender, xPos, zPos, glyph, 0}; + } + + return {CTextColor(zeus::Comp32(0)), Command::Invalid, 0, 0, u'\0', 0}; +} + +u8* CTextRenderBuffer::GetOutStream() { + VerifyBuffer(); + return reinterpret_cast(x34_bytecode.data()) + x48_curBytecodeOffset; +} + +void CTextRenderBuffer::VerifyBuffer() { + if (x34_bytecode.empty()) { + x34_bytecode.resize(x44_blobSize); + } +} + +void CTextRenderBuffer::SetMode(EMode mode) { x0_mode = mode; } + +int CTextRenderBuffer::GetMatchingPaletteIndex(const CGraphicsPalette& palette) { + for (int i = 0; i < x50_palettes.size(); ++i) { + if (memcmp(x50_palettes[i]->GetPaletteData(), palette.GetPaletteData(), 8) == 0) { + return i; } + } - for (BooFontCharacters& chs : m_fontCharacters) { - chs.m_instBuf = CTextSupportShader::s_CharInsts.allocateBlock(CGraphics::g_BooFactory, chs.m_charCount); - auto iBufInfo = chs.m_instBuf.getBufferInfo(); + return -1; +} - boo::ObjToken uniforms[] = {uBufInfo.first.get()}; - boo::PipelineStage unistages[] = {boo::PipelineStage::Vertex}; - size_t unioffs[] = {size_t(uBufInfo.second)}; - size_t unisizes[] = {sizeof(CTextSupportShader::Uniform)}; - boo::ObjToken texs[] = {chs.m_font->GetTexture()}; - chs.m_dataBinding = ctx.newShaderDataBinding(CTextSupportShader::SelectTextPipeline(m_drawFlags), nullptr, - iBufInfo.first.get(), nullptr, 1, uniforms, unistages, unioffs, - unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second); +CGraphicsPalette* CTextRenderBuffer::GetNextAvailablePalette() { + if (x254_nextPalette < 64) { + x50_palettes.push_back(std::make_unique(EPaletteFormat::RGB5A3, 4)); + } else { + x254_nextPalette = 0; + } + ++x254_nextPalette; + return x50_palettes[x254_nextPalette - 1].get(); +} - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - uniforms[0] = uBufInfo2.first.get(); - unioffs[0] = size_t(uBufInfo2.second); - chs.m_dataBinding2 = ctx.newShaderDataBinding(CTextSupportShader::GetTextAdditiveOverdrawPipeline(), nullptr, - iBufInfo.first.get(), nullptr, 1, uniforms, unistages, unioffs, - unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second); - } - } +u32 CTextRenderBuffer::GetCurLen() { + VerifyBuffer(); + return x44_blobSize - x48_curBytecodeOffset; +} - for (BooImage& img : m_images) { - img.m_instBuf = CTextSupportShader::s_ImgInsts.allocateBlock(CGraphics::g_BooFactory, 1); - auto iBufInfo = img.m_instBuf.getBufferInfo(); - - boo::ObjToken uniforms[] = {uBufInfo.first.get()}; - boo::PipelineStage unistages[] = {boo::PipelineStage::Vertex}; - size_t unioffs[] = {size_t(uBufInfo.second)}; - size_t unisizes[] = {sizeof(CTextSupportShader::Uniform)}; - img.m_dataBinding.reserve(img.m_imageDef.x4_texs.size()); - for (TToken& tex : img.m_imageDef.x4_texs) { - boo::ObjToken texs[] = {tex->GetBooTexture()}; - texs[0]->setClampMode(boo::TextureClampMode::ClampToEdge); - img.m_dataBinding.push_back(ctx.newShaderDataBinding( - CTextSupportShader::SelectImagePipeline(m_drawFlags), nullptr, iBufInfo.first.get(), nullptr, 1, uniforms, - unistages, unioffs, unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second)); - } - - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - uniforms[0] = uBufInfo2.first.get(); - unioffs[0] = size_t(uBufInfo2.second); - img.m_dataBinding2.reserve(img.m_imageDef.x4_texs.size()); - for (TToken& tex : img.m_imageDef.x4_texs) { - boo::ObjToken texs[] = {tex->GetBooTexture()}; - img.m_dataBinding2.push_back(ctx.newShaderDataBinding( - CTextSupportShader::GetImageAdditiveOverdrawPipeline(), nullptr, iBufInfo.first.get(), nullptr, 1, - uniforms, unistages, unioffs, unisizes, 1, texs, nullptr, nullptr, 0, iBufInfo.second)); +void CTextRenderBuffer::Render(const zeus::CColor& color, float time) { + x4c_activeFont = -1; + x4d_activePalette = -1; + CMemoryInStream in(x34_bytecode.data(), x44_blobSize); + while (in.GetReadPosition() < x44_blobSize) { + auto cmd = static_cast(in.ReadChar()); + if (cmd == Command::FontChange) { + x4c_activeFont = x4e_queuedFont = in.ReadChar(); + } else if (cmd == Command::CharacterRender) { + if (x4e_queuedFont != -1) { + auto font = x4_fonts[x4e_queuedFont]; + if (font) { + font->SetupRenderState(); + x4e_queuedFont = -1; } } - } - return true; - } BooTrace); -} - -void CTextRenderBuffer::SetMode(EMode mode) { - if (mode == EMode::BufferFill) { - m_images.reserve(m_imagesCount); - for (BooFontCharacters& fc : m_fontCharacters) - fc.m_charData.reserve(fc.m_charCount); - } - m_activeFontCh = -1; - x0_mode = mode; -} - -void CTextRenderBuffer::SetPrimitiveOpacity(int idx, float opacity) { - m_primitiveMarks[idx].SetOpacity(*this, opacity); -} - -u32 CTextRenderBuffer::GetPrimitiveCount() const { return m_primitiveMarks.size(); } - -void CTextRenderBuffer::Render(const zeus::CColor& col, float time) { - CommitResources(); - - const zeus::CMatrix4f mv = CGraphics::g_GXModelView.toMatrix4f(); - const zeus::CMatrix4f proj = CGraphics::GetPerspectiveProjectionMatrix(true); - const zeus::CMatrix4f mat = proj * mv; - - m_uniBuf.access() = CTextSupportShader::Uniform{mat, col}; - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - zeus::CColor colPremul = col * col.a(); - colPremul.a() = col.a(); - m_uniBuf2.access() = CTextSupportShader::Uniform{mat, colPremul}; - } - - for (BooFontCharacters& chs : m_fontCharacters) { - if (chs.m_charData.size()) { - if (chs.m_dirty) { - std::memmove(chs.m_instBuf.access(), chs.m_charData.data(), - sizeof(CTextSupportShader::CharacterInstance) * chs.m_charData.size()); - chs.m_dirty = false; + if (x4f_queuedPalette != -1) { + x50_palettes[x4f_queuedPalette]->Load(); + x4f_queuedPalette = -1; } - CGraphics::SetShaderDataBinding(chs.m_dataBinding); - CGraphics::DrawInstances(0, 4, chs.m_charData.size()); - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - CGraphics::SetShaderDataBinding(chs.m_dataBinding2); - CGraphics::DrawInstances(0, 4, chs.m_charData.size()); + + s16 offX = in.ReadShort(); + s16 offY = in.ReadShort(); + char16_t chr = in.ReadShort(); + zeus::CColor chrColor(static_cast(in.ReadLong())); + if (x4c_activeFont != -1) { + auto font = x4_fonts[x4c_activeFont]; + if (font && font->GetGlyph(chr) != nullptr) { + const auto* glyph = font->GetGlyph(chr); + CGX::SetTevKColor(GX_KCOLOR0, chrColor * color); + CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); + { + GXPosition3f32(offX, 0.f, offY); + GXTexCoord2f32(glyph->GetStartU(), glyph->GetStartV()); + GXPosition3f32(offX + glyph->GetCellWidth(), 0.f, offY); + GXTexCoord2f32(glyph->GetEndU(), glyph->GetStartV()); + GXPosition3f32(offX, 0.f, offY + glyph->GetCellHeight()); + GXTexCoord2f32(glyph->GetStartU(), glyph->GetEndV()); + GXPosition3f32(offX + glyph->GetCellWidth(), 0.f, offY + glyph->GetCellHeight()); + GXTexCoord2f32(glyph->GetEndU(), glyph->GetEndV()); + } + CGX::End(); + } } + } else if (cmd == Command::ImageRender) { + s16 offX = in.ReadShort(); + s16 offY = in.ReadShort(); + u8 imageIdx = in.ReadChar(); + zeus::CColor imageColor(static_cast(in.ReadLong())); + auto imageDef = x14_images[imageIdx]; + auto tex = imageDef.x4_texs[static_cast(time * imageDef.x0_fps) % imageDef.x4_texs.size()]; + if (tex) { + tex->Load(GX_TEXMAP0, EClampMode::Clamp); + float width = imageDef.x4_texs.front()->GetWidth() * imageDef.x14_cropFactor.x(); + float height = imageDef.x4_texs.front()->GetHeight() * imageDef.x14_cropFactor.y(); + float cropXHalf = imageDef.x14_cropFactor.x() * 0.5f; + float cropYHalf = imageDef.x14_cropFactor.y() * 0.5f; + + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); + CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_KONST, GX_CC_ZERO); + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_TEXA, GX_CA_KONST, GX_CA_ZERO); + CGX::SetStandardTevColorAlphaOp(GX_TEVSTAGE0); + constexpr std::array skVtxDesc{ + GXVtxDescList{GX_VA_POS, GX_DIRECT}, + GXVtxDescList{GX_VA_TEX0, GX_DIRECT}, + GXVtxDescList{GX_VA_NULL, GX_NONE}, + }; + CGX::SetVtxDescv(skVtxDesc.data()); + CGX::SetNumChans(0); + CGX::SetNumTexGens(1); + CGX::SetNumTevStages(1); + CGX::SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + CGX::SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY, false, GX_PTIDENTITY); + CGX::SetTevKColor(GX_KCOLOR0, imageColor * color); + CGX::Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 4); + { + GXPosition3f32(offX, 0.f, offY); + GXTexCoord2f32(0.5f - cropXHalf, 0.5f + cropYHalf); + GXPosition3f32(offX + width, 0.f, offY); + GXTexCoord2f32(0.5f + cropXHalf, 0.5f + cropYHalf); + GXPosition3f32(offX, 0.f, offY + height); + GXTexCoord2f32(0.5f - cropXHalf, 0.5f - cropYHalf); + GXPosition3f32(offX + width, 0.f, offY + height); + GXTexCoord2f32(0.5f + cropXHalf, 0.5f - cropYHalf); + } + CGX::End(); + x4e_queuedFont = x4c_activeFont; + x4f_queuedPalette = x4d_activePalette; + } + } else if (cmd == Command::PaletteChange) { + x4d_activePalette = x4f_queuedPalette = in.ReadChar(); } } +} - for (BooImage& img : m_images) { - if (img.m_dirty) { - *img.m_instBuf.access() = img.m_imageData; - img.m_dirty = false; - } - const int idx = int(img.m_imageDef.x0_fps * time) % img.m_dataBinding.size(); - CGraphics::SetShaderDataBinding(img.m_dataBinding[idx]); - CGraphics::DrawInstances(0, 4, 1); - if (m_drawFlags == CGuiWidget::EGuiModelDrawFlags::AlphaAdditiveOverdraw) { - CGraphics::SetShaderDataBinding(img.m_dataBinding2[idx]); - CGraphics::DrawInstances(0, 4, 1); +void CTextRenderBuffer::AddPaletteChange(const CGraphicsPalette& palette) { + if (x0_mode == EMode::BufferFill) { + { + u8* buf = GetOutStream(); + CMemoryStreamOut out(buf, GetCurLen()); + s32 paletteIndex = GetMatchingPaletteIndex(palette); + if (paletteIndex == -1) { + GetNextAvailablePalette(); + paletteIndex = x254_nextPalette - 1; + CGraphicsPalette* destPalette = x50_palettes[x254_nextPalette - 1].get(); + u16* data = destPalette->Lock(); + memcpy(data, palette.GetPaletteData(), 8); + destPalette->UnLock(); + } + out.WriteUint8(static_cast(Command::PaletteChange)); + out.WriteUint8(paletteIndex); + x48_curBytecodeOffset += out.GetNumWrites(); } + } else { + x44_blobSize += 2; } } void CTextRenderBuffer::AddImage(const zeus::CVector2i& offset, const CFontImageDef& image) { - if (x0_mode == EMode::AllocTally) - m_primitiveMarks.push_back({Command::ImageRender, m_imagesCount++, 0}); - else - m_images.emplace_back(image, offset); -} - -void CTextRenderBuffer::AddCharacter(const zeus::CVector2i& offset, char16_t ch, const zeus::CColor& color) { - if (m_activeFontCh == UINT32_MAX) - return; - BooFontCharacters& chs = m_fontCharacters[m_activeFontCh]; - if (x0_mode == EMode::AllocTally) - m_primitiveMarks.push_back({Command::CharacterRender, m_activeFontCh, chs.m_charCount++}); - else { - const CGlyph* glyph = chs.m_font.GetObj()->GetGlyph(ch); - - CTextSupportShader::CharacterInstance& inst = chs.m_charData.emplace_back(); - inst.SetMetrics(*glyph, offset); - inst.m_fontColor = m_main * color; - inst.m_outlineColor = m_outline * color; - inst.m_mulColor = zeus::skWhite; + if (x0_mode == EMode::BufferFill) { + CMemoryStreamOut out(GetOutStream(), GetCurLen()); + x24_primOffsets.reserve(x24_primOffsets.size() + 1); + u32 primCap = x24_primOffsets.capacity(); + if (x24_primOffsets.capacity() <= x24_primOffsets.size()) { + x24_primOffsets.reserve(primCap != 0 ? primCap * 2 : 4); + } + x24_primOffsets.push_back(x48_curBytecodeOffset); + x14_images.reserve(x14_images.size() + 1); + u32 imgIdx = x14_images.size(); + x14_images.push_back(image); + out.WriteUint8(static_cast(Command::ImageRender)); + out.WriteShort(offset.x); + out.WriteShort(offset.y); + out.WriteUint8(imgIdx); + out.WriteLong(zeus::skWhite.toRGBA()); + x48_curBytecodeOffset += out.GetNumWrites(); + } else { + x44_blobSize += 10; } } -void CTextRenderBuffer::AddPaletteChange(const zeus::CColor& main, const zeus::CColor& outline) { - m_main = main; - m_outline = outline; +void CTextRenderBuffer::AddCharacter(const zeus::CVector2i& offset, char16_t ch, const CTextColor& color) { + if (x0_mode == EMode::BufferFill) { + CMemoryStreamOut out(GetOutStream(), GetCurLen()); + x24_primOffsets.reserve(x24_primOffsets.size() + 1); + u32 primCap = x24_primOffsets.capacity(); + if (x24_primOffsets.capacity() <= x24_primOffsets.size()) { + x24_primOffsets.reserve(primCap != 0 ? primCap * 2 : 4); + } + x24_primOffsets.push_back(x48_curBytecodeOffset); + out.WriteUint8(u32(Command::CharacterRender)); + out.WriteShort(offset.x); + out.WriteShort(offset.y); + out.WriteShort(ch); + out.WriteUint32(color.toRGBA()); + x48_curBytecodeOffset += out.GetNumWrites(); + } else { + x44_blobSize += 11; + } } void CTextRenderBuffer::AddFontChange(const TToken& font) { - for (size_t i = 0; i < m_fontCharacters.size(); ++i) { - BooFontCharacters& chs = m_fontCharacters[i]; - if (*chs.m_font.GetObjectTag() == *font.GetObjectTag()) { - m_activeFontCh = i; - return; + if (x0_mode == EMode::BufferFill) { + CMemoryStreamOut out(GetOutStream(), GetCurLen()); + u32 fontCount = x4_fonts.size(); + bool found = false; + u8 fontIndex = 0; + if (fontCount > 0) { + for (const auto& tok : x4_fonts) { + if (tok.GetObjectReference() == font.GetObjectReference()) { + out.WriteUint8(static_cast(Command::FontChange)); + out.WriteUint8(fontIndex); + found = true; + break; + } + ++fontIndex; + } } - } - m_activeFontCh = m_fontCharacters.size(); - m_fontCharacters.emplace_back(font); + if (!found) { + x4_fonts.reserve(x4_fonts.size() + 1); + u32 fontIdx = x4_fonts.size(); + x4_fonts.push_back(font); + out.WriteUint8(static_cast(Command::FontChange)); + out.WriteUint8(fontIdx); + } + x48_curBytecodeOffset += out.GetNumWrites(); + } else { + x44_blobSize += 2; + } } -bool CTextRenderBuffer::HasSpaceAvailable(const zeus::CVector2i& origin, const zeus::CVector2i& extent) const { +bool CTextRenderBuffer::HasSpaceAvailable(const zeus::CVector2i& origin, const zeus::CVector2i& extent) { std::pair bounds = AccumulateTextBounds(); - if (bounds.first.x > bounds.second.x) + if (bounds.first.x > bounds.second.x) { return true; + } - if (0 < origin.y) + if (0 < origin.y) { return false; + } zeus::CVector2i size = bounds.second - bounds.first; return size.y <= extent.y; } -std::pair CTextRenderBuffer::AccumulateTextBounds() const { - std::pair ret = - std::make_pair(zeus::CVector2i{INT_MAX, INT_MAX}, zeus::CVector2i{INT_MIN, INT_MIN}); +std::pair CTextRenderBuffer::AccumulateTextBounds() { + zeus::CVector2i min{INT_MAX, INT_MAX}; + zeus::CVector2i max{INT_MIN, INT_MIN}; + CMemoryInStream in(x34_bytecode.data(), x44_blobSize); - for (const BooFontCharacters& chars : m_fontCharacters) { - for (const CTextSupportShader::CharacterInstance& charInst : chars.m_charData) { - ret.first.x = std::min(ret.first.x, int(charInst.m_pos[0].x())); - ret.first.y = std::min(ret.first.y, int(charInst.m_pos[0].z())); - ret.second.x = std::max(ret.second.x, int(charInst.m_pos[3].x())); - ret.second.y = std::max(ret.second.y, int(charInst.m_pos[3].z())); + while (in.GetReadPosition() < x48_curBytecodeOffset) { + auto cmd = static_cast(in.ReadChar()); + if (cmd == Command::FontChange) { + x4c_activeFont = in.ReadChar(); + } else if (cmd == Command::CharacterRender) { + u16 offX = in.ReadShort(); + u16 offY = in.ReadShort(); + char16_t chr = in.ReadShort(); + in.ReadLong(); + if (x4c_activeFont != -1) { + auto font = x4_fonts[x4c_activeFont]; + if (font) { + const auto* glyph = font->GetGlyph(chr); + if (glyph != nullptr) { + max.x = std::max(max.x, offX + glyph->GetCellWidth()); + max.y = std::max(max.y, offY + glyph->GetCellHeight()); + min.x = std::min(min.x, offX); + min.y = std::min(min.y, offY); + } + } + } + } else if (cmd == Command::ImageRender) { + u16 offX = in.ReadShort(); + u16 offY = in.ReadShort(); + u8 imageIdx = in.ReadChar(); + in.ReadLong(); + const auto& image = x14_images[imageIdx]; + max.x = std::max(max.x, offX + static_cast(static_cast(image.x4_texs.front()->GetWidth()) * + image.x14_cropFactor.x())); + max.y = std::max(max.y, offY + static_cast(static_cast(image.x4_texs.front()->GetHeight()) * + image.x14_cropFactor.y())); + min.x = std::min(min.x, offX); + min.y = std::min(min.y, offY); + } else if (cmd == Command::PaletteChange) { + in.ReadChar(); } } - - for (const BooImage& imgs : m_images) { - ret.first.x = std::min(ret.first.x, int(imgs.m_imageData.m_pos[0].x())); - ret.first.y = std::min(ret.first.y, int(imgs.m_imageData.m_pos[0].z())); - ret.second.x = std::max(ret.second.x, int(imgs.m_imageData.m_pos[3].x())); - ret.second.y = std::max(ret.second.y, int(imgs.m_imageData.m_pos[3].z())); - } - - return ret; + return {min, max}; } } // namespace metaforce diff --git a/Runtime/GuiSys/CTextRenderBuffer.hpp b/Runtime/GuiSys/CTextRenderBuffer.hpp index c73290dab..d2f08d2c1 100644 --- a/Runtime/GuiSys/CTextRenderBuffer.hpp +++ b/Runtime/GuiSys/CTextRenderBuffer.hpp @@ -9,11 +9,6 @@ #include "Runtime/GuiSys/CFontImageDef.hpp" #include "Runtime/GuiSys/CGuiWidget.hpp" -#include - -#include -#include - #include #include #include @@ -32,87 +27,56 @@ class CTextRenderBuffer { friend class CTextSupportShader; public: - enum class Command { CharacterRender, ImageRender, FontChange, PaletteChange }; -#if 0 - struct Primitive - { - CTextColor x0_color1; - Command x4_command; - u16 x8_xPos; - u16 xa_zPos; - char16_t xc_glyph; - u8 xe_imageIndex; - }; -#endif + enum class Command { CharacterRender, ImageRender, FontChange, PaletteChange, Invalid = -1 }; + struct Primitive { + CTextColor x0_color1; + Command x4_command; + s16 x8_xPos; + s16 xa_zPos; + char16_t xc_glyph; + u8 xe_imageIndex; + }; enum class EMode { AllocTally, BufferFill }; private: EMode x0_mode; -#if 0 - std::vector> x4_fonts; - std::vector x14_images; - std::vector x24_primOffsets; - std::vector x34_bytecode; - u32 x44_blobSize = 0; - u32 x48_curBytecodeOffset = 0; - u8 x4c_activeFont; - u32 x50_paletteCount = 0; - std::array, 64> x54_palettes; - u32 x254_nextPalette = 0; - -#else - /* Boo-specific text-rendering functionality */ - hecl::UniformBufferPool::Token m_uniBuf; - hecl::UniformBufferPool::Token m_uniBuf2; - - struct BooFontCharacters; - std::vector m_fontCharacters; - - struct BooImage; - std::vector m_images; - - struct BooPrimitiveMark; - std::vector m_primitiveMarks; - u32 m_imagesCount = 0; - u32 m_activeFontCh = UINT32_MAX; - - zeus::CColor m_main; - zeus::CColor m_outline = zeus::skBlack; - - CGuiWidget::EGuiModelDrawFlags m_drawFlags; - - bool m_committed = false; - void CommitResources(); -#endif + std::vector> x4_fonts; + std::vector x14_images; + std::vector x24_primOffsets; + std::vector x34_bytecode; + u32 x44_blobSize = 0; + u32 x48_curBytecodeOffset = 0; + s8 x4c_activeFont = -1; + s8 x4d_activePalette = -1; + s8 x4e_queuedFont = -1; + s8 x4f_queuedPalette = -1; + rstl::reserved_vector, 64> x50_palettes; + s32 x254_nextPalette = 0; public: CTextRenderBuffer(CTextRenderBuffer&& other) noexcept; - CTextRenderBuffer(EMode mode, CGuiWidget::EGuiModelDrawFlags df); + CTextRenderBuffer(EMode mode); ~CTextRenderBuffer(); CTextRenderBuffer& operator=(CTextRenderBuffer&& other) noexcept; -#if 0 - void SetPrimitive(const Primitive&, int); - Primitive GetPrimitive(int) const; - void GetOutStream(); - void VerifyBuffer(); - int GetMatchingPaletteIndex(const CGraphicsPalette& palette); - CGraphicsPalette* GetNextAvailablePalette(); - void AddPaletteChange(const CGraphicsPalette& palette); -#else - void SetPrimitiveOpacity(int idx, float opacity); - u32 GetPrimitiveCount() const; -#endif + void SetPrimitive(const Primitive&, int); + [[nodiscard]] Primitive GetPrimitive(int) const; + [[nodiscard]] u32 GetPrimitiveCount() const { return x24_primOffsets.size(); } + [[nodiscard]] u8* GetOutStream(); + [[nodiscard]] u32 GetCurLen(); + void VerifyBuffer(); + int GetMatchingPaletteIndex(const CGraphicsPalette& palette); + [[nodiscard]] CGraphicsPalette* GetNextAvailablePalette(); + void AddPaletteChange(const CGraphicsPalette& palette); void SetMode(EMode mode); - void Render(const zeus::CColor& col, float time); + void Render(const CTextColor& col, float time); void AddImage(const zeus::CVector2i& offset, const CFontImageDef& image); - void AddCharacter(const zeus::CVector2i& offset, char16_t ch, const zeus::CColor& color); - void AddPaletteChange(const zeus::CColor& main, const zeus::CColor& outline); + void AddCharacter(const zeus::CVector2i& offset, char16_t ch, const CTextColor& color); void AddFontChange(const TToken& font); - bool HasSpaceAvailable(const zeus::CVector2i& origin, const zeus::CVector2i& extent) const; - std::pair AccumulateTextBounds() const; + [[nodiscard]] bool HasSpaceAvailable(const zeus::CVector2i& origin, const zeus::CVector2i& extent); + [[nodiscard]] std::pair AccumulateTextBounds(); }; } // namespace metaforce diff --git a/Runtime/IFactory.hpp b/Runtime/IFactory.hpp index d82e1247d..757fb0ae1 100644 --- a/Runtime/IFactory.hpp +++ b/Runtime/IFactory.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include diff --git a/Runtime/IMain.hpp b/Runtime/IMain.hpp index a4e5a2feb..de40c2b5e 100644 --- a/Runtime/IMain.hpp +++ b/Runtime/IMain.hpp @@ -1,22 +1,35 @@ #pragma once #include "Runtime/RetroTypes.hpp" - -#include -#include -#include -#include -#include "DataSpec/DNACommon/MetaforceVersionInfo.hpp" #include "Runtime/CMainFlowBase.hpp" +#include "Runtime/ConsoleVariables/FileStoreManager.hpp" -namespace hecl { -class Console; -class CVarManager; -} // namespace hecl +//#include +//#include namespace metaforce { -using ERegion = DataSpec::ERegion; -using EGame = DataSpec::EGame; +class Console; +class CVarManager; +enum class ERegion { USA, JPN, PAL, KOR }; +enum class EGame { + Invalid = 0, + MetroidPrime1, + MetroidPrime2, + MetroidPrime3, + MetroidPrimeTrilogy, +}; +enum class EPlatform { + GameCube, + Wii, +}; + +struct MetaforceVersionInfo { + std::string version; + ERegion region; + EGame game; + EPlatform platform; + std::string gameTitle; +}; class CStopwatch; enum class EGameplayResult { None, Win, Lose, Playing }; @@ -24,23 +37,21 @@ enum class EGameplayResult { None, Win, Lose, Playing }; class IMain { public: virtual ~IMain() = default; - virtual void Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarManager* cvarMgr, boo::IWindow* window, - boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) = 0; + virtual std::string Init(int argc, char** argv, const FileStoreManager& storeMgr, CVarManager* cvarMgr) = 0; virtual void Draw() = 0; virtual bool Proc(float dt) = 0; virtual void Shutdown() = 0; - virtual boo::IWindow* GetMainWindow() const = 0; virtual EClientFlowStates GetFlowState() const = 0; virtual void SetFlowState(EClientFlowStates) = 0; virtual size_t GetExpectedIdSize() const = 0; - virtual void WarmupShaders() = 0; - virtual hecl::Console* Console() const = 0; virtual EGame GetGame() const = 0; virtual ERegion GetRegion() const = 0; virtual bool IsPAL() const = 0; virtual bool IsJapanese() const = 0; virtual bool IsUSA() const = 0; + virtual bool IsKorean() const = 0; virtual bool IsTrilogy() const = 0; + virtual std::string GetGameTitle() const = 0; virtual std::string_view GetVersionString() const = 0; virtual void Quit() = 0; virtual bool IsPaused() const = 0; diff --git a/Runtime/IOStreams.cpp b/Runtime/IOStreams.cpp deleted file mode 100644 index da890cd47..000000000 --- a/Runtime/IOStreams.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include "Runtime/IOStreams.hpp" -#include - -namespace metaforce { - -#define DUMP_BITS 0 - -#if DUMP_BITS -static void PrintBinary(u32 val, u32 count) { - for (u32 i = 0; i < count; ++i) { - fmt::print(FMT_STRING("{}"), (val >> (count - i - 1)) & 0x1); - } -} -#endif - -/*! - * \brief CBitStreamReader::ReadBit - * Reads and decodes an encoded value from a bitstream. - * \param bitCount How many bits to read - * \return s32 The encoded value - */ -s32 CBitStreamReader::ReadEncoded(u32 bitCount) { -#if DUMP_BITS - const auto pos = position(); - const auto boff = x20_bitOffset; -#endif - - u32 ret = 0; - const s32 shiftAmt = x20_bitOffset - s32(bitCount); - if (shiftAmt < 0) { - /* OR in remaining bits of cached value */ - u32 mask = bitCount == 32 ? UINT32_MAX : ((1U << bitCount) - 1); - ret |= (x1c_val << u32(-shiftAmt)) & mask; - - /* Load in exact number of bytes remaining */ - auto loadDiv = std::div(-shiftAmt, 8); - if (loadDiv.rem) - ++loadDiv.quot; - readUBytesToBuf(reinterpret_cast(&x1c_val) + 4 - loadDiv.quot, loadDiv.quot); - x1c_val = hecl::SBig(x1c_val); - - /* New bit offset */ - x20_bitOffset = loadDiv.quot * 8 + shiftAmt; - - /* OR in next bits */ - mask = (1U << u32(-shiftAmt)) - 1; - ret |= (x1c_val >> x20_bitOffset) & mask; - } else { - /* OR in bits of cached value */ - const u32 mask = bitCount == 32 ? UINT32_MAX : ((1U << bitCount) - 1); - ret |= (x1c_val >> u32(shiftAmt)) & mask; - - /* New bit offset */ - x20_bitOffset -= bitCount; - } - -#if DUMP_BITS - std::fputs("READ ", stdout); - PrintBinary(ret, bitCount); - fmt::print(FMT_STRING(" {} {}\n"), pos, boff); -#endif - - return ret; -} - -void CBitStreamWriter::WriteEncoded(u32 val, u32 bitCount) { -#if DUMP_BITS - std::fputs("WRITE ", stdout); - PrintBinary(val, bitCount); - fmt::print(FMT_STRING(" {} {}\n"), position(), x18_bitOffset); -#endif - - const s32 shiftAmt = x18_bitOffset - s32(bitCount); - if (shiftAmt < 0) { - /* OR remaining bits to cached value */ - const u32 mask = (1U << x18_bitOffset) - 1; - x14_val |= (val >> u32(-shiftAmt)) & mask; - - /* Write out 32-bits */ - x14_val = hecl::SBig(x14_val); - writeBytes(&x14_val, sizeof(x14_val)); - - /* Cache remaining bits */ - x18_bitOffset = 0x20 + shiftAmt; - x14_val = val << x18_bitOffset; - } else { - /* OR bits to cached value */ - const u32 mask = bitCount == 32 ? UINT32_MAX : ((1U << bitCount) - 1); - x14_val |= (val & mask) << u32(shiftAmt); - - /* New bit offset */ - x18_bitOffset -= bitCount; - } -} - -void CBitStreamWriter::Flush() { - if (x18_bitOffset >= 0x20) { - return; - } - - auto pos = std::div(0x20 - s32(x18_bitOffset), 8); - if (pos.rem != 0) { - ++pos.quot; - } - - x14_val = hecl::SBig(x14_val); - writeBytes(&x14_val, pos.quot); - x18_bitOffset = 0x20; - x14_val = 0; -} - -CZipInputStream::CZipInputStream(std::unique_ptr&& strm) -: x24_compBuf(new u8[4096]), x28_strm(std::move(strm)) { - x30_zstrm.next_in = x24_compBuf.get(); - x30_zstrm.avail_in = 0; - x30_zstrm.zalloc = [](void*, u32 c, u32 n) -> void* { return new u8[size_t{c} * size_t{n}]; }; - x30_zstrm.zfree = [](void*, void* buf) { delete[] static_cast(buf); }; - inflateInit(&x30_zstrm); -} - -CZipInputStream::~CZipInputStream() { inflateEnd(&x30_zstrm); } - -atUint64 CZipInputStream::readUBytesToBuf(void* buf, atUint64 len) { - x30_zstrm.next_out = static_cast(buf); - x30_zstrm.avail_out = len; - x30_zstrm.total_out = 0; - while (x30_zstrm.avail_out != 0) { - if (x30_zstrm.avail_in == 0) { - atUint64 readSz = x28_strm->readUBytesToBuf(x24_compBuf.get(), 4096); - x30_zstrm.avail_in = readSz; - x30_zstrm.next_in = x24_compBuf.get(); - } - int inflateRet = inflate(&x30_zstrm, Z_NO_FLUSH); - if (inflateRet != Z_OK) - break; - } - return x30_zstrm.total_out; -} - -} // namespace metaforce diff --git a/Runtime/IOStreams.hpp b/Runtime/IOStreams.hpp deleted file mode 100644 index 6aef9d55c..000000000 --- a/Runtime/IOStreams.hpp +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include - -#include "Runtime/GCNTypes.hpp" - -#include -#include -#include -#include -#ifdef URDE_ZIP_INPUT_STREAM -#include -#endif - -namespace metaforce { -using CInputStream = athena::io::IStreamReader; -using COutputStream = athena::io::IStreamWriter; - -struct CBitStreamReader : athena::io::MemoryReader { - u32 x1c_val = 0; - u32 x20_bitOffset = 0; - -public: - static constexpr u32 GetBitCount(u32 maxVal) { - u32 ret = 0; - while (maxVal != 0) { - maxVal /= 2; - ret++; - } - - return ret; - } - - CBitStreamReader(const void* data, atUint64 length) : MemoryReader(data, length) {} - - s32 ReadEncoded(u32 key); -}; - -class CBitStreamWriter : public athena::io::MemoryWriter { - u32 x14_val = 0; - u32 x18_bitOffset = 0x20; - -public: - static constexpr u32 GetBitCount(u32 maxVal) { return CBitStreamReader::GetBitCount(maxVal); } - - explicit CBitStreamWriter(atUint8* data = nullptr, atUint64 length = 0x10) : MemoryWriter(data, length) {} - - void WriteEncoded(u32 val, u32 bitCount); - - void Flush(); - - ~CBitStreamWriter() override { Flush(); } -}; - -using CMemoryInStream = athena::io::MemoryReader; -using CMemoryOutStream = athena::io::MemoryWriter; - -#ifdef URDE_ZIP_INPUT_STREAM -class CZipInputStream : public CInputStream { - std::unique_ptr x24_compBuf; - std::unique_ptr x28_strm; - z_stream x30_zstrm = {}; - -public: - explicit CZipInputStream(std::unique_ptr&& strm); - ~CZipInputStream() override; - atUint64 readUBytesToBuf(void* buf, atUint64 len) override; - void seek(atInt64, athena::SeekOrigin) override {} - atUint64 position() const override { return 0; } - atUint64 length() const override { return 0; } -}; -#endif - -} // namespace metaforce diff --git a/Runtime/ITweak.hpp b/Runtime/ITweak.hpp deleted file mode 100644 index 160d9a046..000000000 --- a/Runtime/ITweak.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -namespace metaforce { -class ITweak { -public: - virtual ~ITweak() = default; -}; -} // namespace metaforce diff --git a/Runtime/ImGuiConsole.cpp b/Runtime/ImGuiConsole.cpp index c6c660b27..f74173cc7 100644 --- a/Runtime/ImGuiConsole.cpp +++ b/Runtime/ImGuiConsole.cpp @@ -1,14 +1,26 @@ +#include +#define IM_VEC2_CLASS_EXTRA \ + ImVec2(const zeus::CVector2f& v) { \ + x = v.x(); \ + y = v.y(); \ + } \ + operator zeus::CVector2f() const { return zeus::CVector2f{x, y}; } #include "ImGuiConsole.hpp" #include "../version.h" #include "MP1/MP1.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" -#include "Runtime/World/CPlayer.hpp" #include "Runtime/ImGuiEntitySupport.hpp" +#include "Runtime/World/CPlayer.hpp" #include "ImGuiEngine.hpp" #include "magic_enum.hpp" +#ifdef NATIVEFILEDIALOG_SUPPORTED +#include +#endif + +#include #include @@ -17,14 +29,34 @@ namespace ImGui { void ClearIniSettings(); } // namespace ImGui +namespace aurora::gfx { +extern std::atomic_uint32_t queuedPipelines; +extern std::atomic_uint32_t createdPipelines; + +extern size_t g_drawCallCount; +extern size_t g_mergedDrawCallCount; +extern size_t g_lastVertSize; +extern size_t g_lastUniformSize; +extern size_t g_lastIndexSize; +extern size_t g_lastStorageSize; +} // namespace aurora::gfx + #include "TCastTo.hpp" // Generated file, do not modify include path namespace metaforce { +static logvisor::Module Log{"Console"}; std::array ImGuiConsole::entities; std::set ImGuiConsole::inspectingEntities; ImGuiPlayerLoadouts ImGuiConsole::loadouts; +ImGuiConsole::ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons) +: m_cvarMgr(cvarMgr), m_cvarCommons(cvarCommons) { +#ifdef NATIVEFILEDIALOG_SUPPORTED + NFD::Init(); +#endif +} + void ImGuiStringViewText(std::string_view text) { // begin()/end() do not work on MSVC ImGui::TextUnformatted(text.data(), text.data() + text.size()); @@ -32,11 +64,19 @@ void ImGuiStringViewText(std::string_view text) { void ImGuiTextCenter(std::string_view text) { ImGui::NewLine(); - float fontSize = ImGui::GetFontSize() * float(text.size()) / 2; + float fontSize = ImGui::CalcTextSize(text.data(), text.data() + text.size()).x; ImGui::SameLine(ImGui::GetWindowSize().x / 2 - fontSize + fontSize / 2); ImGuiStringViewText(text); } +bool ImGuiButtonCenter(std::string_view text) { + ImGui::NewLine(); + float fontSize = ImGui::CalcTextSize(text.data(), text.data() + text.size()).x; + fontSize += ImGui::GetStyle().FramePadding.x; + ImGui::SameLine(ImGui::GetWindowSize().x / 2 - fontSize + fontSize / 2); + return ImGui::Button(text.data()); +} + static std::unordered_map> dummyWorlds; static std::unordered_map> stringTables; @@ -47,7 +87,7 @@ std::string ImGuiLoadStringTable(CAssetId stringId, int idx) { if (!stringTables.contains(stringId)) { stringTables[stringId] = g_SimplePool->GetObj(SObjectTag{SBIG('STRG'), stringId}); } - return hecl::Char16ToUTF8(stringTables[stringId].GetObj()->GetString(idx)); + return CStringExtras::ConvertToUTF8(stringTables[stringId].GetObj()->GetString(idx)); } static bool ContainsCaseInsensitive(std::string_view str, std::string_view val) { @@ -112,15 +152,19 @@ static void Warp(const CAssetId worldId, TAreaId aId) { } } +static inline float GetScale() { return ImGui::GetIO().DisplayFramebufferScale.x; } + void ImGuiConsole::ShowMenuGame() { - m_paused = g_Main->IsPaused(); - if (ImGui::MenuItem("Paused", "F5", &m_paused)) { + if (g_Main != nullptr) { + m_paused = g_Main->IsPaused(); + } + if (ImGui::MenuItem("Paused", "F5", &m_paused, g_Main != nullptr)) { g_Main->SetPaused(m_paused); } if (ImGui::MenuItem("Step Frame", "F6", &m_stepFrame, m_paused)) { g_Main->SetPaused(false); } - if (ImGui::BeginMenu("Warp", g_StateManager != nullptr && g_ResFactory != nullptr && + if (ImGui::BeginMenu("Warp", m_cheats && g_StateManager != nullptr && g_ResFactory != nullptr && g_ResFactory->GetResLoader() != nullptr)) { for (const auto& world : ListWorlds()) { if (ImGui::BeginMenu(world.first.c_str())) { @@ -135,7 +179,7 @@ void ImGuiConsole::ShowMenuGame() { ImGui::EndMenu(); } if (ImGui::MenuItem("Quit", "Alt+F4")) { - g_Main->Quit(); + m_quitRequested = true; } } @@ -244,7 +288,7 @@ static void RenderEntityColumns(const ImGuiEntityEntry& entry) { } void ImGuiConsole::ShowInspectWindow(bool* isOpen) { - float initialWindowSize = 400.f * ImGui::GetIO().DisplayFramebufferScale.x; + float initialWindowSize = 400.f * GetScale(); ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize * 1.5f}, ImGuiCond_FirstUseEver); if (ImGui::Begin("Inspect", isOpen)) { @@ -364,7 +408,7 @@ bool ImGuiConsole::ShowEntityInfoWindow(TUniqueId uid) { void ImGuiConsole::ShowConsoleVariablesWindow() { // For some reason the window shows up tiny without this - float initialWindowSize = 350.f * ImGui::GetIO().DisplayFramebufferScale.x; + float initialWindowSize = 350.f * GetScale(); ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize}, ImGuiCond_FirstUseEver); if (ImGui::Begin("Console Variables", &m_showConsoleVariablesWindow)) { if (ImGui::Button("Clear")) { @@ -372,14 +416,14 @@ void ImGuiConsole::ShowConsoleVariablesWindow() { } ImGui::SameLine(); ImGui::InputText("Filter", &m_cvarFiltersText); - auto cvars = m_cvarMgr.cvars(hecl::CVar::EFlags::Any & ~hecl::CVar::EFlags::Hidden); + auto cvars = m_cvarMgr.cvars(CVar::EFlags::Any & ~CVar::EFlags::Hidden); if (ImGui::Button("Reset to defaults")) { for (auto* cv : cvars) { if (cv->name() == "developer" || cv->name() == "cheats") { // don't reset developer or cheats to default continue; } - hecl::CVarUnlocker l(cv); + CVarUnlocker l(cv); cv->fromLiteralToType(cv->defaultValue()); } } @@ -398,10 +442,13 @@ void ImGuiConsole::ShowConsoleVariablesWindow() { bool hasSortSpec = sortSpecs != nullptr && // no multi-sort sortSpecs->SpecsCount == 1; - std::vector sortedList; + std::vector sortedList; sortedList.reserve(cvars.size()); for (auto* cvar : cvars) { + if (cvar->isHidden()) { + continue; + } if (!m_cvarFiltersText.empty()) { if (ContainsCaseInsensitive(magic_enum::enum_name(cvar->type()), m_cvarFiltersText) || ContainsCaseInsensitive(cvar->name(), m_cvarFiltersText)) { @@ -415,18 +462,19 @@ void ImGuiConsole::ShowConsoleVariablesWindow() { if (hasSortSpec) { const auto& spec = sortSpecs->Specs[0]; if (spec.ColumnUserID == 'name') { - std::sort(sortedList.begin(), sortedList.end(), [&](hecl::CVar* a, hecl::CVar* b) { + std::sort(sortedList.begin(), sortedList.end(), [&](CVar* a, CVar* b) { int compare = a->name().compare(b->name()); return spec.SortDirection == ImGuiSortDirection_Ascending ? compare < 0 : compare > 0; }); } else if (spec.ColumnUserID == 'val') { - std::sort(sortedList.begin(), sortedList.end(), [&](hecl::CVar* a, hecl::CVar* b) { + std::sort(sortedList.begin(), sortedList.end(), [&](CVar* a, CVar* b) { int compare = a->value().compare(b->value()); return spec.SortDirection == ImGuiSortDirection_Ascending ? compare < 0 : compare > 0; }); } for (auto* cv : sortedList) { + bool modified = cv->isModified(); ImGui::PushID(cv); ImGui::TableNextRow(); // Name @@ -440,139 +488,154 @@ void ImGuiConsole::ShowConsoleVariablesWindow() { // Value if (ImGui::TableNextColumn()) { switch (cv->type()) { - case hecl::CVar::EType::Boolean: { + case CVar::EType::Boolean: { bool b = cv->toBoolean(); if (ImGui::Checkbox("", &b)) { cv->fromBoolean(b); + modified = true; } break; } - case hecl::CVar::EType::Real: { + case CVar::EType::Real: { float f = cv->toReal(); if (ImGui::DragFloat("", &f)) { cv->fromReal(f); + modified = true; } break; } - case hecl::CVar::EType::Signed: { + case CVar::EType::Signed: { std::array i{cv->toSigned()}; if (ImGui::DragScalar("", ImGuiDataType_S32, i.data(), i.size())) { cv->fromInteger(i[0]); + modified = true; } break; } - case hecl::CVar::EType::Unsigned: { + case CVar::EType::Unsigned: { std::array i{cv->toUnsigned()}; if (ImGui::DragScalar("", ImGuiDataType_U32, i.data(), i.size())) { cv->fromInteger(i[0]); + modified = true; } break; } - case hecl::CVar::EType::Literal: { + case CVar::EType::Literal: { char buf[4096]; strcpy(buf, cv->value().c_str()); if (ImGui::InputText("", buf, 4096, ImGuiInputTextFlags_EnterReturnsTrue)) { cv->fromLiteral(buf); + modified = true; } break; } - case hecl::CVar::EType::Vec2f: { + case CVar::EType::Vec2f: { auto vec = cv->toVec2f(); - std::array scalars = {vec.simd[0], vec.simd[1]}; + std::array scalars = {vec.x(), vec.y()}; if (ImGui::DragScalarN("", ImGuiDataType_Float, scalars.data(), scalars.size(), 0.1f)) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; cv->fromVec2f(vec); + modified = true; } break; } - case hecl::CVar::EType::Vec2d: { + case CVar::EType::Vec2d: { auto vec = cv->toVec2d(); - std::array scalars = {vec.simd[0], vec.simd[1]}; + std::array scalars = {vec.x(), vec.y()}; if (ImGui::DragScalarN("", ImGuiDataType_Double, scalars.data(), scalars.size(), 0.1f)) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; cv->fromVec2d(vec); + modified = true; } break; } - case hecl::CVar::EType::Vec3f: { + case CVar::EType::Vec3f: { auto vec = cv->toVec3f(); - std::array scalars = {vec.simd[0], vec.simd[1]}; + std::array scalars = {vec.x(), vec.y(), vec.z()}; if (cv->isColor()) { if (ImGui::ColorEdit3("", scalars.data())) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; - vec.simd[2] = scalars[2]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; cv->fromVec3f(vec); + modified = true; } } else if (ImGui::DragScalarN("", ImGuiDataType_Float, scalars.data(), scalars.size(), 0.1f)) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; - vec.simd[2] = scalars[2]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; cv->fromVec3f(vec); + modified = true; } break; } - case hecl::CVar::EType::Vec3d: { + case CVar::EType::Vec3d: { auto vec = cv->toVec3d(); - std::array scalars = {vec.simd[0], vec.simd[1], vec.simd[2]}; + std::array scalars = {vec.x(), vec.y(), vec.z()}; if (cv->isColor()) { std::array color{static_cast(scalars[0]), static_cast(scalars[1]), static_cast(scalars[2])}; if (ImGui::ColorEdit3("", color.data())) { - vec.simd[0] = color[0]; - vec.simd[1] = color[1]; - vec.simd[2] = color[2]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; cv->fromVec3d(vec); + modified = true; } } else if (ImGui::DragScalarN("", ImGuiDataType_Double, scalars.data(), scalars.size(), 0.1f)) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; - vec.simd[2] = scalars[2]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; cv->fromVec3d(vec); + modified = true; } break; } - case hecl::CVar::EType::Vec4f: { + case CVar::EType::Vec4f: { auto vec = cv->toVec4f(); - std::array scalars = {vec.simd[0], vec.simd[1], vec.simd[2], vec.simd[3]}; + std::array scalars = {vec.x(), vec.y(), vec.z(), vec.w()}; if (cv->isColor()) { if (ImGui::ColorEdit4("", scalars.data())) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; - vec.simd[2] = scalars[2]; - vec.simd[3] = scalars[3]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; + vec.w() = scalars[2]; cv->fromVec4f(vec); + modified = true; } } else if (ImGui::DragScalarN("", ImGuiDataType_Float, scalars.data(), scalars.size(), 0.1f)) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; - vec.simd[2] = scalars[2]; - vec.simd[3] = scalars[3]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; + vec.w() = scalars[2]; cv->fromVec4f(vec); + modified = true; } break; } - case hecl::CVar::EType::Vec4d: { + case CVar::EType::Vec4d: { auto vec = cv->toVec4d(); - std::array scalars = {vec.simd[0], vec.simd[1], vec.simd[2], vec.simd[3]}; + std::array scalars = {vec.x(), vec.y(), vec.z(), vec.w()}; if (cv->isColor()) { std::array color{static_cast(scalars[0]), static_cast(scalars[1]), static_cast(scalars[2]), static_cast(scalars[3])}; if (ImGui::ColorEdit4("", color.data())) { - vec.simd[0] = color[0]; - vec.simd[1] = color[1]; - vec.simd[2] = color[2]; - vec.simd[3] = color[3]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; + vec.w() = scalars[2]; cv->fromVec4d(vec); + modified = true; } } else if (ImGui::DragScalarN("", ImGuiDataType_Double, scalars.data(), scalars.size(), 0.1f)) { - vec.simd[0] = scalars[0]; - vec.simd[1] = scalars[1]; - vec.simd[2] = scalars[2]; - vec.simd[3] = scalars[3]; + vec.x() = scalars[0]; + vec.y() = scalars[1]; + vec.z() = scalars[2]; + vec.w() = scalars[2]; cv->fromVec4d(vec); + modified = true; } break; } @@ -580,6 +643,9 @@ void ImGuiConsole::ShowConsoleVariablesWindow() { ImGui::Text("lawl wut? Please contact a developer, your copy of Metaforce is cursed!"); break; } + if (modified && cv->modificationRequiresRestart()) { + ImGui::Text("Restart required for value to take affect!"); + } if (ImGui::IsItemHovered()) { std::string sv(cv->defaultValue()); ImGui::SetTooltip("Default: %s", sv.c_str()); @@ -594,10 +660,10 @@ void ImGuiConsole::ShowConsoleVariablesWindow() { ImGui::End(); } -void ImGuiConsole::ShowAboutWindow(bool canClose, std::string_view errorString) { +void ImGuiConsole::ShowAboutWindow(bool preLaunch) { // Center window ImVec2 center = ImGui::GetMainViewport()->GetCenter(); - ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + ImGui::SetNextWindowPos(center, preLaunch ? ImGuiCond_Always : ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); ImVec4& windowBg = ImGui::GetStyle().Colors[ImGuiCol_WindowBg]; ImGui::PushStyleColor(ImGuiCol_TitleBg, windowBg); @@ -606,28 +672,57 @@ void ImGuiConsole::ShowAboutWindow(bool canClose, std::string_view errorString) bool* open = nullptr; ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoSavedSettings; - if (canClose) { - open = &m_showAboutWindow; - } else { + if (preLaunch) { flags |= ImGuiWindowFlags_NoBackground | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove; + } else { + open = &m_showAboutWindow; } if (ImGui::Begin("About", open, flags)) { - float iconSize = 128.f * ImGui::GetIO().DisplayFramebufferScale.x; + float iconSize = 128.f * GetScale(); ImGui::SameLine(ImGui::GetWindowSize().x / 2 - iconSize + (iconSize / 2)); - ImGui::Image(ImGuiUserTextureID_MetaforceIcon, ImVec2{iconSize, iconSize}); + ImGui::Image(ImGuiEngine::metaforceIcon, ImVec2{iconSize, iconSize}); ImGui::PushFont(ImGuiEngine::fontLarge); ImGuiTextCenter("Metaforce"); ImGui::PopFont(); ImGuiTextCenter(METAFORCE_WC_DESCRIBE); const ImVec2& padding = ImGui::GetStyle().WindowPadding; ImGui::Dummy(padding); - if (!errorString.empty()) { + if (preLaunch) { + if (ImGuiButtonCenter("Settings")) { + m_showPreLaunchSettingsWindow = true; + } +#ifdef NATIVEFILEDIALOG_SUPPORTED + ImGui::Dummy(padding); + if (ImGuiButtonCenter("Select Game")) { + NFD::UniquePathU8 outPath; + nfdresult_t nfdResult = NFD::OpenDialog(outPath, nullptr, 0, nullptr); + if (nfdResult == NFD_OKAY) { + m_gameDiscSelected = outPath.get(); + } else if (nfdResult != NFD_CANCEL) { + Log.report(logvisor::Error, FMT_STRING("nativefiledialog error: {}"), NFD::GetError()); + } + } +#endif +#ifdef EMSCRIPTEN + if (ImGuiButtonCenter("Load Game")) { + m_gameDiscSelected = "game.iso"; + } +#else + if (!m_lastDiscPath.empty()) { + if (ImGuiButtonCenter("Load Previous Game")) { + m_gameDiscSelected = m_lastDiscPath; + } + } +#endif + ImGui::Dummy(padding); + } + if (m_errorString) { ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{0.77f, 0.12f, 0.23f, 1.f}); - ImGuiTextCenter(errorString); + ImGuiTextCenter(*m_errorString); ImGui::PopStyleColor(); ImGui::Dummy(padding); } - ImGuiTextCenter("2015-2021"); + ImGuiTextCenter("2015-2022"); ImGui::BeginGroup(); ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 200)); ImGuiStringViewText("Development & Research"); @@ -647,7 +742,7 @@ void ImGuiConsole::ShowAboutWindow(bool canClose, std::string_view errorString) ImGuiStringViewText("Contributions"); ImGui::PopStyleColor(); ImGuiStringViewText("Darkszero (Profiling)"); - ImGuiStringViewText("shio (Flamethrower)"); + ImGuiStringViewText("shio (Weapons)"); ImGui::EndGroup(); ImGui::Dummy(padding); ImGui::Separator(); @@ -703,15 +798,31 @@ void ImGuiConsole::ShowAboutWindow(bool canClose, std::string_view errorString) ImGui::PopStyleColor(2); } +static std::string BytesToString(size_t bytes) { + constexpr std::array suffixes{"B"sv, "KB"sv, "MB"sv, "GB"sv, "TB"sv, "PB"sv, "EB"sv}; + u32 s = 0; + auto count = static_cast(bytes); + while (count >= 1024.0 && s < 7) { + s++; + count /= 1024.0; + } + if (count - floor(count) == 0.0) { + return fmt::format(FMT_STRING("{}{}"), static_cast(count), suffixes[s]); + } + return fmt::format(FMT_STRING("{:.1f}{}"), count, suffixes[s]); +} + void ImGuiConsole::ShowDebugOverlay() { - if (!m_frameCounter && !m_frameRate && !m_inGameTime && !m_roomTimer && !m_playerInfo && !m_areaInfo && - !m_worldInfo && !m_randomStats && !m_resourceStats) { + if (!m_developer && !m_frameCounter && !m_frameRate && !m_inGameTime && !m_roomTimer) { + return; + } + if (!m_playerInfo && !m_areaInfo && !m_worldInfo && !m_randomStats && !m_resourceStats && !m_pipelineInfo && + !m_drawCallInfo && !m_bufferInfo) { return; } ImGuiIO& io = ImGui::GetIO(); ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | - ImGuiWindowFlags_NoNav; + ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav; if (m_debugOverlayCorner != -1) { SetOverlayWindowLocation(m_debugOverlayCorner); windowFlags |= ImGuiWindowFlags_NoMove; @@ -729,7 +840,7 @@ void ImGuiConsole::ShowDebugOverlay() { } hasPrevious = true; - ImGuiStringViewText(fmt::format(FMT_STRING("FPS: {}\n"), metaforce::CGraphics::GetFPS())); + ImGuiStringViewText(fmt::format(FMT_STRING("FPS: {:.1f}\n"), io.Framerate)); } if (m_inGameTime && g_GameState != nullptr) { if (hasPrevious) { @@ -756,7 +867,7 @@ void ImGuiConsole::ShowDebugOverlay() { ImGuiStringViewText(fmt::format(FMT_STRING("Room Time: {:7.3f} / {:5d} | Last Room:{:7.3f} / {:5d}\n"), currentRoomTime, curFrames, m_lastRoomTime, lastFrames)); } - if (m_playerInfo && g_StateManager != nullptr && g_StateManager->Player() != nullptr) { + if (m_playerInfo && g_StateManager != nullptr && g_StateManager->Player() != nullptr && m_developer) { if (hasPrevious) { ImGui::Separator(); } @@ -779,7 +890,7 @@ void ImGuiConsole::ShowDebugOverlay() { pl.GetVelocity().y(), pl.GetVelocity().z(), camXf.origin.x(), camXf.origin.y(), camXf.origin.z(), zeus::radToDeg(camQ.roll()), zeus::radToDeg(camQ.pitch()), zeus::radToDeg(camQ.yaw()))); } - if (m_worldInfo && g_StateManager != nullptr) { + if (m_worldInfo && g_StateManager != nullptr && m_developer) { if (hasPrevious) { ImGui::Separator(); } @@ -789,7 +900,7 @@ void ImGuiConsole::ShowDebugOverlay() { ImGuiStringViewText( fmt::format(FMT_STRING("World Asset ID: 0x{}, Name: {}\n"), g_GameState->CurrentWorldAssetId(), name)); } - if (m_areaInfo && g_StateManager != nullptr) { + if (m_areaInfo && g_StateManager != nullptr && m_developer) { const metaforce::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId(); if (g_StateManager->GetWorld() != nullptr && g_StateManager->GetWorld()->DoesAreaExist(aId)) { if (hasPrevious) { @@ -815,7 +926,7 @@ void ImGuiConsole::ShowDebugOverlay() { pArea->GetAreaAssetId(), ImGuiLoadStringTable(stringId, 0), pArea->GetAreaId(), layerBits)); } } - if (m_layerInfo && g_StateManager != nullptr) { + if (m_layerInfo && g_StateManager != nullptr && m_developer) { const metaforce::TAreaId aId = g_GameState->CurrentWorldState().GetCurrentAreaId(); const auto* world = g_StateManager->GetWorld(); if (world != nullptr && world->DoesAreaExist(aId) && world->GetWorldLayers()) { @@ -845,7 +956,7 @@ void ImGuiConsole::ShowDebugOverlay() { } } } - if (m_randomStats) { + if (m_randomStats && m_developer) { if (hasPrevious) { ImGui::Separator(); } @@ -853,8 +964,9 @@ void ImGuiConsole::ShowDebugOverlay() { ImGuiStringViewText( fmt::format(FMT_STRING("CRandom16::Next calls: {}\n"), metaforce::CRandom16::GetNumNextCalls())); + ImGuiStringViewText(fmt::format(FMT_STRING("CRandom16::LastSeed: 0x{:08X}\n"), CRandom16::GetLastSeed())); } - if (m_resourceStats) { + if (m_resourceStats && g_SimplePool != nullptr) { if (hasPrevious) { ImGui::Separator(); } @@ -862,34 +974,92 @@ void ImGuiConsole::ShowDebugOverlay() { ImGuiStringViewText(fmt::format(FMT_STRING("Resource Objects: {}\n"), g_SimplePool->GetLiveObjects())); } - ShowCornerContextMenu(m_debugOverlayCorner, m_inputOverlayCorner); + if (m_pipelineInfo && m_developer) { + if (hasPrevious) { + ImGui::Separator(); + } + hasPrevious = true; + + ImGuiStringViewText(fmt::format(FMT_STRING("Queued pipelines: {}\n"), aurora::gfx::queuedPipelines)); + ImGuiStringViewText(fmt::format(FMT_STRING("Done pipelines: {}\n"), aurora::gfx::createdPipelines)); + } + if (m_drawCallInfo && m_developer) { + if (hasPrevious) { + ImGui::Separator(); + } + hasPrevious = true; + + ImGuiStringViewText(fmt::format(FMT_STRING("Draw call count: {}\n"), aurora::gfx::g_drawCallCount)); + ImGuiStringViewText(fmt::format(FMT_STRING("Merged draw calls: {}\n"), aurora::gfx::g_mergedDrawCallCount)); + } + if (m_bufferInfo && m_developer) { + if (hasPrevious) { + ImGui::Separator(); + } + hasPrevious = true; + + ImGuiStringViewText( + fmt::format(FMT_STRING("Vertex size: {}\n"), BytesToString(aurora::gfx::g_lastVertSize))); + ImGuiStringViewText( + fmt::format(FMT_STRING("Uniform size: {}\n"), BytesToString(aurora::gfx::g_lastUniformSize))); + ImGuiStringViewText( + fmt::format(FMT_STRING("Index size: {}\n"), BytesToString(aurora::gfx::g_lastIndexSize))); + ImGuiStringViewText( + fmt::format(FMT_STRING("Storage size: {}\n"), BytesToString(aurora::gfx::g_lastStorageSize))); + ImGuiStringViewText(fmt::format(FMT_STRING("Total: {}\n"), + BytesToString(aurora::gfx::g_lastVertSize + aurora::gfx::g_lastUniformSize + + aurora::gfx::g_lastIndexSize + aurora::gfx::g_lastStorageSize))); + } + if (ShowCornerContextMenu(m_debugOverlayCorner, m_inputOverlayCorner)) { + m_cvarCommons.m_debugOverlayCorner->fromInteger(m_debugOverlayCorner); + } } ImGui::End(); } +void TextCenter(const std::string& text) { + float font_size = ImGui::GetFontSize() * text.size() / 2; + ImGui::SameLine(ImGui::GetWindowSize().x / 2 - font_size + (font_size / 2)); + + ImGui::TextUnformatted(text.c_str()); +} void ImGuiConsole::ShowInputViewer() { if (!m_showInput || g_InputGenerator == nullptr) { return; } auto input = g_InputGenerator->GetLastInput(); - if (input.x4_controllerIdx != 0) { + if (input.ControllerIdx() != 0) { return; } + + u32 thisWhich = input.ControllerIdx(); + if (m_whichController != thisWhich) { + const char* name = PADGetName(thisWhich); + if (name != nullptr) { + m_controllerName = name; + m_whichController = thisWhich; + } + } + // Code -stolen- borrowed from Practice Mod ImGuiIO& io = ImGui::GetIO(); ImGuiWindowFlags windowFlags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | - ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | - ImGuiWindowFlags_NoNav; + ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav; if (m_inputOverlayCorner != -1) { SetOverlayWindowLocation(m_inputOverlayCorner); windowFlags |= ImGuiWindowFlags_NoMove; } + ImGui::SetNextWindowBgAlpha(0.65f); if (ImGui::Begin("Input Overlay", nullptr, windowFlags)) { + float scale = GetScale(); + if (!m_controllerName.empty()) { + TextCenter(m_controllerName); + ImGui::Separator(); + } ImDrawList* dl = ImGui::GetWindowDrawList(); zeus::CVector2f p = ImGui::GetCursorScreenPos(); - float scale = ImGui::GetIO().DisplayFramebufferScale.x; float leftStickRadius = 30 * scale; p = p + zeus::CVector2f{20, 20} * scale; // Pad p so we don't clip outside our rect zeus::CVector2f leftStickCenter = p + zeus::CVector2f(30, 45) * scale; @@ -923,22 +1093,22 @@ void ImGuiConsole::ShowInputViewer() { // left stick { - dl->AddCircleFilled(leftStickCenter, leftStickRadius, stickGray, 8); float x = input.ALeftX(); float y = -input.ALeftY(); - dl->AddCircleFilled(leftStickCenter + (zeus::CVector2f{x, y} * leftStickRadius), leftStickRadius / 3, red); + dl->AddCircleFilled(leftStickCenter, leftStickRadius, stickGray, 8); dl->AddLine(leftStickCenter, leftStickCenter + zeus::CVector2f(x * leftStickRadius, y * leftStickRadius), IM_COL32(255, 244, 0, 255), 1.5f); + dl->AddCircleFilled(leftStickCenter + (zeus::CVector2f{x, y} * leftStickRadius), leftStickRadius / 3, red); } // right stick { - dl->AddCircleFilled(rightStickCenter, rightStickRadius, stickGray, 8); float x = input.ARightX(); float y = -input.ARightY(); - dl->AddCircleFilled(rightStickCenter + (zeus::CVector2f{x, y} * rightStickRadius), rightStickRadius / 3, red); + dl->AddCircleFilled(rightStickCenter, rightStickRadius, stickGray, 8); dl->AddLine(rightStickCenter, rightStickCenter + zeus::CVector2f(x * rightStickRadius, y * rightStickRadius), IM_COL32(255, 244, 0, 255), 1.5f); + dl->AddCircleFilled(rightStickCenter + (zeus::CVector2f{x, y} * rightStickRadius), rightStickRadius / 3, red); } // dpad @@ -999,44 +1169,53 @@ void ImGuiConsole::ShowInputViewer() { float halfTriggerWidth = triggerWidth / 2; zeus::CVector2f lStart = lCenter - zeus::CVector2f(halfTriggerWidth, 0); zeus::CVector2f lEnd = lCenter + zeus::CVector2f(halfTriggerWidth, triggerHeight); - float lValue = triggerWidth * input.ALTrigger(); + float lValue = triggerWidth * std::min(1.f, input.ALTrigger()); dl->AddRectFilled(lStart, lStart + zeus::CVector2f(lValue, triggerHeight), input.DL() ? red : stickGray); dl->AddRectFilled(lStart + zeus::CVector2f(lValue, 0), lEnd, darkGray); zeus::CVector2f rStart = rCenter - zeus::CVector2f(halfTriggerWidth, 0); zeus::CVector2f rEnd = rCenter + zeus::CVector2f(halfTriggerWidth, triggerHeight); - float rValue = triggerWidth * input.ARTrigger(); + float rValue = triggerWidth * std::min(1.f, input.ARTrigger()); dl->AddRectFilled(rEnd - zeus::CVector2f(rValue, triggerHeight), rEnd, input.DR() ? red : stickGray); dl->AddRectFilled(rStart, rEnd - zeus::CVector2f(rValue, 0), darkGray); } ImGui::Dummy(zeus::CVector2f(270, 130) * scale); - ShowCornerContextMenu(m_inputOverlayCorner, m_debugOverlayCorner); + if (ShowCornerContextMenu(m_inputOverlayCorner, m_debugOverlayCorner)) { + m_cvarCommons.m_debugInputOverlayCorner->fromInteger(m_inputOverlayCorner); + } } ImGui::End(); } -void ImGuiConsole::ShowCornerContextMenu(int& corner, int avoidCorner) const { +bool ImGuiConsole::ShowCornerContextMenu(int& corner, int avoidCorner) const { + bool result = false; if (ImGui::BeginPopupContextWindow()) { if (ImGui::MenuItem("Custom", nullptr, corner == -1)) { corner = -1; + result = true; } if (ImGui::MenuItem("Top-left", nullptr, corner == 0, avoidCorner != 0)) { corner = 0; + result = true; } if (ImGui::MenuItem("Top-right", nullptr, corner == 1, avoidCorner != 1)) { corner = 1; + result = true; } if (ImGui::MenuItem("Bottom-left", nullptr, corner == 2, avoidCorner != 2)) { corner = 2; + result = true; } if (ImGui::MenuItem("Bottom-right", nullptr, corner == 3, avoidCorner != 3)) { corner = 3; + result = true; } ImGui::EndPopup(); } + return result; } void ImGuiConsole::SetOverlayWindowLocation(int corner) const { @@ -1053,68 +1232,78 @@ void ImGuiConsole::SetOverlayWindowLocation(int corner) const { ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, windowPosPivot); } -void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) { +static void ImGuiCVarMenuItem(const char* name, CVar* cvar, bool& value) { + if (cvar == nullptr) { + return; + } + if (ImGui::MenuItem(name, nullptr, &value)) { + cvar->fromBoolean(value); + } + if (ImGui::IsItemHovered()) { + std::string tooltip{cvar->rawHelp()}; + if (!tooltip.empty()) { + ImGui::SetTooltip("%s", tooltip.c_str()); + } + } +} + +void ImGuiConsole::ShowAppMainMenuBar(bool canInspect, bool preLaunch) { if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("Game")) { ShowMenuGame(); ImGui::EndMenu(); } if (ImGui::BeginMenu("Tools")) { - ImGui::MenuItem("Player Transform", nullptr, &m_showPlayerTransformEditor, canInspect && m_developer); - ImGui::MenuItem("Inspect", nullptr, &m_showInspectWindow, canInspect && m_developer); - ImGui::MenuItem("Items", nullptr, &m_showItemsWindow, canInspect && m_developer && m_cheats); - ImGui::MenuItem("Layers", nullptr, &m_showLayersWindow, canInspect && m_developer); - ImGui::MenuItem("Console Variables", nullptr, &m_showConsoleVariablesWindow); - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Debug")) { - if (ImGui::MenuItem("Frame Counter", nullptr, &m_frameCounter)) { - m_cvarCommons.m_debugOverlayShowFrameCounter->fromBoolean(m_frameCounter); - } - if (ImGui::MenuItem("Frame Rate", nullptr, &m_frameRate)) { - m_cvarCommons.m_debugOverlayShowFramerate->fromBoolean(m_frameRate); - } - if (ImGui::MenuItem("In-Game Time", nullptr, &m_inGameTime)) { - m_cvarCommons.m_debugOverlayShowInGameTime->fromBoolean(m_inGameTime); - } - if (ImGui::MenuItem("Room Timer", nullptr, &m_roomTimer)) { - m_cvarCommons.m_debugOverlayShowRoomTimer->fromBoolean(m_roomTimer); - } - if (ImGui::MenuItem("Player Info", nullptr, &m_playerInfo)) { - m_cvarCommons.m_debugOverlayPlayerInfo->fromBoolean(m_playerInfo); - } - if (ImGui::MenuItem("World Info", nullptr, &m_worldInfo)) { - m_cvarCommons.m_debugOverlayWorldInfo->fromBoolean(m_worldInfo); - } - if (ImGui::MenuItem("Area Info", nullptr, &m_areaInfo)) { - m_cvarCommons.m_debugOverlayAreaInfo->fromBoolean(m_areaInfo); - } - if (ImGui::MenuItem("Layer Info", nullptr, &m_layerInfo)) { - m_cvarCommons.m_debugOverlayLayerInfo->fromBoolean(m_layerInfo); - } - if (ImGui::MenuItem("Random Stats", nullptr, &m_randomStats)) { - m_cvarCommons.m_debugOverlayShowRandomStats->fromBoolean(m_randomStats); - } - if (ImGui::MenuItem("Resource Stats", nullptr, &m_resourceStats)) { - m_cvarCommons.m_debugOverlayShowResourceStats->fromBoolean(m_resourceStats); - } - if (ImGui::MenuItem("Show Input", nullptr, &m_showInput)) { - m_cvarCommons.m_debugOverlayShowInput->fromBoolean(m_showInput); + ImGui::MenuItem("Controller Config", nullptr, &m_controllerConfigVisible); + ImGui::MenuItem("Items", nullptr, &m_showItemsWindow, canInspect && m_cheats); + if (m_developer) { + ImGui::Separator(); + ImGui::MenuItem("Console Variables", nullptr, &m_showConsoleVariablesWindow); + ImGui::MenuItem("Inspect", nullptr, &m_showInspectWindow, canInspect); + ImGui::MenuItem("Layers", nullptr, &m_showLayersWindow, canInspect); + ImGui::MenuItem("Player Transform", nullptr, &m_showPlayerTransformEditor, canInspect && m_cheats); } ImGui::EndMenu(); } - ImGui::Spacing(); - if (ImGui::BeginMenu("Help")) { - ImGui::MenuItem("About", nullptr, &m_showAboutWindow); + if (ImGui::BeginMenu("Overlays")) { + ImGuiCVarMenuItem("Frame Counter", m_cvarCommons.m_debugOverlayShowFrameCounter, m_frameCounter); + ImGuiCVarMenuItem("Frame Rate", m_cvarCommons.m_debugOverlayShowFramerate, m_frameRate); + ImGuiCVarMenuItem("In-Game Time", m_cvarCommons.m_debugOverlayShowInGameTime, m_inGameTime); + ImGuiCVarMenuItem("Room Timer", m_cvarCommons.m_debugOverlayShowRoomTimer, m_roomTimer); + ImGuiCVarMenuItem("Player Info", m_cvarCommons.m_debugOverlayPlayerInfo, m_playerInfo); + ImGuiCVarMenuItem("World Info", m_cvarCommons.m_debugOverlayWorldInfo, m_worldInfo); + ImGuiCVarMenuItem("Area Info", m_cvarCommons.m_debugOverlayAreaInfo, m_areaInfo); + ImGuiCVarMenuItem("Layer Info", m_cvarCommons.m_debugOverlayLayerInfo, m_layerInfo); + ImGuiCVarMenuItem("Random Stats", m_cvarCommons.m_debugOverlayShowRandomStats, m_randomStats); + ImGuiCVarMenuItem("Draw Call Info", m_cvarCommons.m_debugOverlayDrawCallInfo, m_drawCallInfo); + ImGuiCVarMenuItem("Pipeline Info", m_cvarCommons.m_debugOverlayPipelineInfo, m_pipelineInfo); + ImGuiCVarMenuItem("Buffer Info", m_cvarCommons.m_debugOverlayBufferInfo, m_bufferInfo); + ImGuiCVarMenuItem("Resource Stats", m_cvarCommons.m_debugOverlayShowResourceStats, m_resourceStats); + ImGuiCVarMenuItem("Show Input", m_cvarCommons.m_debugOverlayShowInput, m_showInput); +#if 0 // Currently unimplemented ImGui::Separator(); - if (ImGui::BeginMenu("ImGui")) { - if (ImGui::MenuItem("Clear Settings")) { - ImGui::ClearIniSettings(); - } -#ifndef NDEBUG - ImGui::MenuItem("Show Demo", nullptr, &m_showDemoWindow); + ImGuiCVarMenuItem("Draw AI Paths", m_cvarCommons.m_debugToolDrawAiPath, m_drawAiPath); + ImGuiCVarMenuItem("Draw Lighting", m_cvarCommons.m_debugToolDrawLighting, m_drawLighting); + ImGuiCVarMenuItem("Draw Collision Actors", m_cvarCommons.m_debugToolDrawCollisionActors, m_drawCollisionActors); + ImGuiCVarMenuItem("Draw Maze Path", m_cvarCommons.m_debugToolDrawMazePath, m_drawMazePath); + ImGuiCVarMenuItem("Draw Platform Collision", m_cvarCommons.m_debugToolDrawPlatformCollision, + m_drawPlatformCollision); #endif - ImGui::EndMenu(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Help")) { + ImGui::MenuItem("About", nullptr, &m_showAboutWindow, !preLaunch); + if (m_developer) { + ImGui::Separator(); + if (ImGui::BeginMenu("ImGui")) { + if (ImGui::MenuItem("Clear Settings")) { + ImGui::ClearIniSettings(); + } +#ifndef NDEBUG + ImGui::MenuItem("Show Demo", nullptr, &m_showDemoWindow); +#endif + ImGui::EndMenu(); + } } ImGui::EndMenu(); } @@ -1122,53 +1311,71 @@ void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) { } } -s32 TranslateBooSpecialKey(boo::ESpecialKey key) { return 256 + static_cast(key); } +void ImGuiConsole::ToggleVisible() { + if (g_Main != nullptr) { + m_isVisible ^= 1; + } +} + void ImGuiConsole::PreUpdate() { OPTICK_EVENT(); + bool preLaunch = g_Main == nullptr; if (!m_isInitialized) { m_isInitialized = true; - m_cvarCommons.m_debugOverlayShowFrameCounter->addListener( - [this](hecl::CVar* c) { m_frameCounter = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayShowFramerate->addListener([this](hecl::CVar* c) { m_frameRate = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayShowInGameTime->addListener([this](hecl::CVar* c) { m_inGameTime = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayShowRoomTimer->addListener([this](hecl::CVar* c) { m_roomTimer = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayPlayerInfo->addListener([this](hecl::CVar* c) { m_playerInfo = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayWorldInfo->addListener([this](hecl::CVar* c) { m_worldInfo = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayAreaInfo->addListener([this](hecl::CVar* c) { m_areaInfo = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayLayerInfo->addListener([this](hecl::CVar* c) { m_layerInfo = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayShowRandomStats->addListener([this](hecl::CVar* c) { m_randomStats = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayShowResourceStats->addListener( - [this](hecl::CVar* c) { m_resourceStats = c->toBoolean(); }); - m_cvarCommons.m_debugOverlayShowInput->addListener([this](hecl::CVar* c) { m_showInput = c->toBoolean(); }); - m_cvarMgr.findCVar("developer")->addListener([this](hecl::CVar* c) { m_developer = c->toBoolean(); }); - m_cvarMgr.findCVar("cheats")->addListener([this](hecl::CVar* c) { m_cheats = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayShowFrameCounter->addListener([this](CVar* c) { m_frameCounter = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayShowFramerate->addListener([this](CVar* c) { m_frameRate = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayShowInGameTime->addListener([this](CVar* c) { m_inGameTime = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayShowRoomTimer->addListener([this](CVar* c) { m_roomTimer = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayPlayerInfo->addListener([this](CVar* c) { m_playerInfo = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayWorldInfo->addListener([this](CVar* c) { m_worldInfo = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayAreaInfo->addListener([this](CVar* c) { m_areaInfo = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayLayerInfo->addListener([this](CVar* c) { m_layerInfo = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayShowRandomStats->addListener([this](CVar* c) { m_randomStats = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayShowResourceStats->addListener([this](CVar* c) { m_resourceStats = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayShowInput->addListener([this](CVar* c) { m_showInput = c->toBoolean(); }); + m_cvarCommons.m_debugToolDrawAiPath->addListener([this](CVar* c) { m_drawAiPath = c->toBoolean(); }); + m_cvarCommons.m_debugToolDrawCollisionActors->addListener( + [this](CVar* c) { m_drawCollisionActors = c->toBoolean(); }); + m_cvarCommons.m_debugToolDrawPlatformCollision->addListener( + [this](CVar* c) { m_drawPlatformCollision = c->toBoolean(); }); + m_cvarCommons.m_debugToolDrawMazePath->addListener([this](CVar* c) { m_drawMazePath = c->toBoolean(); }); + m_cvarCommons.m_debugToolDrawLighting->addListener([this](CVar* c) { m_drawLighting = c->toBoolean(); }); + m_cvarCommons.m_debugOverlayCorner->addListener([this](CVar* c) { m_debugOverlayCorner = c->toSigned(); }); + m_cvarCommons.m_debugInputOverlayCorner->addListener([this](CVar* c) { m_inputOverlayCorner = c->toSigned(); }); + m_cvarCommons.m_lastDiscPath->addListener([this](CVar* c) { m_lastDiscPath = c->toLiteral(); }); + m_cvarMgr.findCVar("developer")->addListener([this](CVar* c) { m_developer = c->toBoolean(); }); + m_cvarMgr.findCVar("cheats")->addListener([this](CVar* c) { m_cheats = c->toBoolean(); }); } - // We ned to make sure we have a valid CRandom16 at all times, so lets do that here + if (!preLaunch && !m_isLaunchInitialized) { + if (m_developer) { + m_toasts.emplace_back("Press Left Alt to toggle menu"s, 5.f); + } + m_isLaunchInitialized = true; + } + // We need to make sure we have a valid CRandom16 at all times, so let's do that here if (g_StateManager != nullptr && g_StateManager->GetActiveRandom() == nullptr) { g_StateManager->SetActiveRandomToDefault(); } - if (ImGui::IsKeyReleased('`')) { - m_isVisible ^= 1; - } - if (m_stepFrame) { - g_Main->SetPaused(true); - m_stepFrame = false; - } - if (m_paused && !m_stepFrame && ImGui::IsKeyPressed(TranslateBooSpecialKey(boo::ESpecialKey::F6))) { - g_Main->SetPaused(false); - m_stepFrame = true; - } - if (ImGui::IsKeyReleased(TranslateBooSpecialKey(boo::ESpecialKey::F5))) { - m_paused ^= 1; - g_Main->SetPaused(m_paused); + if (!preLaunch) { + if (m_stepFrame) { + g_Main->SetPaused(true); + m_stepFrame = false; + } + if (m_paused && !m_stepFrame && ImGui::IsKeyPressed(ImGuiKey_F6)) { + g_Main->SetPaused(false); + m_stepFrame = true; + } + if (ImGui::IsKeyReleased(ImGuiKey_F5)) { + m_paused ^= 1; + g_Main->SetPaused(m_paused); + } } bool canInspect = g_StateManager != nullptr && g_StateManager->GetObjectList(); - if (m_isVisible) { - ShowAppMainMenuBar(canInspect); - } else if (m_developer) { - ShowMenuHint(); + if (preLaunch || m_isVisible) { + ShowAppMainMenuBar(canInspect, preLaunch); } + ShowToasts(); if (canInspect && (m_showInspectWindow || !inspectingEntities.empty())) { UpdateEntityEntries(); if (m_showInspectWindow) { @@ -1189,8 +1396,8 @@ void ImGuiConsole::PreUpdate() { if (canInspect && m_showLayersWindow) { ShowLayersWindow(); } - if (m_showAboutWindow) { - ShowAboutWindow(true); + if (preLaunch || m_showAboutWindow) { + ShowAboutWindow(preLaunch); } if (m_showDemoWindow) { ImGui::ShowDemoWindow(&m_showDemoWindow); @@ -1201,6 +1408,11 @@ void ImGuiConsole::PreUpdate() { ShowDebugOverlay(); ShowInputViewer(); ShowPlayerTransformEditor(); + ShowPipelineProgress(); + m_controllerConfig.show(m_controllerConfigVisible); + if (preLaunch && m_showPreLaunchSettingsWindow) { + ShowPreLaunchSettingsWindow(); + } } void ImGuiConsole::PostUpdate() { @@ -1228,7 +1440,7 @@ void ImGuiConsole::PostUpdate() { // Always calculate room time regardless of if the overlay is displayed, this allows us have an accurate display if // the user chooses to display it later on during gameplay - if (g_StateManager && m_currentRoom != g_StateManager->GetCurrentArea()) { + if (g_StateManager != nullptr && m_currentRoom != g_StateManager->GetCurrentArea()) { const double igt = g_GameState->GetTotalPlayTime(); m_currentRoom = static_cast(g_StateManager->GetCurrentArea()); m_lastRoomTime = igt - m_currentRoomStart; @@ -1239,6 +1451,9 @@ void ImGuiConsole::PostUpdate() { void ImGuiConsole::Shutdown() { dummyWorlds.clear(); stringTables.clear(); +#ifdef NATIVEFILEDIALOG_SUPPORTED + NFD::Quit(); +#endif } static constexpr std::array GeneralItems{ @@ -1451,7 +1666,7 @@ void ImGuiConsole::ShowItemsWindow() { void ImGuiConsole::ShowLayersWindow() { // For some reason the window shows up tiny without this - float initialWindowSize = 350.f * ImGui::GetIO().DisplayFramebufferScale.x; + float initialWindowSize = 350.f * GetScale(); ImGui::SetNextWindowSize(ImVec2{initialWindowSize, initialWindowSize}, ImGuiCond_FirstUseEver); if (ImGui::Begin("Layers", &m_showLayersWindow)) { @@ -1519,11 +1734,14 @@ void ImGuiConsole::ShowLayersWindow() { ImGui::End(); } -void ImGuiConsole::ShowMenuHint() { - if (m_menuHintTime <= 0.f) { +void ImGuiConsole::ShowToasts() { + if (m_toasts.empty()) { return; } - m_menuHintTime -= ImGui::GetIO().DeltaTime; + auto& toast = m_toasts.front(); + const float dt = ImGui::GetIO().DeltaTime; + toast.remain -= dt; + toast.current += dt; const ImGuiViewport* viewport = ImGui::GetMainViewport(); const ImVec2 workPos = viewport->WorkPos; @@ -1532,7 +1750,7 @@ void ImGuiConsole::ShowMenuHint() { const ImVec2 windowPos{workPos.x + workSize.x / 2, workPos.y + workSize.y - padding}; ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, ImVec2{0.5f, 1.f}); - const float alpha = std::min(m_menuHintTime, 1.f); + const float alpha = std::min({toast.remain, toast.current, 1.f}); ImGui::SetNextWindowBgAlpha(alpha * 0.65f); ImVec4 textColor = ImGui::GetStyleColorVec4(ImGuiCol_Text); textColor.w *= alpha; @@ -1540,14 +1758,18 @@ void ImGuiConsole::ShowMenuHint() { borderColor.w *= alpha; ImGui::PushStyleColor(ImGuiCol_Text, textColor); ImGui::PushStyleColor(ImGuiCol_Border, borderColor); - if (ImGui::Begin("Menu Hint", nullptr, + if (ImGui::Begin("Toast", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav | ImGuiWindowFlags_NoMove)) { - ImGuiStringViewText("Press ` to toggle menu"sv); + ImGuiStringViewText(toast.message); } ImGui::End(); ImGui::PopStyleColor(2); + + if (toast.remain <= 0.f) { + m_toasts.pop_front(); + } } void ImGuiConsole::ShowPlayerTransformEditor() { @@ -1617,4 +1839,189 @@ void ImGuiConsole::ShowPlayerTransformEditor() { } ImGui::End(); } + +void ImGuiConsole::ShowPipelineProgress() { + const u32 queuedPipelines = aurora::gfx::queuedPipelines; + if (queuedPipelines == 0) { + return; + } + const u32 createdPipelines = aurora::gfx::createdPipelines; + const u32 totalPipelines = queuedPipelines + createdPipelines; + + const auto* viewport = ImGui::GetMainViewport(); + const auto padding = viewport->WorkPos.y + 10.f; + const auto halfWidth = viewport->GetWorkCenter().x; + ImGui::SetNextWindowPos(ImVec2{halfWidth, padding}, ImGuiCond_Always, ImVec2{0.5f, 0.f}); + ImGui::SetNextWindowSize(ImVec2{halfWidth, 0.f}, ImGuiCond_Always); + ImGui::SetNextWindowBgAlpha(0.65f); + ImGui::Begin("Pipelines", nullptr, + ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | + ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing); + const auto percent = static_cast(createdPipelines) / static_cast(totalPipelines); + const auto progressStr = fmt::format(FMT_STRING("Processing pipelines: {} / {}"), createdPipelines, totalPipelines); + const auto textSize = ImGui::CalcTextSize(progressStr.data(), progressStr.data() + progressStr.size()); + ImGui::NewLine(); + ImGui::SameLine(ImGui::GetWindowWidth() / 2.f - textSize.x + textSize.x / 2.f); + ImGuiStringViewText(progressStr); + ImGui::ProgressBar(percent); + ImGui::End(); +} + +void ImGuiConsole::ControllerAdded(uint32_t idx) { + const char* name = PADGetName(idx); + if (name != nullptr) { + m_toasts.emplace_back(fmt::format(FMT_STRING("Controller {} ({}) connected"), idx, name), 5.f); + } else { + m_toasts.emplace_back(fmt::format(FMT_STRING("Controller {} connected"), idx), 5.f); + } +} + +void ImGuiConsole::ControllerRemoved(uint32_t idx) { + m_toasts.emplace_back(fmt::format(FMT_STRING("Controller {} disconnected"), idx), 5.f); +} + +static void ImGuiCVarCheckbox(CVarManager& mgr, std::string_view cvarName, const char* label, bool* ptr = nullptr) { + auto* cvar = mgr.findCVar(cvarName); + if (cvar != nullptr) { + bool value = cvar->toBoolean(); + bool modified = false; + if (ptr == nullptr) { + modified = ImGui::Checkbox(label, &value); + } else { + modified = ImGui::Checkbox(label, ptr); + value = *ptr; + } + // Kinda useless for these tbh + // std::string tooltip{cvar->rawHelp()}; + // if (!tooltip.empty() && ImGui::IsItemHovered()) { + // ImGui::SetTooltip("%s", tooltip.c_str()); + // } + if (modified) { + cvar->unlock(); + cvar->fromBoolean(value); + cvar->lock(); + } + } +} + +void ImGuiConsole::ShowPreLaunchSettingsWindow() { + if (ImGui::Begin("Settings", &m_showPreLaunchSettingsWindow, ImGuiWindowFlags_AlwaysAutoResize)) { + if (ImGui::BeginTabBar("Settings")) { + if (ImGui::BeginTabItem("Graphics")) { + size_t backendCount = 0; + const auto* backends = aurora_get_available_backends(&backendCount); + ImGuiStringViewText(fmt::format(FMT_STRING("Current backend: {}"), backend_name(aurora_get_backend()))); + auto desiredBackend = static_cast(BACKEND_AUTO); + if (auto* cvar = m_cvarMgr.findCVar("graphicsApi")) { + bool valid = false; + const auto name = cvar->toLiteral(&valid); + if (valid) { + desiredBackend = static_cast(backend_from_string(name)); + } + } + bool modified = false; + modified = ImGui::RadioButton("Auto", &desiredBackend, static_cast(BACKEND_AUTO)); + for (size_t i = 0; i < backendCount; ++i, ++backends) { + const auto backend = *backends; + modified = + ImGui::RadioButton(backend_name(backend).data(), &desiredBackend, static_cast(backend)) || modified; + } + if (modified) { + m_cvarCommons.m_graphicsApi->fromLiteral(backend_to_string(static_cast(desiredBackend))); + } + ImGuiCVarCheckbox(m_cvarMgr, "fullscreen", "Fullscreen"); + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Game")) { + ImGuiCVarCheckbox(m_cvarMgr, "allowJoystickInBackground", "Enable Background Joystick Input"); + ImGuiCVarCheckbox(m_cvarMgr, "tweak.game.SplashScreensDisabled", "Skip Splash Screens"); + ImGuiCVarCheckbox(m_cvarMgr, "cheats", "Enable Cheats", &m_cheats); + if (m_cheats) { + ImGuiCVarCheckbox(m_cvarMgr, "developer", "Developer Mode", &m_developer); + } + ImGui::EndTabItem(); + } + if (ImGui::BeginTabItem("Experimental")) { + ImGuiCVarCheckbox(m_cvarMgr, "variableDt", "Variable Delta Time (broken)"); + ImGui::EndTabItem(); + } + ImGui::EndTabBar(); + } + } + ImGui::End(); +} + +static bool eq(std::string_view a, std::string_view b) { + if (a.size() != b.size()) { + return false; + } + return std::equal(a.begin(), a.end(), b.begin(), b.end(), [](char a, char b) { return tolower(a) == b; }); +} + +AuroraBackend backend_from_string(const std::string& str) { + if (eq(str, "d3d12"sv) || eq(str, "d3d"sv)) { + return BACKEND_D3D12; + } + if (eq(str, "metal"sv)) { + return BACKEND_METAL; + } + if (eq(str, "vulkan"sv) || eq(str, "vk"sv)) { + return BACKEND_VULKAN; + } + if (eq(str, "opengl"sv) || eq(str, "gl"sv)) { + return BACKEND_OPENGL; + } + if (eq(str, "opengles"sv) || eq(str, "gles"sv)) { + return BACKEND_OPENGLES; + } + if (eq(str, "webgpu"sv) || eq(str, "wgpu"sv)) { + return BACKEND_WEBGPU; + } + if (eq(str, "null"sv) || eq(str, "none"sv)) { + return BACKEND_NULL; + } + return BACKEND_AUTO; +} + +std::string_view backend_to_string(AuroraBackend backend) { + switch (backend) { + default: + return "auto"sv; + case BACKEND_D3D12: + return "d3d12"sv; + case BACKEND_METAL: + return "metal"sv; + case BACKEND_VULKAN: + return "vulkan"sv; + case BACKEND_OPENGL: + return "opengl"sv; + case BACKEND_OPENGLES: + return "opengles"sv; + case BACKEND_WEBGPU: + return "webgpu"sv; + case BACKEND_NULL: + return "null"sv; + } +} + +std::string_view backend_name(AuroraBackend backend) { + switch (backend) { + default: + return "Auto"sv; + case BACKEND_D3D12: + return "D3D12"sv; + case BACKEND_METAL: + return "Metal"sv; + case BACKEND_VULKAN: + return "Vulkan"sv; + case BACKEND_OPENGL: + return "OpenGL"sv; + case BACKEND_OPENGLES: + return "OpenGL ES"sv; + case BACKEND_WEBGPU: + return "WebGPU"sv; + case BACKEND_NULL: + return "Null"sv; + } +} } // namespace metaforce diff --git a/Runtime/ImGuiConsole.hpp b/Runtime/ImGuiConsole.hpp index 071c7ac0c..a87737c18 100644 --- a/Runtime/ImGuiConsole.hpp +++ b/Runtime/ImGuiConsole.hpp @@ -2,17 +2,23 @@ #include #include +#include -#include "RetroTypes.hpp" +#include "Runtime/RetroTypes.hpp" #include "Runtime/World/CActor.hpp" #include "Runtime/World/CEntity.hpp" #include "Runtime/ImGuiPlayerLoadouts.hpp" +#include "Runtime/ImGuiControllerConfig.hpp" -#include "hecl/CVarCommons.hpp" -#include "hecl/CVarManager.hpp" +#include "Runtime/ConsoleVariables/CVarCommons.hpp" +#include "Runtime/ConsoleVariables/CVarManager.hpp" #include +#if __APPLE__ +#include +#endif + namespace metaforce { void ImGuiStringViewText(std::string_view text); void ImGuiTextCenter(std::string_view text); @@ -33,25 +39,38 @@ struct ImGuiEntityEntry { [[nodiscard]] CActor* AsActor() const { return isActor ? static_cast(ent) : nullptr; } }; +struct Toast { + std::string message; + float remain; + float current = 0.f; + Toast(std::string message, float duration) noexcept : message(std::move(message)), remain(duration) {} +}; + class ImGuiConsole { public: static std::set inspectingEntities; static std::array entities; static ImGuiPlayerLoadouts loadouts; - ImGuiConsole(hecl::CVarManager& cvarMgr, hecl::CVarCommons& cvarCommons) - : m_cvarMgr(cvarMgr), m_cvarCommons(cvarCommons) {} + ImGuiConsole(CVarManager& cvarMgr, CVarCommons& cvarCommons); void PreUpdate(); void PostUpdate(); void Shutdown(); - void ShowAboutWindow(bool canClose, std::string_view errorString = ""sv); static void BeginEntityRow(const ImGuiEntityEntry& entry); static void EndEntityRow(const ImGuiEntityEntry& entry); + void ControllerAdded(uint32_t idx); + void ControllerRemoved(uint32_t idx); + void ToggleVisible(); + + std::optional m_errorString; + std::optional m_gameDiscSelected; + bool m_quitRequested = false; + private: - hecl::CVarManager& m_cvarMgr; - hecl::CVarCommons& m_cvarCommons; + CVarManager& m_cvarMgr; + CVarCommons& m_cvarCommons; bool m_showInspectWindow = false; bool m_showDemoWindow = false; @@ -60,6 +79,7 @@ private: bool m_showLayersWindow = false; bool m_showConsoleVariablesWindow = false; bool m_showPlayerTransformEditor = false; + bool m_showPreLaunchSettingsWindow = false; std::optional m_savedLocation; std::optional m_savedRotation; @@ -73,10 +93,15 @@ private: std::string m_inspectFilterText; std::string m_layersFilterText; std::string m_cvarFiltersText; + std::string m_lastDiscPath = m_cvarCommons.m_lastDiscPath->toLiteral(); // Debug overlays bool m_frameCounter = m_cvarCommons.m_debugOverlayShowFrameCounter->toBoolean(); +#if TARGET_OS_TV + bool m_frameRate = true; +#else bool m_frameRate = m_cvarCommons.m_debugOverlayShowFramerate->toBoolean(); +#endif bool m_inGameTime = m_cvarCommons.m_debugOverlayShowInGameTime->toBoolean(); bool m_roomTimer = m_cvarCommons.m_debugOverlayShowRoomTimer->toBoolean(); bool m_playerInfo = m_cvarCommons.m_debugOverlayPlayerInfo->toBoolean(); @@ -86,18 +111,39 @@ private: bool m_randomStats = m_cvarCommons.m_debugOverlayShowRandomStats->toBoolean(); bool m_resourceStats = m_cvarCommons.m_debugOverlayShowResourceStats->toBoolean(); bool m_showInput = m_cvarCommons.m_debugOverlayShowInput->toBoolean(); + bool m_drawAiPath = m_cvarCommons.m_debugToolDrawAiPath->toBoolean(); + bool m_drawCollisionActors = m_cvarCommons.m_debugToolDrawCollisionActors->toBoolean(); + bool m_drawPlatformCollision = m_cvarCommons.m_debugToolDrawPlatformCollision->toBoolean(); + bool m_drawMazePath = m_cvarCommons.m_debugToolDrawMazePath->toBoolean(); + bool m_drawLighting = m_cvarCommons.m_debugToolDrawLighting->toBoolean(); +#if TARGET_OS_IOS + bool m_pipelineInfo = false; + bool m_drawCallInfo = false; + bool m_bufferInfo = false; +#else + bool m_pipelineInfo = m_cvarCommons.m_debugOverlayPipelineInfo->toBoolean(); // TODO cvar + bool m_drawCallInfo = m_cvarCommons.m_debugOverlayDrawCallInfo->toBoolean(); // TODO cvar + bool m_bufferInfo = m_cvarCommons.m_debugOverlayBufferInfo->toBoolean(); // TODO cvar +#endif bool m_developer = m_cvarMgr.findCVar("developer")->toBoolean(); bool m_cheats = m_cvarMgr.findCVar("cheats")->toBoolean(); bool m_isInitialized = false; + bool m_isLaunchInitialized = false; - int m_debugOverlayCorner = 2; // bottom-left - int m_inputOverlayCorner = 3; // bottom-right + int m_debugOverlayCorner = m_cvarCommons.m_debugOverlayCorner->toSigned(); + int m_inputOverlayCorner = m_cvarCommons.m_debugInputOverlayCorner->toSigned(); const void* m_currentRoom = nullptr; double m_lastRoomTime = 0.f; double m_currentRoomStart = 0.f; - float m_menuHintTime = 5.f; + std::deque m_toasts; + std::string m_controllerName; + u32 m_whichController = -1; - void ShowAppMainMenuBar(bool canInspect); + bool m_controllerConfigVisible = false; + ImGuiControllerConfig m_controllerConfig; + + void ShowAboutWindow(bool preLaunch); + void ShowAppMainMenuBar(bool canInspect, bool preLaunch); void ShowMenuGame(); bool ShowEntityInfoWindow(TUniqueId uid); void ShowInspectWindow(bool* isOpen); @@ -107,10 +153,16 @@ private: void ShowItemsWindow(); void ShowLayersWindow(); void ShowConsoleVariablesWindow(); - void ShowMenuHint(); + void ShowToasts(); void ShowInputViewer(); void SetOverlayWindowLocation(int corner) const; - void ShowCornerContextMenu(int& corner, int avoidCorner) const; + bool ShowCornerContextMenu(int& corner, int avoidCorner) const; void ShowPlayerTransformEditor(); + void ShowPipelineProgress(); + void ShowPreLaunchSettingsWindow(); }; + +AuroraBackend backend_from_string(const std::string& str); +std::string_view backend_to_string(AuroraBackend backend); +std::string_view backend_name(AuroraBackend backend); } // namespace metaforce diff --git a/Runtime/ImGuiControllerConfig.cpp b/Runtime/ImGuiControllerConfig.cpp new file mode 100644 index 000000000..39a564942 --- /dev/null +++ b/Runtime/ImGuiControllerConfig.cpp @@ -0,0 +1,238 @@ +#include "Runtime/ImGuiControllerConfig.hpp" + +#include "Runtime/RetroTypes.hpp" +#include "Runtime/Streams/CFileOutStream.hpp" +#include "Runtime/Streams/ContainerReaders.hpp" +#include "Runtime/Streams/ContainerWriters.hpp" + +#include + +namespace metaforce { +ImGuiControllerConfig::Button::Button(CInputStream& in) +: button(in.Get()) +, uvX(in.Get()) +, uvY(in.Get()) +, width(in.Get()) +, height(in.Get()) +, offX(in.Get()) +, offY(in.Get()) {} + +void ImGuiControllerConfig::Button::PutTo(COutputStream& out) const { + out.Put(button); + out.Put(uvX); + out.Put(uvY); + out.Put(width); + out.Put(height); + out.Put(offX); + out.Put(offY); +} + +ImGuiControllerConfig::ControllerAtlas::ControllerAtlas(CInputStream& in) : name(in.Get()) { + u32 vidPidCount = in.Get(); + vidPids.reserve(vidPidCount); + + for (u32 i = 0; i < vidPidCount; ++i) { + u16 vid = static_cast(in.Get()); + u16 pid = static_cast(in.Get()); + vidPids.emplace_back(vid, pid); + } + + atlasFile = in.Get(); + read_vector(buttons, in); +}; + +void ImGuiControllerConfig::ControllerAtlas::PutTo(COutputStream& out) const { + out.Put(name); + out.Put(static_cast(vidPids.size())); + for (const auto& vidPid : vidPids) { + out.Put(vidPid.first); + out.Put(vidPid.second); + } + + write_vector(buttons, out); +} + +void ImGuiControllerConfig::show(bool& visible) { + + /** TODO: + * - Implement multiple controllers + * - Implement setting controller ports (except for the GameCube adapter, which is hard coded) + * - Implement fancy graphical UI + */ + + if (!visible) { + return; + } + + if (m_pendingMapping != nullptr) { + s32 nativeButton = PADGetNativeButtonPressed(m_pendingPort); + if (nativeButton != -1) { + m_pendingMapping->nativeButton = nativeButton; + m_pendingMapping = nullptr; + m_pendingPort = -1; + PADBlockInput(false); + } + } + + std::vector controllers; + controllers.push_back("None"); + for (u32 i = 0; i < PADCount(); ++i) { + controllers.push_back(fmt::format(FMT_STRING("{}-{}"), PADGetNameForControllerIndex(i), i)); + } + + m_pendingValid = false; + if (ImGui::Begin("Controller Config", &visible)) { + if (ImGui::CollapsingHeader("Ports")) { + for (u32 i = 0; i < 4; ++i) { + ImGui::PushID(fmt::format(FMT_STRING("PortConf-{}"), i).c_str()); + s32 index = PADGetIndexForPort(i); + int sel = 0; + std::string name = "None"; + const char* tmpName = PADGetName(i); + bool changed = false; + if (tmpName != nullptr) { + name = fmt::format(FMT_STRING("{}-{}"), tmpName, index); + } + if (ImGui::BeginCombo(fmt::format(FMT_STRING("Port {}"), i + 1).c_str(), name.c_str())) { + for (u32 j = 0; const auto& s : controllers) { + if (ImGui::Selectable(s.c_str(), name == s)) { + sel = j; + changed = true; + } + ++j; + } + ImGui::EndCombo(); + } + + if (changed) { + if (sel > 0) { + PADSetPortForIndex(sel - 1, i); + } else if (sel == 0) { + PADClearPort(i); + } + } + ImGui::PopID(); + } + } + if (ImGui::BeginTabBar("Controllers")) { + for (u32 i = 0; i < 4; ++i) { + if (ImGui::BeginTabItem(fmt::format(FMT_STRING("Port {}"), i + 1).c_str())) { + ImGui::PushID(fmt::format(FMT_STRING("Port_{}"), i + 1).c_str()); + /* If the tab is changed while pending for input, cancel the pending port */ + if (m_pendingMapping != nullptr && m_pendingPort != i) { + m_pendingMapping = nullptr; + m_pendingValid = false; + m_pendingPort = -1; + PADBlockInput(false); + } + u32 vid, pid; + PADGetVidPid(i, &vid, &pid); + if (vid == 0 && pid == 0) { + ImGui::EndTabItem(); + ImGui::PopID(); + continue; + } + ImGui::Text("%s", PADGetName(i)); + u32 buttonCount = 0; + PADButtonMapping* mapping = PADGetButtonMappings(i, &buttonCount); + if (mapping != nullptr) { + for (u32 m = 0; m < buttonCount; ++m) { + const char* padName = PADGetButtonName(mapping[m].padButton); + if (padName == nullptr) { + continue; + } + ImGui::PushID(padName); + bool pressed = ImGui::Button(padName); + ImGui::SameLine(); + ImGui::Text("%s", PADGetNativeButtonName(mapping[m].nativeButton)); + + if (pressed && m_pendingMapping == nullptr) { + m_pendingMapping = &mapping[m]; + m_pendingPort = i; + PADBlockInput(true); + } + + if (m_pendingMapping == &mapping[m]) { + m_pendingValid = true; + ImGui::SameLine(); + ImGui::Text(" - Waiting for button..."); + } + ImGui::PopID(); + } + } + + if (ImGui::CollapsingHeader("Dead-zones")) { + PADDeadZones* deadZones = PADGetDeadZones(i); + ImGui::Checkbox("Use Dead-zones", &deadZones->useDeadzones); + float tmp = static_cast(deadZones->stickDeadZone * 100.f) / 32767.f; + if (ImGui::DragFloat("Left Stick", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { + deadZones->stickDeadZone = static_cast((tmp / 100.f) * 32767); + } + tmp = static_cast(deadZones->substickDeadZone * 100.f) / 32767.f; + if (ImGui::DragFloat("Right Stick", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { + deadZones->substickDeadZone = static_cast((tmp / 100.f) * 32767); + } + ImGui::Checkbox("Emulate Triggers", &deadZones->emulateTriggers); + tmp = static_cast(deadZones->leftTriggerActivationZone * 100.f) / 32767.f; + if (ImGui::DragFloat("Left Trigger Activation", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { + deadZones->leftTriggerActivationZone = static_cast((tmp / 100.f) * 32767); + } + tmp = static_cast(deadZones->rightTriggerActivationZone * 100.f) / 32767.f; + if (ImGui::DragFloat("Right Trigger Activation", &tmp, 0.5f, 0.f, 100.f, "%.3f%%")) { + deadZones->rightTriggerActivationZone = static_cast((tmp / 100.f) * 32767); + } + } + ImGui::PopID(); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); + } + + ImGui::Separator(); + if (ImGui::Button("Display Editor")) { + m_editorVisible = true; + } + ImGui::SameLine(); + if (ImGui::Button("Save Mappings")) { + PADSerializeMappings(); + } + ImGui::SameLine(); + if (ImGui::Button("Restore Defaults")) { + for (u32 i = 0; i < 4; ++i) { + PADRestoreDefaultMapping(i); + } + } + } + ImGui::End(); + + showEditor(m_editorVisible); +} + +void ImGuiControllerConfig::showEditor(bool& visible) { + if (!visible) { + return; + } + + if (ImGui::Begin("Controller Atlas Editor", &visible)) { + /* TODO: Atlas editor */ + ImGui::Separator(); + if (ImGui::Button("Save Controller Database")) { + CFileOutStream out("ControllerAtlases.ctrdb"); + out.WriteUint32(SLITTLE('CTDB')); + out.WriteUint32(1); // Version + write_vector(m_controllerAtlases, out); + } + ImGui::SameLine(); + if (ImGui::Button("Export") && m_currentAtlas != nullptr) { + CFileOutStream out("test.ctratlas"); + out.Put(SLITTLE('CTRA')); + out.Put(1); // Version + out.Put(*m_currentAtlas); + } + + /* TODO: Import logic */ + } + ImGui::End(); +} +} // namespace metaforce diff --git a/Runtime/ImGuiControllerConfig.hpp b/Runtime/ImGuiControllerConfig.hpp new file mode 100644 index 000000000..446abdc12 --- /dev/null +++ b/Runtime/ImGuiControllerConfig.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include "Runtime/GCNTypes.hpp" +#include "Runtime/Streams/CInputStream.hpp" +#include "Runtime/Streams/COutputStream.hpp" + +#include "imgui.h" +#include + +#include +#include +#include +#include + +namespace metaforce { +class ImGuiControllerConfig { + struct Button { + s32 button = -1; // the SDL button this entry corresponds to + u32 uvX = 0; // Offset if icon image in atlas from left (in pixels) + u32 uvY = 0; // Offset if icon image in atlas from top (in pixels) + u32 width = 32; // Width of button image (in pixels) + u32 height = 32; // Height of button image (in pixels) + float offX = 0.f; // Offset from left of config window + float offY = 0.f; // Offset from top of config window + + Button() = default; + explicit Button(CInputStream& in); + void PutTo(COutputStream& in) const; + }; + + struct ControllerAtlas { + std::string name; + std::vector> vidPids; + std::string atlasFile; // Path to atlas relative to controller definition + std::vector