Plugins agregados

This commit is contained in:
2026-03-30 15:33:19 -06:00
parent df2b257d93
commit eefc67e50a
766 changed files with 107667 additions and 0 deletions

355
OTRExporter/.gitignore vendored Normal file
View File

@@ -0,0 +1,355 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
*.out
*.o
*.d
lib/libgfxd/libgfxd.a
ExporterTest/ExporterTest.a
ZAPDUtils/ZAPDUtils.a
.vscode/
build/
ZAPDUtils/build/
ZAPD/BuildInfo.h
baserom/
baserom_ntsc/
*.vtx.inc
*.otr
*.o2r
*.swp
*.a
*.z64
*.n64
*.zip
Extract/
tmp.txt

View File

@@ -0,0 +1,65 @@
################################################################################
# Command for variable_watch. This command issues error message, if a variable
# is changed. If variable PROPERTY_READER_GUARD_DISABLED is TRUE nothing happens
# variable_watch(<variable> property_reader_guard)
################################################################################
function(property_reader_guard VARIABLE ACCESS VALUE CURRENT_LIST_FILE STACK)
if("${PROPERTY_READER_GUARD_DISABLED}")
return()
endif()
if("${ACCESS}" STREQUAL "MODIFIED_ACCESS")
message(FATAL_ERROR
" Variable ${VARIABLE} is not supposed to be changed.\n"
" It is used only for reading target property ${VARIABLE}.\n"
" Use\n"
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}\" \"<value>\")\n"
" or\n"
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}_<CONFIG>\" \"<value>\")\n"
" instead.\n")
endif()
endfunction()
################################################################################
# Create variable <name> with generator expression that expands to value of
# target property <name>_<CONFIG>. If property is empty or not set then property
# <name> is used instead. Variable <name> has watcher property_reader_guard that
# doesn't allow to edit it.
# create_property_reader(<name>)
# Input:
# name - Name of watched property and output variable
################################################################################
function(create_property_reader NAME)
set(PROPERTY_READER_GUARD_DISABLED TRUE)
set(CONFIG_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}_$<UPPER_CASE:$<CONFIG>>>>")
set(IS_CONFIG_VALUE_EMPTY "$<STREQUAL:${CONFIG_VALUE},>")
set(GENERAL_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}>>")
set("${NAME}" "$<IF:${IS_CONFIG_VALUE_EMPTY},${GENERAL_VALUE},${CONFIG_VALUE}>" PARENT_SCOPE)
variable_watch("${NAME}" property_reader_guard)
endfunction()
################################################################################
# Set property $<name>_${PROPS_CONFIG_U} of ${PROPS_TARGET} to <value>
# set_config_specific_property(<name> <value>)
# Input:
# name - Prefix of property name
# value - New value
################################################################################
function(set_config_specific_property NAME VALUE)
set_target_properties("${PROPS_TARGET}" PROPERTIES "${NAME}_${PROPS_CONFIG_U}" "${VALUE}")
endfunction()
################################################################################
create_property_reader("TARGET_NAME")
create_property_reader("OUTPUT_DIRECTORY")
set_config_specific_property("TARGET_NAME" "${PROPS_TARGET}")
set_config_specific_property("OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("ARCHIVE_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("LIBRARY_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("RUNTIME_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("ARCHIVE_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
set_config_specific_property("LIBRARY_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
set_config_specific_property("RUNTIME_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")

View File

@@ -0,0 +1,16 @@
include("${CMAKE_CURRENT_LIST_DIR}/Default.cmake")
set_config_specific_property("OUTPUT_DIRECTORY" "${CMAKE_SOURCE_DIR}$<$<NOT:$<STREQUAL:${CMAKE_VS_PLATFORM_NAME},Win32>>:/${CMAKE_VS_PLATFORM_NAME}>/${PROPS_CONFIG}")
if(MSVC)
create_property_reader("DEFAULT_CXX_EXCEPTION_HANDLING")
create_property_reader("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT")
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
if (CMAKE_C_COMPILER_LAUNCHER MATCHES "ccache|sccache")
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Z7")
else()
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
endif()
endif()

View File

@@ -0,0 +1,233 @@
# utils file for projects came from visual studio solution with cmake-converter.
################################################################################
# Wrap each token of the command with condition
################################################################################
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW)
macro(prepare_commands)
unset(TOKEN_ROLE)
unset(COMMANDS)
foreach(TOKEN ${ARG_COMMANDS})
if("${TOKEN}" STREQUAL "COMMAND")
set(TOKEN_ROLE "KEYWORD")
elseif("${TOKEN_ROLE}" STREQUAL "KEYWORD")
set(TOKEN_ROLE "CONDITION")
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
set(TOKEN_ROLE "COMMAND")
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
set(TOKEN_ROLE "ARG")
endif()
if("${TOKEN_ROLE}" STREQUAL "KEYWORD")
list(APPEND COMMANDS "${TOKEN}")
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
set(CONDITION ${TOKEN})
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
list(APPEND COMMANDS "$<$<NOT:${CONDITION}>:${DUMMY}>$<${CONDITION}:${TOKEN}>")
elseif("${TOKEN_ROLE}" STREQUAL "ARG")
list(APPEND COMMANDS "$<${CONDITION}:${TOKEN}>")
endif()
endforeach()
endmacro()
cmake_policy(POP)
################################################################################
# Transform all the tokens to absolute paths
################################################################################
macro(prepare_output)
unset(OUTPUT)
foreach(TOKEN ${ARG_OUTPUT})
if(IS_ABSOLUTE ${TOKEN})
list(APPEND OUTPUT "${TOKEN}")
else()
list(APPEND OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${TOKEN}")
endif()
endforeach()
endmacro()
################################################################################
# Parse add_custom_command_if args.
#
# Input:
# PRE_BUILD - Pre build event option
# PRE_LINK - Pre link event option
# POST_BUILD - Post build event option
# TARGET - Target
# OUTPUT - List of output files
# DEPENDS - List of files on which the command depends
# COMMANDS - List of commands(COMMAND condition1 commannd1 args1 COMMAND
# condition2 commannd2 args2 ...)
# Output:
# OUTPUT - Output files
# DEPENDS - Files on which the command depends
# COMMENT - Comment
# PRE_BUILD - TRUE/FALSE
# PRE_LINK - TRUE/FALSE
# POST_BUILD - TRUE/FALSE
# TARGET - Target name
# COMMANDS - Prepared commands(every token is wrapped in CONDITION)
# NAME - Unique name for custom target
# STEP - PRE_BUILD/PRE_LINK/POST_BUILD
################################################################################
function(add_custom_command_if_parse_arguments)
cmake_parse_arguments("ARG" "PRE_BUILD;PRE_LINK;POST_BUILD" "TARGET;COMMENT" "DEPENDS;OUTPUT;COMMANDS" ${ARGN})
if(WIN32)
set(DUMMY "cd.")
elseif(UNIX)
set(DUMMY "true")
endif()
prepare_commands()
prepare_output()
set(DEPENDS "${ARG_DEPENDS}")
set(COMMENT "${ARG_COMMENT}")
set(PRE_BUILD "${ARG_PRE_BUILD}")
set(PRE_LINK "${ARG_PRE_LINK}")
set(POST_BUILD "${ARG_POST_BUILD}")
set(TARGET "${ARG_TARGET}")
if(PRE_BUILD)
set(STEP "PRE_BUILD")
elseif(PRE_LINK)
set(STEP "PRE_LINK")
elseif(POST_BUILD)
set(STEP "POST_BUILD")
endif()
set(NAME "${TARGET}_${STEP}")
set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
set(DEPENDS "${DEPENDS}" PARENT_SCOPE)
set(COMMENT "${COMMENT}" PARENT_SCOPE)
set(PRE_BUILD "${PRE_BUILD}" PARENT_SCOPE)
set(PRE_LINK "${PRE_LINK}" PARENT_SCOPE)
set(POST_BUILD "${POST_BUILD}" PARENT_SCOPE)
set(TARGET "${TARGET}" PARENT_SCOPE)
set(COMMANDS "${COMMANDS}" PARENT_SCOPE)
set(STEP "${STEP}" PARENT_SCOPE)
set(NAME "${NAME}" PARENT_SCOPE)
endfunction()
################################################################################
# Add conditional custom command
#
# Generating Files
# The first signature is for adding a custom command to produce an output:
# add_custom_command_if(
# <OUTPUT output1 [output2 ...]>
# <COMMANDS>
# <COMMAND condition command1 [args1...]>
# [COMMAND condition command2 [args2...]]
# [DEPENDS [depends...]]
# [COMMENT comment]
#
# Build Events
# add_custom_command_if(
# <TARGET target>
# <PRE_BUILD | PRE_LINK | POST_BUILD>
# <COMMAND condition command1 [args1...]>
# [COMMAND condition command2 [args2...]]
# [COMMENT comment]
#
# Input:
# output - Output files the command is expected to produce
# condition - Generator expression for wrapping the command
# command - Command-line(s) to execute at build time.
# args - Command`s args
# depends - Files on which the command depends
# comment - Display the given message before the commands are executed at
# build time.
# PRE_BUILD - Run before any other rules are executed within the target
# PRE_LINK - Run after sources have been compiled but before linking the
# binary
# POST_BUILD - Run after all other rules within the target have been
# executed
################################################################################
function(add_custom_command_if)
add_custom_command_if_parse_arguments(${ARGN})
if(OUTPUT AND TARGET)
message(FATAL_ERROR "Wrong syntax. A TARGET and OUTPUT can not both be specified.")
endif()
if(OUTPUT)
add_custom_command(OUTPUT ${OUTPUT}
${COMMANDS}
DEPENDS ${DEPENDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
elseif(TARGET)
if(PRE_BUILD AND NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio")
add_custom_target(
${NAME}
${COMMANDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
add_dependencies(${TARGET} ${NAME})
else()
add_custom_command(
TARGET ${TARGET}
${STEP}
${COMMANDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
endif()
else()
message(FATAL_ERROR "Wrong syntax. A TARGET or OUTPUT must be specified.")
endif()
endfunction()
################################################################################
# Use props file for a target and configs
# use_props(<target> <configs...> <props_file>)
# Inside <props_file> there are following variables:
# PROPS_TARGET - <target>
# PROPS_CONFIG - One of <configs...>
# PROPS_CONFIG_U - Uppercase PROPS_CONFIG
# Input:
# target - Target to apply props file
# configs - Build configurations to apply props file
# props_file - CMake script
################################################################################
macro(use_props TARGET CONFIGS PROPS_FILE)
set(PROPS_TARGET "${TARGET}")
foreach(PROPS_CONFIG ${CONFIGS})
string(TOUPPER "${PROPS_CONFIG}" PROPS_CONFIG_U)
get_filename_component(ABSOLUTE_PROPS_FILE "${PROPS_FILE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
if(EXISTS "${ABSOLUTE_PROPS_FILE}")
include("${ABSOLUTE_PROPS_FILE}")
else()
message(WARNING "Corresponding cmake file from props \"${ABSOLUTE_PROPS_FILE}\" doesn't exist")
endif()
endforeach()
endmacro()
################################################################################
# Add compile options to source file
# source_file_compile_options(<source_file> [compile_options...])
# Input:
# source_file - Source file
# compile_options - Options to add to COMPILE_FLAGS property
################################################################################
function(source_file_compile_options SOURCE_FILE)
if("${ARGC}" LESS_EQUAL "1")
return()
endif()
get_source_file_property(COMPILE_OPTIONS "${SOURCE_FILE}" COMPILE_OPTIONS)
if(COMPILE_OPTIONS)
list(APPEND COMPILE_OPTIONS ${ARGN})
else()
set(COMPILE_OPTIONS "${ARGN}")
endif()
set_source_files_properties("${SOURCE_FILE}" PROPERTIES COMPILE_OPTIONS "${COMPILE_OPTIONS}")
endfunction()
################################################################################
# Default properties of visual studio projects
################################################################################
set(DEFAULT_CXX_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultCXX.cmake")

View File

@@ -0,0 +1,97 @@
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
set(CMAKE_SYSTEM_VERSION 10.0 CACHE STRING "" FORCE)
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use")
project(OTRExporter C CXX)
################################################################################
# Set target arch type if empty. Visual studio solution generator provides it.
################################################################################
#if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
# if(NOT CMAKE_VS_PLATFORM_NAME)
# set(CMAKE_VS_PLATFORM_NAME "x64")
# endif()
# message("${CMAKE_VS_PLATFORM_NAME} architecture in use")
#
# if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
# OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
# message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
# endif()
#endif()
################################################################################
# Global configuration types
################################################################################
set(CMAKE_CONFIGURATION_TYPES
"Debug"
"Release"
CACHE STRING "" FORCE
)
################################################################################
# Global compiler options
################################################################################
if(MSVC)
# remove default flags provided with CMake for MSVC
set(CMAKE_C_FLAGS "")
set(CMAKE_C_FLAGS_DEBUG "")
set(CMAKE_C_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_RELEASE "")
endif()
################################################################################
# Global linker options
################################################################################
if(MSVC)
# remove default flags provided with CMake for MSVC
set(CMAKE_EXE_LINKER_FLAGS "")
set(CMAKE_MODULE_LINKER_FLAGS "")
set(CMAKE_SHARED_LINKER_FLAGS "")
set(CMAKE_STATIC_LINKER_FLAGS "")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}")
endif()
################################################################################
# Common utils
################################################################################
include(CMake/Utils.cmake)
################################################################################
# Additional Global Settings(add specific info there)
################################################################################
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
################################################################################
# Use solution folders feature
################################################################################
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
################################################################################
# Sub-projects
################################################################################
if (NOT TARGET libultraship)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libultraship ${CMAKE_BINARY_DIR}/libultraship)
endif()
if (NOT TARGET ZAPD)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../ZAPDTR/ZAPD ${CMAKE_BINARY_DIR}/ZAPD)
endif()
add_subdirectory(OTRExporter)
if (GAME_STR STREQUAL "MM")
target_compile_definitions(OTRExporter PRIVATE GAME_MM)
else()
target_compile_definitions(OTRExporter PRIVATE GAME_OOT)
endif()

9
OTRExporter/LICENSE Normal file
View File

@@ -0,0 +1,9 @@
Copyright (c) 2022 Harbour Masters
MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,92 @@
#include "AnimationExporter.h"
#ifdef GAME_MM
#include <resource/type/Animation.h>
#elif GAME_OOT
#include "../../soh/soh/resource/type/Animation.h"
#endif
#include <Globals.h>
#include "DisplayListExporter.h"
#undef FindResource
void OTRExporter_Animation::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZAnimation* anim = (ZAnimation*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Animation));
ZNormalAnimation* normalAnim = dynamic_cast<ZNormalAnimation*>(anim);
ZCurveAnimation* curveAnim = dynamic_cast<ZCurveAnimation*>(anim);
ZLinkAnimation* linkAnim = dynamic_cast<ZLinkAnimation*>(anim);
if (linkAnim != nullptr)
{
writer->Write((uint32_t)SOH::AnimationType::Link);
writer->Write((uint16_t)linkAnim->frameCount);
std::string name;
bool found = Globals::Instance->GetSegmentedPtrName((linkAnim->segmentAddress), res->parent, "", name, res->parent->workerID);
if (found)
{
if (name.at(0) == '&')
name.erase(0, 1);
writer->Write(StringHelper::Sprintf("__OTR__misc/link_animetion/%s", name.c_str()));
}
else
{
writer->Write("");
}
//writer->Write((uint32_t)linkAnim->segmentAddress);
}
else if (curveAnim != nullptr)
{
writer->Write((uint32_t)SOH::AnimationType::Curve);
writer->Write((uint16_t)curveAnim->frameCount);
writer->Write((uint32_t)curveAnim->refIndexArr.size());
for (auto val : curveAnim->refIndexArr)
writer->Write(val);
writer->Write((uint32_t)curveAnim->transformDataArr.size());
for (auto val : curveAnim->transformDataArr)
{
writer->Write(val.unk_00);
writer->Write(val.unk_02);
writer->Write(val.unk_04);
writer->Write(val.unk_06);
writer->Write(val.unk_08);
}
writer->Write((uint32_t)curveAnim->copyValuesArr.size());
for (auto val : curveAnim->copyValuesArr)
writer->Write(val);
}
else if (normalAnim != nullptr)
{
writer->Write((uint32_t)SOH::AnimationType::Normal);
writer->Write((uint16_t)normalAnim->frameCount);
writer->Write((uint32_t)normalAnim->rotationValues.size());
for (size_t i = 0; i < normalAnim->rotationValues.size(); i++)
writer->Write(normalAnim->rotationValues[i]);
writer->Write((uint32_t)normalAnim->rotationIndices.size());
for (size_t i = 0; i < normalAnim->rotationIndices.size(); i++)
{
writer->Write(normalAnim->rotationIndices[i].x);
writer->Write(normalAnim->rotationIndices[i].y);
writer->Write(normalAnim->rotationIndices[i].z);
}
writer->Write(normalAnim->limit);
}
else
{
writer->Write((uint32_t)SOH::AnimationType::Legacy);
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include "ZResource.h"
#include "ZTexture.h"
#include "ZAnimation.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Animation : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,116 @@
#include "ArrayExporter.h"
#include "VtxExporter.h"
#include <ZVector.h>
void OTRExporter_Array::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZArray* arr = (ZArray*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Array));
writer->Write((uint32_t)arr->resList[0]->GetResourceType());
writer->Write((uint32_t)arr->arrayCnt);
for (size_t i = 0; i < arr->arrayCnt; i++)
{
if (arr->resList[i]->GetResourceType() == ZResourceType::Vertex)
{
ZVtx* vtx = (ZVtx*)arr->resList[i];
writer->Write(vtx->x);
writer->Write(vtx->y);
writer->Write(vtx->z);
writer->Write(vtx->flag);
writer->Write(vtx->s);
writer->Write(vtx->t);
writer->Write(vtx->r);
writer->Write(vtx->g);
writer->Write(vtx->b);
writer->Write(vtx->a);
}
else if (arr->resList[i]->GetResourceType() == ZResourceType::Vector)
{
ZVector* vec = (ZVector*)arr->resList[i];
writer->Write((uint32_t)vec->scalarType);
writer->Write((uint32_t)vec->dimensions);
for (size_t k = 0; k < vec->dimensions; k++)
{
// OTRTODO: Duplicate code here. Cleanup at a later date...
switch (vec->scalarType)
{
case ZScalarType::ZSCALAR_S8:
writer->Write(vec->scalars[k].scalarData.s8);
break;
case ZScalarType::ZSCALAR_U8:
case ZScalarType::ZSCALAR_X8:
writer->Write(vec->scalars[k].scalarData.u8);
break;
case ZScalarType::ZSCALAR_S16:
writer->Write(vec->scalars[k].scalarData.s16);
break;
case ZScalarType::ZSCALAR_U16:
case ZScalarType::ZSCALAR_X16:
writer->Write(vec->scalars[k].scalarData.u16);
break;
case ZScalarType::ZSCALAR_S32:
writer->Write(vec->scalars[k].scalarData.s32);
break;
case ZScalarType::ZSCALAR_U32:
case ZScalarType::ZSCALAR_X32:
writer->Write(vec->scalars[k].scalarData.u32);
break;
case ZScalarType::ZSCALAR_S64:
writer->Write(vec->scalars[k].scalarData.s64);
break;
case ZScalarType::ZSCALAR_U64:
case ZScalarType::ZSCALAR_X64:
writer->Write(vec->scalars[k].scalarData.u64);
break;
// OTRTODO: ADD OTHER TYPES
default:
break;
}
}
}
else
{
ZScalar* scal = (ZScalar*)arr->resList[i];
writer->Write((uint32_t)scal->scalarType);
switch (scal->scalarType)
{
case ZScalarType::ZSCALAR_S8:
writer->Write(scal->scalarData.s8);
break;
case ZScalarType::ZSCALAR_U8:
case ZScalarType::ZSCALAR_X8:
writer->Write(scal->scalarData.u8);
break;
case ZScalarType::ZSCALAR_S16:
writer->Write(scal->scalarData.s16);
break;
case ZScalarType::ZSCALAR_U16:
case ZScalarType::ZSCALAR_X16:
writer->Write(scal->scalarData.u16);
break;
case ZScalarType::ZSCALAR_S32:
writer->Write(scal->scalarData.s32);
break;
case ZScalarType::ZSCALAR_U32:
case ZScalarType::ZSCALAR_X32:
writer->Write(scal->scalarData.u32);
break;
case ZScalarType::ZSCALAR_S64:
writer->Write(scal->scalarData.s64);
break;
case ZScalarType::ZSCALAR_U64:
case ZScalarType::ZSCALAR_X64:
writer->Write(scal->scalarData.u64);
break;
// OTRTODO: ADD OTHER TYPES
default:
break;
}
}
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "ZResource.h"
#include "ZArray.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Array : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,483 @@
#include "AudioExporter.h"
#include "Main.h"
#include <Utils/MemoryStream.h>
#include <Globals.h>
#include <Utils/DiskFile.h>
#include "DisplayListExporter.h"
const char* OTRExporter_Audio::GetMediumStr(uint8_t medium) {
switch (medium) {
case 0:
return "Ram";
case 1:
return "Unk";
case 2:
return "Cart";
case 3:
return "Disk";
case 5:
return "RamUnloaded";
default:
return "ERROR";
}
}
const char* OTRExporter_Audio::GetCachePolicyStr(uint8_t policy) {
switch (policy) {
case 0:
return "Temporary";
case 1:
return "Persistent";
case 2:
return "Either";
case 3:
return "Permanent";
default:
return "ERROR";
}
}
const char* OTRExporter_Audio::GetCodecStr(uint8_t codec) {
switch (codec) {
case 0:
return "ADPCM";
case 1:
return "S8";
case 2:
return "S16MEM";
case 3:
return "ADPCMSMALL";
case 4:
return "REVERB";
case 5:
return "S16";
case 6:
return "UNK6";
case 7:
return "UNK7";
default:
return "ERROR";
}
}
std::string OTRExporter_Audio::GetSampleEntryReference(ZAudio* audio, SampleEntry* entry)
{
if (entry != nullptr)
{
if (audio->sampleOffsets[entry->bankId].contains(entry->sampleDataOffset) &&
audio->sampleOffsets[entry->bankId][entry->sampleDataOffset] != "") {
return (StringHelper::Sprintf("audio/samples/%s_META",
audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str()));
}
else
return StringHelper::Sprintf("audio/samples/sample_%d_%08X_META", entry->bankId, entry->sampleDataOffset);
}
else
return("");
}
void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer)
{
WriteHeader(nullptr, "", writer, static_cast<uint32_t>(SOH::ResourceType::SOH_AudioSample), 2);
writer->Write(entry->codec);
writer->Write(entry->medium);
writer->Write(entry->unk_bit26);
writer->Write(entry->unk_bit25);
writer->Write((uint32_t)entry->data.size());
writer->Write((char*)entry->data.data(), entry->data.size());
writer->Write((uint32_t)(entry->loop.start));
writer->Write((uint32_t)(entry->loop.end));
writer->Write((uint32_t)(entry->loop.count));
writer->Write((uint32_t)entry->loop.states.size());
for (size_t i = 0; i < entry->loop.states.size(); i++)
writer->Write((entry->loop.states[i]));
writer->Write((uint32_t)(entry->book.order));
writer->Write((uint32_t)(entry->book.npredictors));
writer->Write((uint32_t)entry->book.books.size());
for (size_t i = 0; i < entry->book.books.size(); i++)
writer->Write((entry->book.books[i]));
}
void OTRExporter_Audio::WriteSampleEntry(SampleEntry* entry, tinyxml2::XMLElement* xmlDoc) {
tinyxml2::XMLElement* sEntry = xmlDoc;
sEntry->SetAttribute("Codec", GetCodecStr(entry->codec));
sEntry->SetAttribute("Medium", GetMediumStr(entry->medium));
sEntry->SetAttribute("bit26", entry->unk_bit26);
sEntry->SetAttribute("Relocated", entry->unk_bit25);
tinyxml2::XMLElement* loopRoot = sEntry->InsertNewChildElement("ADPCMLoop");
loopRoot->SetAttribute("Start", entry->loop.start);
loopRoot->SetAttribute("End", entry->loop.end);
loopRoot->SetAttribute("Count", (int)entry->loop.count); // Cast to int to -1 shows as -1.
for (size_t i = 0; i < entry->loop.states.size(); i++) {
tinyxml2::XMLElement* loop = loopRoot->InsertNewChildElement("Predictor");
loop->SetAttribute("State", entry->loop.states[i]);
loopRoot->InsertEndChild(loop);
}
sEntry->InsertEndChild(loopRoot);
tinyxml2::XMLElement* bookRoot = sEntry->InsertNewChildElement("ADPCMBook");
bookRoot->SetAttribute("Order", entry->book.order);
bookRoot->SetAttribute("Npredictors", entry->book.npredictors);
for (size_t i = 0; i < entry->book.books.size(); i++) {
tinyxml2::XMLElement* book = bookRoot->InsertNewChildElement("Book");
book->SetAttribute("Page", entry->book.books[i]);
bookRoot->InsertEndChild(book);
}
sEntry->InsertEndChild(bookRoot);
}
void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, BinaryWriter* writer)
{
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
if (entry != nullptr)
{
// This second byte isn't used but is needed to maintain compatibility with the V2 format.
writer->Write((uint8_t)(entry != nullptr ? 1 : 0));
writer->Write(GetSampleEntryReference(audio, entry->sampleEntry));
writer->Write(entry->tuning);
}
}
void OTRExporter_Audio::WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, tinyxml2::XMLElement* xmlDoc,
const char* name) {
tinyxml2::XMLElement* sfEntry = xmlDoc->InsertNewChildElement(name);
if (entry != nullptr)
{
sfEntry->SetAttribute("SampleRef", GetSampleEntryReference(audio, entry->sampleEntry).c_str());
sfEntry->SetAttribute("Tuning", entry->tuning);
}
xmlDoc->InsertEndChild(sfEntry);
}
void OTRExporter_Audio::WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer)
{
writer->Write((uint32_t)envelopes.size());
for (auto env : envelopes)
{
writer->Write(env->delay);
writer->Write(env->arg);
}
}
void OTRExporter_Audio::WriteEnvData(std::vector<AdsrEnvelope*> envelopes, tinyxml2::XMLElement* xmlDoc) {
tinyxml2::XMLElement* envs = xmlDoc->InsertNewChildElement("Envelopes");
envs->SetAttribute("Count", (uint32_t)envelopes.size());
for (auto e : envelopes) {
tinyxml2::XMLElement* env = envs->InsertNewChildElement("Envelope");
env->SetAttribute("Delay", e->delay);
env->SetAttribute("Arg", e->arg);
}
xmlDoc->InsertEndChild(envs);
}
void OTRExporter_Audio::WriteSoundFontTableXML(ZAudio* audio) {
for (size_t i = 0; i < audio->soundFontTable.size(); i++) {
tinyxml2::XMLDocument soundFont;
tinyxml2::XMLElement* root = soundFont.NewElement("SoundFont");
root->SetAttribute("Version", 0);
root->SetAttribute("Num", (uint32_t)i);
root->SetAttribute("Medium", GetMediumStr(audio->soundFontTable[i].medium));
root->SetAttribute("CachePolicy", GetCachePolicyStr(audio->soundFontTable[i].cachePolicy));
root->SetAttribute("Data1", audio->soundFontTable[i].data1);
root->SetAttribute("Data2", audio->soundFontTable[i].data2);
root->SetAttribute("Data3", audio->soundFontTable[i].data3);
soundFont.InsertFirstChild(root);
tinyxml2::XMLElement* drums = root->InsertNewChildElement("Drums");
drums->SetAttribute("Count", (uint32_t)audio->soundFontTable[i].drums.size());
for (const auto& d : audio->soundFontTable[i].drums) {
tinyxml2::XMLElement* drum = drums->InsertNewChildElement("Drum");
drum->SetAttribute("ReleaseRate", d.releaseRate);
drum->SetAttribute("Pan", d.pan);
drum->SetAttribute("Loaded", d.loaded);
drum->SetAttribute("SampleRef", GetSampleEntryReference(audio, d.sample).c_str());
drum->SetAttribute("Tuning", d.tuning);
WriteEnvData(d.env, drum);
drums->InsertEndChild(drum);
}
root->InsertEndChild(drums);
tinyxml2::XMLElement* instruments = root->InsertNewChildElement("Instruments");
instruments->SetAttribute("Count", (uint32_t)audio->soundFontTable[i].instruments.size());
//for (size_t k = 0; k < audio->soundFontTable[i].instruments.size(); k++) {
for (const auto i : audio->soundFontTable[i].instruments) {
tinyxml2::XMLElement* instrument = instruments->InsertNewChildElement("Instrument");
instrument->SetAttribute("IsValid", i.isValidInstrument);
instrument->SetAttribute("Loaded", i.loaded);
instrument->SetAttribute("NormalRangeLo", i.normalRangeLo);
instrument->SetAttribute("NormalRangeHi", i.normalRangeHi);
instrument->SetAttribute("ReleaseRate", i.releaseRate);
WriteEnvData(i.env, instrument);
WriteSoundFontEntry(audio, i.lowNotesSound, instrument, "LowNotesSound");
WriteSoundFontEntry(audio, i.normalNotesSound, instrument, "NormalNotesSound");
WriteSoundFontEntry(audio, i.highNotesSound, instrument, "HighNotesSound");
}
root->InsertEndChild(instruments);
tinyxml2::XMLElement* sfxTbl = root->InsertNewChildElement("SfxTable");
sfxTbl->SetAttribute("Count", (uint32_t)audio->soundFontTable[i].soundEffects.size());
for (const auto s : audio->soundFontTable[i].soundEffects) {
WriteSoundFontEntry(audio, s, sfxTbl, "Sfx");
}
root->InsertEndChild(sfxTbl);
soundFont.InsertEndChild(root);
tinyxml2::XMLPrinter printer;
soundFont.Accept(&printer);
std::string fName = OTRExporter_DisplayList::GetPathToRes(
(ZResource*)(audio), StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str()));
std::vector<char> xmlData((printer.CStr()), printer.CStr() + printer.CStrSize() - 1);
AddFile(fName, xmlData);
}
}
void OTRExporter_Audio::WriteSoundFontTableBinary(ZAudio* audio) {
for (size_t i = 0; i < audio->soundFontTable.size(); i++) {
MemoryStream* fntStream = new MemoryStream();
BinaryWriter fntWriter = BinaryWriter(fntStream);
WriteHeader(nullptr, "", &fntWriter, static_cast<uint32_t>(SOH::ResourceType::SOH_AudioSoundFont), 2);
fntWriter.Write((uint32_t)i);
fntWriter.Write(audio->soundFontTable[i].medium);
fntWriter.Write(audio->soundFontTable[i].cachePolicy);
fntWriter.Write(audio->soundFontTable[i].data1);
fntWriter.Write(audio->soundFontTable[i].data2);
fntWriter.Write(audio->soundFontTable[i].data3);
fntWriter.Write((uint32_t)audio->soundFontTable[i].drums.size());
fntWriter.Write((uint32_t)audio->soundFontTable[i].instruments.size());
fntWriter.Write((uint32_t)audio->soundFontTable[i].soundEffects.size());
for (size_t k = 0; k < audio->soundFontTable[i].drums.size(); k++) {
fntWriter.Write(audio->soundFontTable[i].drums[k].releaseRate);
fntWriter.Write(audio->soundFontTable[i].drums[k].pan);
fntWriter.Write(audio->soundFontTable[i].drums[k].loaded);
WriteEnvData(audio->soundFontTable[i].drums[k].env, &fntWriter);
fntWriter.Write((uint8_t)(audio->soundFontTable[i].drums[k].sample != nullptr ? 1 : 0));
fntWriter.Write(GetSampleEntryReference(audio, audio->soundFontTable[i].drums[k].sample));
fntWriter.Write(audio->soundFontTable[i].drums[k].tuning);
}
for (size_t k = 0; k < audio->soundFontTable[i].instruments.size(); k++) {
fntWriter.Write((uint8_t)audio->soundFontTable[i].instruments[k].isValidInstrument);
fntWriter.Write(audio->soundFontTable[i].instruments[k].loaded);
fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeLo);
fntWriter.Write(audio->soundFontTable[i].instruments[k].normalRangeHi);
fntWriter.Write(audio->soundFontTable[i].instruments[k].releaseRate);
WriteEnvData(audio->soundFontTable[i].instruments[k].env, &fntWriter);
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].lowNotesSound, &fntWriter);
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].normalNotesSound, &fntWriter);
WriteSoundFontEntry(audio, audio->soundFontTable[i].instruments[k].highNotesSound, &fntWriter);
}
for (size_t k = 0; k < audio->soundFontTable[i].soundEffects.size(); k++) {
WriteSoundFontEntry(audio, audio->soundFontTable[i].soundEffects[k], &fntWriter);
}
std::string fName = OTRExporter_DisplayList::GetPathToRes(
(ZResource*)(audio), StringHelper::Sprintf("fonts/%s", audio->soundFontNames[i].c_str()));
AddFile(fName, fntStream->ToVector());
}
}
void OTRExporter_Audio::WriteSequenceXML(ZAudio* audio) {
for (size_t i = 0; i < audio->sequences.size(); i++) {
MemoryStream* seqStream = new MemoryStream();
BinaryWriter seqWriter = BinaryWriter(seqStream);
auto& seq = audio->sequences[i];
tinyxml2::XMLDocument sequence;
tinyxml2::XMLElement* root = sequence.NewElement("Sequence");
root->SetAttribute("Index", (uint32_t)i);
root->SetAttribute("Medium", GetMediumStr(audio->sequenceTable[i].medium));
root->SetAttribute("CachePolicy", GetCachePolicyStr(audio->sequenceTable[i].cachePolicy));
root->SetAttribute("Size", (uint32_t)seq.size());
std::string seqName = OTRExporter_DisplayList::GetPathToRes(
(ZResource*)(audio), StringHelper::Sprintf("sequencedata/%s_RAW", audio->seqNames[i].c_str()));
root->SetAttribute("Path", seqName.c_str());
tinyxml2::XMLElement* fontIndicies = root->InsertNewChildElement("FontIndicies");
for (size_t k = 0; k < audio->fontIndices[i].size(); k++) {
tinyxml2::XMLElement* fontIndex = fontIndicies->InsertNewChildElement("FontIndex");
fontIndex->SetAttribute("FontIdx", audio->fontIndices[i][k]);
}
root->InsertEndChild(fontIndicies);
root->InsertEndChild(root);
sequence.InsertEndChild(root);
seqWriter.Write(seq.data(), seq.size());
AddFile(seqName, seqStream->ToVector());
tinyxml2::XMLPrinter printer;
sequence.Accept(&printer);
std::string seqMetaName = OTRExporter_DisplayList::GetPathToRes(
(ZResource*)(audio), StringHelper::Sprintf("sequences/%s_META", audio->seqNames[i].c_str()));
std::vector<char> xmlData((printer.CStr()), printer.CStr() + printer.CStrSize() - 1);
AddFile(seqMetaName, xmlData);
}
}
void OTRExporter_Audio::WriteSequenceBinary(ZAudio* audio) {
for (size_t i = 0; i < audio->sequences.size(); i++) {
auto& seq = audio->sequences[i];
MemoryStream* seqStream = new MemoryStream();
BinaryWriter seqWriter = BinaryWriter(seqStream);
WriteHeader(nullptr, "", &seqWriter, static_cast<uint32_t>(SOH::ResourceType::SOH_AudioSequence), 2);
seqWriter.Write((uint32_t)seq.size());
seqWriter.Write(seq.data(), seq.size());
seqWriter.Write((uint8_t)i);
seqWriter.Write((uint8_t)audio->sequenceTable[i].medium);
seqWriter.Write((uint8_t)audio->sequenceTable[i].cachePolicy);
seqWriter.Write((uint32_t)audio->fontIndices[i].size());
for (size_t k = 0; k < audio->fontIndices[i].size(); k++)
seqWriter.Write((uint8_t)audio->fontIndices[i][k]);
std::string fName = OTRExporter_DisplayList::GetPathToRes(
(ZResource*)(audio), StringHelper::Sprintf("sequences/%s", audio->seqNames[i].c_str()));
AddFile(fName, seqStream->ToVector());
}
}
std::string OTRExporter_Audio::GetSampleEntryStr(ZAudio* audio, SampleEntry* entry) {
std::string basePath = "";
if (audio->sampleOffsets[entry->bankId].contains(entry->sampleDataOffset) &&
audio->sampleOffsets[entry->bankId][entry->sampleDataOffset] != "") {
basePath = StringHelper::Sprintf(
"samples/%s", audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str());
} else
basePath = StringHelper::Sprintf("samples/sample_%d_%08X", entry->bankId, entry->sampleDataOffset);
return basePath;
}
std::string OTRExporter_Audio::GetSampleDataStr(ZAudio* audio, SampleEntry* entry) {
std::string basePath = "";
if (audio->sampleOffsets[entry->bankId].contains(entry->sampleDataOffset) &&
audio->sampleOffsets[entry->bankId][entry->sampleDataOffset] != "") {
basePath = StringHelper::Sprintf(
"samples/%s_RAW",
audio->sampleOffsets[entry->bankId][entry->sampleDataOffset].c_str());
} else
basePath = StringHelper::Sprintf("samples/sample_%d_%08X_RAW", entry->bankId, entry->sampleDataOffset);
return basePath;
}
void OTRExporter_Audio::WriteSampleBinary(ZAudio* audio) {
ZResource* res = audio;
for (const auto& pair : audio->samples) {
MemoryStream* sampleStream = new MemoryStream();
BinaryWriter sampleWriter = BinaryWriter(sampleStream);
WriteSampleEntry(pair.second, &sampleWriter);
std::string basePath = GetSampleEntryStr(audio, pair.second);
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath);
fName += "_META";
AddFile(fName, sampleStream->ToVector());
}
}
void OTRExporter_Audio::WriteSampleXML(ZAudio* audio) {
ZResource* res = audio;
for (const auto& pair : audio->samples) {
tinyxml2::XMLDocument sample;
tinyxml2::XMLElement* root = sample.NewElement("Sample");
root->SetAttribute("Version", 0);
WriteSampleEntry(pair.second, root);
// There is no overload for size_t. MSVC and GCC are fine with `size` being cast
// to size_t and passed in, but apple clang is not.
root->SetAttribute("Size", (uint64_t)pair.second->data.size());
sample.InsertEndChild(root);
std::string sampleDataPath = GetSampleDataStr(audio, pair.second);
sampleDataPath = OTRExporter_DisplayList::GetPathToRes(res, sampleDataPath);
root->SetAttribute("Path", sampleDataPath.c_str());
std::string basePath = GetSampleEntryStr(audio, pair.second);
std::string fName = OTRExporter_DisplayList::GetPathToRes(res, basePath);
fName += "_META";
tinyxml2::XMLPrinter printer;
sample.Accept(&printer);
std::vector<char> xmlData((printer.CStr()), printer.CStr() + printer.CStrSize() - 1);
AddFile(fName, xmlData);
MemoryStream* stream = new MemoryStream();
BinaryWriter sampleDataWriter = BinaryWriter(stream);
sampleDataWriter.Write((char*)pair.second->data.data(), pair.second->data.size());
AddFile(sampleDataPath, stream->ToVector());
}
}
void OTRExporter_Audio::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZAudio* audio = (ZAudio*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Audio), 2);
// Write Samples as individual files
if (Globals::Instance->xmlExtractModes & (1 << (int)XMLModeShift::Sample))
WriteSampleXML(audio);
else
WriteSampleBinary(audio);
// Write the soundfont table
if (Globals::Instance->xmlExtractModes & (1 << (int)XMLModeShift::SoundFont))
WriteSoundFontTableXML(audio);
else
WriteSoundFontTableBinary(audio);
// Write Sequences
if (Globals::Instance->xmlExtractModes & (1 << (int)XMLModeShift::Sequence))
WriteSequenceXML(audio);
else
WriteSequenceBinary(audio);
}

View File

@@ -0,0 +1,33 @@
#pragma once
#include "ZResource.h"
#include "ZAudio.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
#include <tinyxml2.h>
class OTRExporter_Audio : public OTRExporter
{
public:
void WriteSampleEntry(SampleEntry* entry, BinaryWriter* writer);
void WriteSampleEntry(SampleEntry* entry, tinyxml2::XMLElement* writer);
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
private:
void WriteSoundFontTableBinary(ZAudio* audio);
void WriteSoundFontTableXML(ZAudio* audio);
void WriteSequenceBinary(ZAudio* audio);
void WriteSequenceXML(ZAudio* audio);
void WriteSampleBinary(ZAudio* audio);
void WriteSampleXML(ZAudio* audio);
std::string GetSampleEntryReference(ZAudio* audio, SampleEntry* entry);
std::string GetSampleEntryStr(ZAudio* audio, SampleEntry* entry);
std::string GetSampleDataStr(ZAudio* audio, SampleEntry* entry);
void WriteEnvData(std::vector<AdsrEnvelope*> envelopes, BinaryWriter* writer);
void WriteEnvData(std::vector<AdsrEnvelope*> envelopes, tinyxml2::XMLElement* xmlDoc);
void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, BinaryWriter* writer);
void WriteSoundFontEntry(ZAudio* audio, SoundFontEntry* entry, tinyxml2::XMLElement* xmlDoc, const char* name);
const char* GetMediumStr(uint8_t medium);
const char* GetCachePolicyStr(uint8_t policy);
const char* GetCodecStr(uint8_t codec);
};

View File

@@ -0,0 +1,14 @@
#include "BackgroundExporter.h"
#include "../ZAPD/ZFile.h"
void OTRExporter_Background::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZBackground* bg = (ZBackground*)res;
WriteHeader(bg, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Background));
writer->Write((uint32_t)bg->GetRawDataSize());
auto data = bg->parent->GetRawData();
writer->Write((char*)data.data() + bg->GetRawDataIndex(), bg->GetRawDataSize());
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "ZResource.h"
#include "ZBackground.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Background : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,21 @@
#include "BlobExporter.h"
#include "../ZAPD/ZFile.h"
void OTRExporter_Blob::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZBlob* blob = (ZBlob*)res;
WriteHeader(blob, outPath, writer, static_cast<uint32_t>(Ship::ResourceType::Blob));
auto start = std::chrono::steady_clock::now();
writer->Write((uint32_t)blob->GetRawDataSize());
auto data = blob->parent->GetRawData();
for (size_t i = blob->GetRawDataIndex(); i < blob->GetRawDataIndex() + blob->GetRawDataSize(); i++)
writer->Write(data[i]);
auto end = std::chrono::steady_clock::now();
size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "ZResource.h"
#include "ZBlob.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Blob : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,105 @@
#ifdef GAME_MM
#include "CKeyFrameExporter.h"
#include "DisplayListExporter.h"
#include "Globals.h"
#include "spdlog/spdlog.h"
// The Win32 API defines this function for its own uses.
#ifdef FindResource
#undef FindResource
#endif
void OTRExporter_CKeyFrameSkel::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) {
ZKeyFrameSkel* skel = (ZKeyFrameSkel*)res;
ZKeyFrameLimbList* list = skel->limbList.get();
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::TSH_CKeyFrameSkel));
writer->Write(skel->limbCount);
writer->Write(skel->dListCount);
writer->Write((uint8_t)skel->limbType);
writer->Write(list->numLimbs);
for (size_t i = 0; i < list->limbs.size(); i++) {
ZKeyFrameLimb* limb = list->limbs[i];
std::string name = "";
if (GETSEGOFFSET(limb->dlist) != SEGMENTED_NULL) {
bool found = Globals::Instance->GetSegmentedPtrName(GETSEGOFFSET(limb->dlist), res->parent, "", name,
res->parent->workerID);
if (!found) {
ZDisplayList* dl = (ZDisplayList*)res->parent->FindResource(limb->dlist & 0x00FFFFFF);
if (dl != nullptr) {
name = dl->GetName();
found = true;
}
}
if (found) {
if (name.at(0) == '&')
name.erase(0, 1);
name = OTRExporter_DisplayList::GetPathToRes(res, name);
} else {
spdlog::error("Texture not found: 0x{:X}", limb->dlist);
//writer->Write("");
name = "";
}
}
writer->Write(name);
writer->Write(limb->numChildren);
writer->Write(limb->flags);
if (skel->limbType == ZKeyframeSkelType::Normal) {
ZKeyFrameStandardLimb* stdLimb = (ZKeyFrameStandardLimb*)limb;
writer->Write(stdLimb->translation.x);
writer->Write(stdLimb->translation.y);
writer->Write(stdLimb->translation.z);
} else {
ZKeyFrameFlexLimb* flexLimb = (ZKeyFrameFlexLimb*)limb;
writer->Write(flexLimb->callbackIndex);
}
}
}
void OTRExporter_CKeyFrameAnim::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) {
ZKeyFrameAnim* anim = (ZKeyFrameAnim*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::TSH_CKeyFrameAnim));
writer->Write((uint8_t)anim->skel->limbType);
if (anim->skel->limbType == ZKeyframeSkelType::Normal) {
writer->Write((uint32_t)anim->bitFlags.size());
for (const auto b : anim->bitFlags) {
writer->Write(b);
}
} else {
writer->Write((uint32_t)anim->bitFlagsFlex.size());
for (const auto b : anim->bitFlagsFlex) {
writer->Write(b);
}
}
writer->Write((uint32_t)anim->keyFrames.size());
for (const auto k : anim->keyFrames) {
writer->Write(k.frame);
writer->Write(k.value);
writer->Write(k.velocity);
}
writer->Write((uint32_t)anim->kfNums.size());
for (const auto kf : anim->kfNums) {
writer->Write(kf);
}
writer->Write((uint32_t)anim->presetValues.size());
for (const auto pv : anim->presetValues) {
writer->Write(pv);
}
writer->Write(anim->unk_10);
writer->Write(anim->duration);
}
#endif

View File

@@ -0,0 +1,19 @@
#pragma once
#ifdef GAME_MM
#include "ZResource.h"
#include "ZCKeyFrame.h"
#include "ZCkeyFrameAnim.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_CKeyFrameSkel : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};
class OTRExporter_CKeyFrameAnim : public OTRExporter {
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};
#endif

View File

@@ -0,0 +1,213 @@
set(PROJECT_NAME OTRExporter)
################################################################################
# Source groups
################################################################################
set(Header_Files
"AnimationExporter.h"
"ArrayExporter.h"
"AudioExporter.h"
"BackgroundExporter.h"
"BlobExporter.h"
"CKeyFrameExporter.h"
"CollisionExporter.h"
"command_macros_base.h"
"CutsceneExporter.h"
"DisplayListExporter.h"
"Exporter.h"
"ExporterArchive.h"
"ExporterArchiveO2R.h"
"ExporterArchiveOTR.h"
"Main.h"
"MtxExporter.h"
"PathExporter.h"
"PlayerAnimationExporter.h"
"RoomExporter.h"
"SkeletonExporter.h"
"SkeletonLimbExporter.h"
"TextExporter.h"
"TextMMExporter.h"
"TextureExporter.h"
"TextureAnimationExporter.h"
"VersionInfo.h"
"VtxExporter.h"
"z64cutscene.h"
"z64cutscene_commands.h"
)
source_group("Header Files" FILES ${Header_Files})
set(Source_Files
"AnimationExporter.cpp"
"ArrayExporter.cpp"
"AudioExporter.cpp"
"BackgroundExporter.cpp"
"BlobExporter.cpp"
"CollisionExporter.cpp"
"CKeyFrameExporter.cpp"
"CutsceneExporter.cpp"
"DisplayListExporter.cpp"
"Exporter.cpp"
"ExporterArchive.cpp"
"ExporterArchiveO2R.cpp"
"ExporterArchiveOTR.cpp"
"Main.cpp"
"MtxExporter.cpp"
"PathExporter.cpp"
"PlayerAnimationExporter.cpp"
"RoomExporter.cpp"
"SkeletonExporter.cpp"
"SkeletonLimbExporter.cpp"
"TextExporter.cpp"
"TextMMExporter.cpp"
"TextureExporter.cpp"
"TextureAnimationExporter.cpp"
"VersionInfo.cpp"
"VtxExporter.cpp"
)
source_group("Source Files" FILES ${Source_Files})
set(ALL_FILES
${Header_Files}
${Source_Files}
)
################################################################################
# Target
################################################################################
add_library(${PROJECT_NAME} STATIC ${ALL_FILES})
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
endif()
set(ROOT_NAMESPACE OTRExporter)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set_target_properties(${PROJECT_NAME} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
)
endif()
################################################################################
# MSVC runtime library
################################################################################
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
$<$<CONFIG:Debug>:
MultiThreadedDebug
>
$<$<CONFIG:Release>:
MultiThreaded
>
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
)
set_target_properties(${PROJECT_NAME} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
endif()
################################################################################
# Compile definitions
################################################################################
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
target_compile_definitions(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Debug>:"
"_DEBUG"
">"
"$<$<CONFIG:Release>:"
"NDEBUG"
">"
"_CONSOLE;"
"_CRT_SECURE_NO_WARNINGS;"
STORMLIB_NO_AUTO_LINK
)
endif()
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
target_compile_definitions(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Debug>:"
"_DEBUG"
">"
"$<$<CONFIG:Release>:"
"NDEBUG"
">"
"_CONSOLE;"
"_CRT_SECURE_NO_WARNINGS;"
)
endif()
################################################################################
# Compile and link options
################################################################################
target_include_directories(${PROJECT_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/ZAPD/
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/include
# TODO: these should no longer be necessary if we were to link against LUS
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/src
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/extern
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/src/resource
${CMAKE_CURRENT_SOURCE_DIR}/../../mm/2s2h
.
)
find_package(nlohmann_json REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC nlohmann_json::nlohmann_json)
find_package(spdlog REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC spdlog::spdlog)
FetchContent_Declare(
StormLib
GIT_REPOSITORY https://github.com/ladislav-zezula/StormLib.git
GIT_TAG v9.25
)
FetchContent_MakeAvailable(StormLib)
target_include_directories(${PROJECT_NAME} PRIVATE ${stormlib_SOURCE_DIR}/src)
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Debug>:
/Od;
/Oi-
>
$<$<CONFIG:Release>:
/Oi;
/Gy
/O2
>
/permissive-;
/sdl;
/W3;
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
${DEFAULT_CXX_EXCEPTION_HANDLING}
)
target_link_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Release>:
/OPT:REF;
/OPT:ICF
/INCREMENTAL:NO
>
/SUBSYSTEM:CONSOLE
)
endif()
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
target_compile_options(${PROJECT_NAME} PRIVATE
-Wall -Wextra -Wno-error
-Wno-unused-parameter
-Wno-unused-function
-Wno-unused-variable
-Wno-missing-field-initializers
-Wno-parentheses
-Wno-narrowing
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>
)
endif()
################################################################################
# Dependencies
################################################################################
add_dependencies(${PROJECT_NAME}
libultraship
)
# Link with other targets.
target_link_libraries(${PROJECT_NAME} PUBLIC "${ADDITIONAL_LIBRARY_DEPENDENCIES}")

View File

@@ -0,0 +1,84 @@
#include "CollisionExporter.h"
#include <libultraship/bridge.h>
void OTRExporter_Collision::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZCollisionHeader* col = (ZCollisionHeader*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_CollisionHeader));
writer->Write(col->absMinX);
writer->Write(col->absMinY);
writer->Write(col->absMinZ);
writer->Write(col->absMaxX);
writer->Write(col->absMaxY);
writer->Write(col->absMaxZ);
writer->Write((uint32_t)col->vertices.size());
for (uint16_t i = 0; i < col->vertices.size(); i++)
{
writer->Write(col->vertices[i].scalars[0].scalarData.s16);
writer->Write(col->vertices[i].scalars[1].scalarData.s16);
writer->Write(col->vertices[i].scalars[2].scalarData.s16);
}
writer->Write((uint32_t)col->polygons.size());
for (uint16_t i = 0; i < col->polygons.size(); i++)
{
writer->Write(col->polygons[i].type);
writer->Write(col->polygons[i].vtxA);
writer->Write(col->polygons[i].vtxB);
writer->Write(col->polygons[i].vtxC);
writer->Write(col->polygons[i].normX);
writer->Write(col->polygons[i].normY);
writer->Write(col->polygons[i].normZ);
writer->Write(col->polygons[i].dist);
}
writer->Write((uint32_t)col->polygonTypes.size());
for (uint16_t i = 0; i < col->polygonTypes.size(); i++) {
writer->Write(col->polygonTypes[i].data[1]);
writer->Write(col->polygonTypes[i].data[0]);
}
writer->Write((uint32_t)col->camData->entries.size());
for (auto entry : col->camData->entries)
{
auto camPosDecl = col->parent->GetDeclarationRanged(Seg2Filespace(entry.cameraPosDataSeg, col->parent->baseAddress));
int idx = 0;
if (camPosDecl != nullptr)
idx = ((entry.cameraPosDataSeg & 0x00FFFFFF) - camPosDecl->address) / 6;
writer->Write(entry.cameraSType);
writer->Write(entry.numData);
writer->Write((uint32_t)idx);
}
writer->Write((uint32_t)col->camData->cameraPositionData.size());
for (auto entry : col->camData->cameraPositionData)
{
writer->Write(entry.x);
writer->Write(entry.y);
writer->Write(entry.z);
}
writer->Write((uint32_t)col->waterBoxes.size());
for (auto waterBox : col->waterBoxes)
{
writer->Write(waterBox.xMin);
writer->Write(waterBox.ySurface);
writer->Write(waterBox.zMin);
writer->Write(waterBox.xLength);
writer->Write(waterBox.zLength);
writer->Write(waterBox.properties);
}
}

View File

@@ -0,0 +1,11 @@
#pragma once
#include "ZResource.h"
#include "ZCollision.h"
#include "Exporter.h"
class OTRExporter_Collision : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,606 @@
#include "CutsceneExporter.h"
#include "Globals.h"
#include <libultraship/bridge.h>
void OTRExporter_Cutscene::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) {
ZCutscene* cs = (ZCutscene*)res;
WriteHeader(cs, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Cutscene));
writer->Write((uint32_t)0);
const auto currentStream = writer->GetBaseAddress();
writer->Write(CS_BEGIN_CUTSCENE(cs->numCommands, cs->endFrame));
if (Globals::Instance->game == ZGame::MM_RETAIL) {
SaveMM(cs, writer);
} else {
SaveOot(cs, writer);
}
// CS_END
writer->Write(0xFFFFFFFF);
writer->Write((uint32_t)0);
const auto endStream = writer->GetBaseAddress();
writer->Seek((uint32_t)currentStream - 4, SeekOffsetType::Start);
writer->Write((uint32_t)((endStream - currentStream) / 4));
writer->Seek((uint32_t)endStream, SeekOffsetType::Start);
}
void OTRExporter_Cutscene::SaveOot(ZCutscene* cs, BinaryWriter* writer) {
for (size_t i = 0; i < cs->commands.size(); i++) {
switch (cs->commands[i]->commandID) {
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_EYE_SPLINE: {
CutsceneOoTCommand_GenericCameraCmd* cmdCamPos = (CutsceneOoTCommand_GenericCameraCmd*)cs->commands[i];
writer->Write(CS_CMD_CAM_EYE);
writer->Write(CMD_HH(0x0001, ((CutsceneOoTCommand_GenericCameraCmd*)cs->commands[i])->startFrame));
writer->Write(CMD_HH(cmdCamPos->endFrame, 0x0000));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTCommand_CameraPoint* point = (CutsceneOoTCommand_CameraPoint*)e;
writer->Write(CMD_BBH(point->continueFlag, point->cameraRoll, point->nextPointFrame));
writer->Write(point->viewAngle);
writer->Write(CMD_HH(point->posX, point->posY));
writer->Write(CMD_HH(point->posZ, point->unused));
}
} break;
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_AT_SPLINE: {
CutsceneOoTCommand_GenericCameraCmd* cmdCamPos = (CutsceneOoTCommand_GenericCameraCmd*)cs->commands[i];
writer->Write(CS_CMD_CAM_AT);
writer->Write(CMD_HH(0x0001, cmdCamPos->startFrame));
writer->Write(CMD_HH(cmdCamPos->endFrame, 0x0000));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTCommand_CameraPoint* point = (CutsceneOoTCommand_CameraPoint*)e;
writer->Write(CMD_BBH(point->continueFlag, point->cameraRoll, point->nextPointFrame));
writer->Write(point->viewAngle);
writer->Write(CMD_HH(point->posX, point->posY));
writer->Write(CMD_HH(point->posZ, point->unused));
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_MISC: {
writer->Write(CS_CMD_MISC);
writer->Write((uint32_t)CMD_W((cs->commands[i])->entries.size()));
for (const auto& e : cs->commands[i]->entries) // All in OOT seem to only have 1 entry
{
CutsceneOoTSubCommandEntry_GenericCmd* cmd = (CutsceneOoTSubCommandEntry_GenericCmd*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HH(cmd->endFrame, cmd->pad));
writer->Write(CMD_W(cmd->unused1));
writer->Write(CMD_W(cmd->unused2));
writer->Write(CMD_W(cmd->unused3));
writer->Write(CMD_W(cmd->unused4));
writer->Write(CMD_W(cmd->unused5));
writer->Write(CMD_W(cmd->unused6));
writer->Write(CMD_W(cmd->unused7));
writer->Write(CMD_W(cmd->unused8));
writer->Write(CMD_W(cmd->unused9));
writer->Write(CMD_W(cmd->unused10));
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_LIGHT_SETTING: {
writer->Write(CS_CMD_SET_LIGHTING);
writer->Write((uint32_t)CMD_W((cs->commands[i])->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTSubCommandEntry_GenericCmd* cmd = (CutsceneOoTSubCommandEntry_GenericCmd*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HH(cmd->endFrame, cmd->pad));
writer->Write(CMD_W(cmd->unused1));
writer->Write(CMD_W(cmd->unused2));
writer->Write(CMD_W(cmd->unused3));
writer->Write(CMD_W(cmd->unused4));
writer->Write(CMD_W(cmd->unused5));
writer->Write(CMD_W(cmd->unused6));
writer->Write(CMD_W(cmd->unused7));
writer->Write((uint32_t)0x0);
writer->Write((uint32_t)0x0);
writer->Write((uint32_t)0x0);
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_EYE_SPLINE_REL_TO_PLAYER: {
CutsceneOoTCommand_GenericCameraCmd* cmdCamPos = (CutsceneOoTCommand_GenericCameraCmd*)cs->commands[i];
writer->Write(CS_CMD_CAM_EYE_REL_TO_PLAYER);
writer->Write(CMD_HH(0x0001, cmdCamPos->startFrame));
writer->Write(CMD_HH(cmdCamPos->endFrame, 0x0000));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTCommand_CameraPoint* point = (CutsceneOoTCommand_CameraPoint*)e;
writer->Write(CMD_BBH(point->continueFlag, point->cameraRoll, point->nextPointFrame));
writer->Write(point->viewAngle);
writer->Write(CMD_HH(point->posX, point->posY));
writer->Write(CMD_HH(point->posZ, point->unused));
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_AT_SPLINE_REL_TO_PLAYER: {
CutsceneOoTCommand_GenericCameraCmd* cmdCamPos = (CutsceneOoTCommand_GenericCameraCmd*)cs->commands[i];
writer->Write(CS_CMD_CAM_AT_REL_TO_PLAYER);
writer->Write(CMD_HH(0x0001, cmdCamPos->startFrame));
writer->Write(CMD_HH(cmdCamPos->endFrame, 0x0000));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTCommand_CameraPoint* point = (CutsceneOoTCommand_CameraPoint*)e;
writer->Write(CMD_BBH(point->continueFlag, point->cameraRoll, point->nextPointFrame));
writer->Write(point->viewAngle);
writer->Write(CMD_HH(point->posX, point->posY));
writer->Write(CMD_HH(point->posZ, point->unused));
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_EYE: // Not used in OOT
break;
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_AT: // Not used in OOT
break;
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_RUMBLE_CONTROLLER: {
writer->Write(CS_CMD_09);
writer->Write((uint32_t)CMD_W(((CutsceneOoTCommand_Rumble*)cs->commands[i])->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTSubCommandEntry_Rumble* r = (CutsceneOoTSubCommandEntry_Rumble*)e;
writer->Write(CMD_HH(r->base, r->startFrame));
writer->Write(CMD_HBB(e->endFrame, r->sourceStrength, r->duration));
writer->Write(CMD_BBH(r->decreaseRate, r->unk_09, r->unk_0A));
}
break;
}
// case 0x15://Both unused in OoT
// case 0x1A://(uint32_t)CutsceneOoT_CommandType::Unknown:
{
#if 0
CutsceneCommandUnknown* cmdUnk = (CutsceneCommandUnknown*)cs->commands[i];
writer->Write((uint32_t)cs->commands[i]->commandID);
writer->Write((uint32_t)cmdUnk->entries.size());
for (const auto e : cmdUnk->entries)
{
writer->Write(CMD_W(e->unused0));
writer->Write(CMD_W(e->unused1));
writer->Write(CMD_W(e->unused2));
writer->Write(CMD_W(e->unused3));
writer->Write(CMD_W(e->unused4));
writer->Write(CMD_W(e->unused5));
writer->Write(CMD_W(e->unused6));
writer->Write(CMD_W(e->unused7));
writer->Write(CMD_W(e->unused8));
writer->Write(CMD_W(e->unused9));
writer->Write(CMD_W(e->unused10));
writer->Write(CMD_W(e->unused11));
}
#endif
}
break;
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_TEXT: {
writer->Write(CS_CMD_TEXTBOX);
writer->Write((uint32_t)CMD_W((cs->commands[i])->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTSubCommandEntry_Text* textBox = (CutsceneOoTSubCommandEntry_Text*)e;
if (textBox->base == 0xFFFF) // CS_TEXT_NONE
{
writer->Write(CMD_HH(0xFFFF, textBox->startFrame));
writer->Write(CMD_HH(textBox->endFrame, 0xFFFF));
writer->Write(CMD_HH(0xFFFF, 0xFFFF));
} else // CS_TEXT_DISPLAY_TEXTBOX
{
writer->Write(CMD_HH(textBox->base, textBox->startFrame));
writer->Write(CMD_HH(textBox->endFrame, textBox->type));
writer->Write(CMD_HH(textBox->textId1, textBox->textId2));
}
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_PLAYER_CUE: // ActorAction0
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_7:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_8:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_9:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_10:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_11:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_12:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_13:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_14:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_15:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_16:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_0_17:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_7:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_8:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_9:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_10:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_11:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_12:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_13:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_14:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_15:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_16:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_1_17:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_7:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_8:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_9:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_10:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_11:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_12:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_2_13:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_7:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_8:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_9:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_10:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_11:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_3_12:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_7:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_4_8:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_5_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_5_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_5_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_5_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_5_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_5_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_5_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_6_7:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_7_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_7_1:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_7_2:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_7_3:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_7_4:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_7_5:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_7_6:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_8_0:
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_ACTOR_CUE_9_0: {
writer->Write((uint32_t)cs->commands[i]->commandID);
writer->Write((uint32_t)CMD_W(cs->commands[i]->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTSubCommandEntry_ActorCue* actorAct = (CutsceneOoTSubCommandEntry_ActorCue*)e;
writer->Write(CMD_HH(actorAct->base, actorAct->startFrame));
writer->Write(CMD_HH(actorAct->endFrame, actorAct->rotX));
writer->Write(CMD_HH(actorAct->rotY, actorAct->rotZ));
writer->Write(CMD_W(actorAct->startPosX));
writer->Write(CMD_W(actorAct->startPosY));
writer->Write(CMD_W(actorAct->startPosZ));
writer->Write(CMD_W(actorAct->endPosX));
writer->Write(CMD_W(actorAct->endPosY));
writer->Write(CMD_W(actorAct->endPosZ));
writer->Write(CMD_W(actorAct->normalX));
writer->Write(CMD_W(actorAct->normalY));
writer->Write(CMD_W(actorAct->normalZ));
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_TRANSITION: {
CutsceneOoTCommand_Transition* cmdTFX = (CutsceneOoTCommand_Transition*)cs->commands[i];
writer->Write(CS_CMD_SCENE_TRANS_FX);
writer->Write((uint32_t)1);
writer->Write(CMD_HH((cmdTFX->base), cmdTFX->startFrame));
writer->Write(CMD_HH((cmdTFX->endFrame), cmdTFX->endFrame));
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_START_SEQ: {
writer->Write(CS_CMD_PLAYBGM);
writer->Write((uint32_t)CMD_W(cs->commands[i]->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTSubCommandEntry_GenericCmd* cmd = (CutsceneOoTSubCommandEntry_GenericCmd*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HH(cmd->endFrame, cmd->pad));
writer->Write(CMD_W(cmd->unused1));
writer->Write(CMD_W(cmd->unused2));
writer->Write(CMD_W(cmd->unused3));
writer->Write(CMD_W(cmd->unused4));
writer->Write(CMD_W(cmd->unused5));
writer->Write(CMD_W(cmd->unused6));
writer->Write(CMD_W(cmd->unused7));
writer->Write((uint32_t)0);
writer->Write((uint32_t)0);
writer->Write((uint32_t)0);
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_STOP_SEQ: {
writer->Write(CS_CMD_STOPBGM);
writer->Write((uint32_t)CMD_W(cs->commands[i]->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTSubCommandEntry_GenericCmd* cmd = (CutsceneOoTSubCommandEntry_GenericCmd*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HH(cmd->endFrame, cmd->pad));
writer->Write(CMD_W(cmd->unused1));
writer->Write(CMD_W(cmd->unused2));
writer->Write(CMD_W(cmd->unused3));
writer->Write(CMD_W(cmd->unused4));
writer->Write(CMD_W(cmd->unused5));
writer->Write(CMD_W(cmd->unused6));
writer->Write(CMD_W(cmd->unused7));
writer->Write((uint32_t)0);
writer->Write((uint32_t)0);
writer->Write((uint32_t)0);
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_FADE_OUT_SEQ: {
writer->Write(CS_CMD_FADEBGM);
writer->Write((uint32_t)CMD_W(cs->commands[i]->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneOoTSubCommandEntry_GenericCmd* cmd = (CutsceneOoTSubCommandEntry_GenericCmd*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HH(cmd->endFrame, cmd->pad));
writer->Write(CMD_W(cmd->unused1));
writer->Write(CMD_W(cmd->unused2));
writer->Write(CMD_W(cmd->unused3));
writer->Write(CMD_W(cmd->unused4));
writer->Write(CMD_W(cmd->unused5));
writer->Write(CMD_W(cmd->unused6));
writer->Write(CMD_W(cmd->unused7));
writer->Write((uint32_t)0);
writer->Write((uint32_t)0);
writer->Write((uint32_t)0);
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_TIME: {
writer->Write(CS_CMD_SETTIME);
writer->Write((uint32_t)CMD_W(cs->commands[i]->entries.size()));
for (const auto& e : cs->commands[i]->entries) {
CutsceneSubCommandEntry_SetTime* t = (CutsceneSubCommandEntry_SetTime*)e;
writer->Write(CMD_HH(t->base, t->startFrame));
writer->Write(CMD_HBB(t->endFrame, t->hour, t->minute));
writer->Write((uint32_t)0);
// writer->Write((uint32_t)CMD_W(t->unk_08));
}
break;
}
case (uint32_t)CutsceneOoT_CommandType::CS_CMD_DESTINATION: {
CutsceneOoTCommand_Destination* t = (CutsceneOoTCommand_Destination*)cs->commands[i];
writer->Write(CS_CMD_TERMINATOR);
writer->Write((uint32_t)1);
writer->Write(CMD_HH(t->base, t->startFrame));
writer->Write(CMD_HH(t->endFrame, t->endFrame));
break;
}
default: {
// writer->Write((uint32_t)cs->commands[i]->commandID);
printf("Undefined CS Opcode: %04X\n", cs->commands[i]->commandID);
} break;
}
}
}
// MUST be uint16_t for -1
typedef enum : uint16_t {
/* -1 */ CS_TEXT_TYPE_NONE = (uint16_t)-1,
/* 0 */ CS_TEXT_TYPE_DEFAULT = 0,
/* 1 */ CS_TEXT_TYPE_1,
/* 2 */ CS_TEXT_OCARINA_ACTION,
/* 3 */ CS_TEXT_TYPE_3,
/* 4 */ CS_TEXT_TYPE_BOSSES_REMAINS, // use `altText1` in the Giant Cutscene if all remains are already obtained
/* 5 */ CS_TEXT_TYPE_ALL_NORMAL_MASKS
} CutsceneTextType;
typedef enum : uint8_t {
/* 0 */ Header,
/* 1 */ CamPoint,
/* 2 */ CamMisc,
/* 3 */ Footer,
} CutsceneSplineType;
void OTRExporter_Cutscene::SaveMM(ZCutscene* cs, BinaryWriter* writer) {
for (size_t i = 0; i < cs->commands.size(); i++) {
writer->Write((uint32_t)cs->commands[i]->commandID);
if (((cs->commands[i]->commandID >= (uint32_t)CutsceneMM_CommandType::CS_CMD_ACTOR_CUE_100) &&
(cs->commands[i]->commandID <= (uint32_t)CutsceneMM_CommandType::CS_CMD_ACTOR_CUE_149)) ||
(cs->commands[i]->commandID == (uint32_t)CutsceneMM_CommandType::CS_CMD_ACTOR_CUE_201) ||
((cs->commands[i]->commandID >= (uint32_t)CutsceneMM_CommandType::CS_CMD_ACTOR_CUE_450) &&
(cs->commands[i]->commandID <= (uint32_t)CutsceneMM_CommandType::CS_CMD_ACTOR_CUE_599))) {
goto actorCue;
}
switch ((CutsceneMM_CommandType)cs->commands[i]->commandID) {
case CutsceneMM_CommandType::CS_CMD_TEXT: {
writer->Write((uint32_t)cs->commands[i]->entries.size());
for (const auto& e : cs->commands[i]->entries) {
auto* cmd = (CutsceneMMSubCommandEntry_Text*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HH(cmd->endFrame, cmd->type));
writer->Write(CMD_HH(cmd->textId1, cmd->textId2));
}
break;
}
// BENTODO: Can these stay consilidated?
case CutsceneMM_CommandType::CS_CMD_CAMERA_SPLINE: {
// This command uses 4 different macros that are all different sizes and uses the number of bytes of the
// whole command instead of entries like most other commands. numEntries isn't actually the number of entries in the command
// rather the number of bytes the command will take up in the rom. We also can not simply use GetCommandSize because it returns
// a larger size to help ZAPD know where to start reading for the next command.
writer->Write((uint32_t)cs->commands[i]->numEntries);
// monkaS
size_t j = 0;
for (;;) {
auto* header = dynamic_cast<CutsceneSubCommandEntry_SplineHeader*>(cs->commands[i]->entries[j]);
//Debugging check, can probably remove after testing
assert(header != nullptr);
uint32_t numEntries = header->numEntries;
writer->Write(CMD_HH(header->numEntries, header->unused0));
writer->Write(CMD_HH(header->unused1, header->duration));
for (size_t k = 0; k < numEntries * 2; k++) {
auto* element =
dynamic_cast<CutsceneSubCommandEntry_SplineCamPoint*>(cs->commands[i]->entries[++j]);
// Debugging check, can probably remove after testing
assert(element != nullptr);
writer->Write(CMD_BBH(element->interpType, element->weight, element->duration));
writer->Write(CMD_HH(element->posX, element->posY));
writer->Write(CMD_HH(element->posZ, element->relTo));
}
for (size_t k = 0; k < numEntries; k++) {
auto* element =
dynamic_cast<CutsceneSubCommandEntry_SplineMiscPoint*>(cs->commands[i]->entries[++j]);
// Debugging check, can probably remove after testing
assert(element != nullptr);
writer->Write(CMD_HH(element->unused0, element->roll));
writer->Write(CMD_HH(element->fov, element->unused1));
}
auto* header2 = dynamic_cast<CutsceneSubCommandEntry_SplineFooter*>(cs->commands[i]->entries[++j]);
if (header2 != nullptr) {
if (header2->base == 0xFFFF) {
break;
}
}
}
// The footer exists as an error checking type and a way to output an empty macro. It holds no actual data.
auto* footer = dynamic_cast<CutsceneSubCommandEntry_SplineFooter*>(cs->commands[i]->entries[j]);
assert(footer != nullptr);
writer->Write((uint16_t)0xFFFF);
writer->Write((uint16_t)0x0004);
//i += j;
break;
}
case CutsceneMM_CommandType::CS_CMD_MISC:
case CutsceneMM_CommandType::CS_CMD_LIGHT_SETTING:
case CutsceneMM_CommandType::CS_CMD_TRANSITION:
case CutsceneMM_CommandType::CS_CMD_MOTION_BLUR:
case CutsceneMM_CommandType::CS_CMD_GIVE_TATL:
case CutsceneMM_CommandType::CS_CMD_STOP_SEQ:
case CutsceneMM_CommandType::CS_CMD_START_SEQ:
case CutsceneMM_CommandType::CS_CMD_SFX_REVERB_INDEX_2:
case CutsceneMM_CommandType::CS_CMD_SFX_REVERB_INDEX_1:
case CutsceneMM_CommandType::CS_CMD_MODIFY_SEQ:
case CutsceneMM_CommandType::CS_CMD_START_AMBIENCE:
case CutsceneMM_CommandType::CS_CMD_FADE_OUT_AMBIENCE:
case CutsceneMM_CommandType::CS_CMD_DESTINATION:
case CutsceneMM_CommandType::CS_CMD_CHOOSE_CREDITS_SCENES:
default:
{
writer->Write((uint32_t)cs->commands[i]->entries.size());
for (const auto e : cs->commands[i]->entries) {
writer->Write(CMD_HH(e->base, e->startFrame));
writer->Write(CMD_HH(e->endFrame, e->pad));
}
break;
}
case CutsceneMM_CommandType::CS_CMD_TRANSITION_GENERAL: {
writer->Write((uint32_t)cs->commands[i]->entries.size());
for (const auto e : cs->commands[i]->entries) {
auto* cmd = (CutsceneSubCommandEntry_TransitionGeneral*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HBB(cmd->endFrame, cmd->unk_06, cmd->unk_07));
writer->Write(CMD_BBBB(cmd->unk_08, 0, 0, 0));
}
break;
}
case CutsceneMM_CommandType::CS_CMD_FADE_OUT_SEQ: {
writer->Write((uint32_t)cs->commands[i]->entries.size());
for (const auto e : cs->commands[i]->entries) {
writer->Write(CMD_HH(e->base, e->startFrame));
writer->Write(CMD_HH(e->endFrame, e->pad));
writer->Write(CMD_W(0));
}
break;
}
case CutsceneMM_CommandType::CS_CMD_TIME: {
writer->Write((uint32_t)cs->commands[i]->entries.size());
for (const auto e : cs->commands[i]->entries) {
auto* cmd = (CutsceneSubCommandEntry_SetTime*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HBB(cmd->endFrame, cmd->hour, cmd->minute));
writer->Write(CMD_W(0));
}
break;
}
case CutsceneMM_CommandType::CS_CMD_PLAYER_CUE: {
actorCue:
writer->Write((uint32_t)cs->commands[i]->entries.size());
for (const auto e : cs->commands[i]->entries) {
auto* cmd = (CutsceneMMSubCommandEntry_ActorCue*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HH(cmd->endFrame, cmd->rotX));
writer->Write(CMD_HH(cmd->rotY, cmd->rotZ));
writer->Write(CMD_W(cmd->startPosX));
writer->Write(CMD_W(cmd->startPosY));
writer->Write(CMD_W(cmd->startPosZ));
writer->Write(CMD_W(cmd->endPosX));
writer->Write(CMD_W(cmd->endPosY));
writer->Write(CMD_W(cmd->endPosZ));
writer->Write(CMD_F(cmd->normalX));
writer->Write(CMD_F(cmd->normalY));
writer->Write(CMD_F(cmd->normalZ));
}
break;
}
case CutsceneMM_CommandType::CS_CMD_RUMBLE: {
writer->Write((uint32_t)cs->commands[i]->entries.size());
for (const auto e : cs->commands[i]->entries) {
auto* cmd = (CutsceneMMSubCommandEntry_Rumble*)e;
writer->Write(CMD_HH(cmd->base, cmd->startFrame));
writer->Write(CMD_HBB(cmd->endFrame, cmd->intensity, cmd->decayTimer));
writer->Write(CMD_BBBB(cmd->decayStep, 0, 0, 0));
}
break;
}
}
}
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include "ZResource.h"
#include "ZCutscene.h"
#include "z64cutscene_commands.h"
#include "Exporter.h"
class OTRExporter_Cutscene : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
void SaveOot(ZCutscene* res, BinaryWriter* writer);
void SaveMM(ZCutscene* res, BinaryWriter* writer);
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,17 @@
#pragma once
#include "ZResource.h"
#include "ZTexture.h"
#include "ZDisplayList.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_DisplayList : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
static std::string GetParentFolderName(ZResource* res);
static std::string GetPathToRes(ZResource* res, std::string varName);
static std::string GetPrefix(ZResource* res);
};

View File

@@ -0,0 +1,21 @@
#include "Exporter.h"
#include "VersionInfo.h"
void OTRExporter::WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, uint32_t resType, int32_t resVersion)
{
writer->Write((uint8_t)Endianness::Little); // 0x00
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write((uint32_t)resType); // 0x04
//writer->Write((uint32_t)MAJOR_VERSION); // 0x08
writer->Write((uint32_t)resVersion); // 0x08
writer->Write((uint64_t)0xDEADBEEFDEADBEEF); // id, 0x0C
writer->Write((uint32_t)resourceVersions[resType]); // 0x10
writer->Write((uint64_t)0); // ROM CRC, 0x14
writer->Write((uint32_t)0); // ROM Enum, 0x1C
while (writer->GetBaseAddress() < 0x40)
writer->Write((uint32_t)0); // To be used at a later date!
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "ZResource.h"
#include "ZArray.h"
#include "stdint.h"
#include <Utils/BinaryWriter.h>
#include <libultraship/bridge.h>
#include "VersionInfo.h"
#ifdef GAME_MM
#include "../../mm/2s2h/resource/type/2shResourceType.h"
#elif GAME_OOT
#include "../../soh/soh/resource/type/SohResourceType.h"
#endif
class OTRExporter : public ZResourceExporter
{
protected:
static void WriteHeader(ZResource* res, const fs::path& outPath, BinaryWriter* writer, uint32_t resType, int32_t resVersion = 0);
};

View File

@@ -0,0 +1,11 @@
#include "ExporterArchive.h"
#include "Utils/StringHelper.h"
#include <ship/utils/StrHash64.h>
#include <filesystem>
ExporterArchive::ExporterArchive(const std::string& path, bool enableWriting) : mPath(path) {
}
ExporterArchive::~ExporterArchive() {
}

View File

@@ -0,0 +1,26 @@
#pragma once
#undef _DLL
#include <string>
#include <vector>
#include <unordered_map>
#include <memory>
#include <mutex>
#include <StormLib.h>
class ExporterArchive : public std::enable_shared_from_this<ExporterArchive> {
public:
ExporterArchive() {}
ExporterArchive(const std::string& path, bool enableWriting);
~ExporterArchive();
virtual int CreateArchive(size_t fileCapacity) = 0;
virtual bool AddFile(const std::string& filePath, void* fileData, size_t fileSize) = 0;
std::string mPath;
std::mutex mMutex;
virtual bool Load(bool enableWriting) = 0;
virtual bool Unload() = 0;
};

View File

@@ -0,0 +1,93 @@
#include "ExporterArchiveO2R.h"
#include "Utils/StringHelper.h"
#include <ship/utils/StrHash64.h>
#include <filesystem>
#include <spdlog/spdlog.h>
ExporterArchiveO2R::ExporterArchiveO2R(const std::string& path, bool enableWriting) {
mPath = path;
mZip = nullptr;
}
ExporterArchiveO2R::~ExporterArchiveO2R() {
Unload();
}
bool ExporterArchiveO2R::Load(bool enableWriting) {
int openErr;
zip_t* archive = zip_open(mPath.c_str(), ZIP_CHECKCONS, &openErr);
if (archive == nullptr) {
zip_error_t error;
zip_error_init_with_code(&error, openErr);
SPDLOG_ERROR("Failed to open ZIP (O2R) file. Error: {}", zip_error_strerror(&error));
zip_error_fini(&error);
return false;
}
SPDLOG_INFO("Loaded ZIP (O2R) archive: {}", mPath.c_str());
mZip = archive;
return true;
}
bool ExporterArchiveO2R::Unload() {
printf("Unload\n");
int err;
{
const std::lock_guard<std::mutex> lock(mMutex);
err = zip_close(mZip);
}
if (err < 0) {
zip_error_t* zipError = zip_get_error(mZip);
SPDLOG_ERROR("Failed to close ZIP (O2R) file. Error: {}", zip_error_strerror(zipError));
printf("fail\n");
zip_error_fini(zipError);
return false;
}
return true;
}
int ExporterArchiveO2R::CreateArchive([[maybe_unused]] size_t fileCapacity) {
int openErr;
zip_t* zip;
{
const std::lock_guard<std::mutex> lock(mMutex);
zip = zip_open(mPath.c_str(), ZIP_CREATE, &openErr);
}
if (zip == nullptr) {
zip_error_t error;
zip_error_init_with_code(&error, openErr);
SPDLOG_ERROR("Failed to create ZIP (O2R) file. Error: {}", zip_error_strerror(&error));
zip_error_fini(&error);
return -1;
}
mZip = zip;
SPDLOG_INFO("Loaded ZIP (O2R) archive: {}", mPath.c_str());
return 0;
}
bool ExporterArchiveO2R::AddFile(const std::string& filePath, void* fileData, size_t fileSize) {
zip_source_t* source = zip_source_buffer(mZip, fileData, fileSize, 0);
if (source == nullptr) {
zip_error_t* zipError = zip_get_error(mZip);
SPDLOG_ERROR("Failed to create ZIP source. Error: {}", zip_error_strerror(zipError));
zip_source_free(source);
zip_error_fini(zipError);
return false;
}
if (zip_file_add(mZip, filePath.c_str(), source, ZIP_FL_OVERWRITE | ZIP_FL_ENC_UTF_8) < 0) {
zip_error_t* zipError = zip_get_error(mZip);
SPDLOG_ERROR("Failed to add file to ZIP. Error: {}", zip_error_strerror(zipError));
zip_source_free(source);
zip_error_fini(zipError);
return false;
}
return true;
}

View File

@@ -0,0 +1,24 @@
#pragma once
#undef _DLL
#include <string>
#include <vector>
#include <unordered_map>
#include <memory>
#include <mutex>
#include <zip.h>
#include "ExporterArchive.h"
class ExporterArchiveO2R : public ExporterArchive {
public:
ExporterArchiveO2R(const std::string& path, bool enableWriting);
~ExporterArchiveO2R();
int CreateArchive(size_t fileCapacity) override;
bool AddFile(const std::string& filePath, void* fileData, size_t fileSize) override;
zip_t* mZip;
bool Load(bool enableWriting) override;
bool Unload() override;
};

View File

@@ -0,0 +1,147 @@
#ifdef INCLUDE_MPQ_SUPPORT
#include "ExporterArchiveOTR.h"
#include "Utils/StringHelper.h"
#include <ship/utils/StrHash64.h>
#include <filesystem>
ExporterArchiveOtr::ExporterArchiveOtr(const std::string& path, bool enableWriting) {
mPath = path;
mMpq = nullptr;
}
ExporterArchiveOtr::~ExporterArchiveOtr() {
Unload();
}
bool ExporterArchiveOtr::Load(bool enableWriting) {
HANDLE mpqHandle = NULL;
bool baseLoaded = false;
std::string fullPath = std::filesystem::absolute(mPath).string();
bool openArchiveSuccess;
{
const std::lock_guard<std::mutex> lock(mMutex);
openArchiveSuccess = SFileOpenArchive(fullPath.c_str(), 0, enableWriting ? 0 : MPQ_OPEN_READ_ONLY, &mpqHandle);
}
if (openArchiveSuccess) {
printf("Opened mpq file %s\n", fullPath.c_str());
mMpq = mpqHandle;
mPath = fullPath;
baseLoaded = true;
}
if (!baseLoaded) {
printf("No valid OTR file was provided.");
return false;
}
return true;
}
bool ExporterArchiveOtr::Unload() {
bool success = true;
bool closeArchiveSuccess;
{
const std::lock_guard<std::mutex> lock(mMutex);
closeArchiveSuccess = SFileCloseArchive(mMpq);
}
if (!closeArchiveSuccess) {
printf("Failed to close mpq\n");
success = false;
}
mMpq = nullptr;
return success;
}
int ExporterArchiveOtr::CreateArchive(size_t fileCapacity) {
bool success;
{
const std::lock_guard<std::mutex> lock(mMutex);
success = SFileCreateArchive(mPath.c_str(), MPQ_CREATE_LISTFILE | MPQ_CREATE_ATTRIBUTES | MPQ_CREATE_ARCHIVE_V2,
static_cast<DWORD>(fileCapacity), &mMpq);
}
int32_t error = GetLastError();
if (success) {
return 0;
} else {
printf("We tried to create an archive, but it has fallen and cannot get up.\n");
return -1;
}
}
bool ExporterArchiveOtr::AddFile(const std::string& filePath, void* fileData, size_t fileSize) {
HANDLE hFile;
#ifdef _WIN32
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
FILETIME t;
SystemTimeToFileTime(&sysTime, &t);
ULONGLONG theTime = static_cast<uint64_t>(t.dwHighDateTime) << (sizeof(t.dwHighDateTime) * 8) | t.dwLowDateTime;
#else
time_t theTime;
time(&theTime);
#endif
std::string updatedPath = filePath;
StringHelper::ReplaceOriginal(updatedPath, "\\", "/");
bool createFileSuccess;
{
const std::lock_guard<std::mutex> lock(mMutex);
createFileSuccess =
SFileCreateFile(mMpq, updatedPath.c_str(), theTime, static_cast<DWORD>(fileSize), 0, MPQ_FILE_COMPRESS, &hFile);
}
if (!createFileSuccess) {
printf("Failed to create file.\n");
return false;
}
bool writeFileSuccess;
{
const std::lock_guard<std::mutex> lock(mMutex);
writeFileSuccess = SFileWriteFile(hFile, fileData, static_cast<DWORD>(fileSize), MPQ_COMPRESSION_ZLIB);
}
if (!writeFileSuccess) {
printf("Failed to write.\n");
bool closeFileSuccess;
{
const std::lock_guard<std::mutex> lock(mMutex);
closeFileSuccess = SFileCloseFile(hFile);
}
if (!closeFileSuccess) {
printf("Failed to close.\n");
}
return false;
}
bool finishFileSuccess;
{
const std::lock_guard<std::mutex> lock(mMutex);
finishFileSuccess = SFileFinishFile(hFile);
}
if (!finishFileSuccess) {
printf("Failed to finish file.\n");
bool closeFileSuccess;
{
const std::lock_guard<std::mutex> lock(mMutex);
closeFileSuccess = SFileCloseFile(hFile);
}
if (!closeFileSuccess) {
printf("Failed to close after finish failure.\n");
}
return false;
}
// SFileFinishFile already frees the handle, so no need to close it again.
mAddedFiles.push_back(updatedPath);
mHashes[CRC64(updatedPath.c_str())] = updatedPath;
return true;
}
#endif

View File

@@ -0,0 +1,29 @@
#pragma once
#ifdef INCLUDE_MPQ_SUPPORT
#undef _DLL
#include <string>
#include <vector>
#include <unordered_map>
#include <memory>
#include <mutex>
#include <StormLib.h>
#include "ExporterArchive.h"
class ExporterArchiveOtr : public ExporterArchive {
public:
ExporterArchiveOtr(const std::string& path, bool enableWriting);
~ExporterArchiveOtr();
int CreateArchive(size_t fileCapacity) override;
bool AddFile(const std::string& filePath, void* fileData, size_t fileSize) override;
bool Load(bool enableWriting) override;
bool Unload() override;
private:
std::unordered_map<uint64_t, std::string> mHashes;
std::vector<std::string> mAddedFiles;
HANDLE mMpq;
};
#endif

View File

@@ -0,0 +1,440 @@
#include "Main.h"
#include "Exporter.h"
#include "BackgroundExporter.h"
#include "TextureExporter.h"
#include "RoomExporter.h"
#include "CollisionExporter.h"
#include "DisplayListExporter.h"
#include "PlayerAnimationExporter.h"
#include "SkeletonExporter.h"
#include "SkeletonLimbExporter.h"
#include "ArrayExporter.h"
#include "VtxExporter.h"
#include "AnimationExporter.h"
#include "CutsceneExporter.h"
#include "PathExporter.h"
#include "TextExporter.h"
#include "TextMMExporter.h"
#include "BlobExporter.h"
#include "MtxExporter.h"
#include "AudioExporter.h"
#include "TextureAnimationExporter.h"
#include "CKeyFrameExporter.h"
#include <Globals.h>
#include <Utils/DiskFile.h>
#include <Utils/Directory.h>
#include <Utils/MemoryStream.h>
#include <Utils/BinaryWriter.h>
#include <Utils/BitConverter.h>
#include <bit>
#include <mutex>
#include <ExporterArchiveO2R.h>
#include "ExporterArchiveOTR.h"
#ifdef GAME_MM
std::string archiveFileName = "mm.o2r";
#elif GAME_OOT
std::string archiveFileName = "oot.o2r";
#endif
std::string customArchiveFileName = "";
std::string customAssetsPath = "";
std::string portVersionString = "0.0.0";
std::shared_ptr<ExporterArchive> archive;
BinaryWriter* fileWriter;
std::chrono::steady_clock::time_point fileStart, resStart;
std::map<std::string, std::vector<char>> files;
std::mutex fileMutex;
void InitVersionInfo();
enum class ExporterFileMode
{
BuildOTR = (int)ZFileMode::Custom + 1,
};
static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileMode)
{
if (buildMode == "botr")
{
fileMode = (ZFileMode)ExporterFileMode::BuildOTR;
printf("BOTR: Generating OTR Archive...\n");
archive = std::make_shared<ExporterArchiveO2R>(archiveFileName, true);
if (DiskFile::Exists(archiveFileName))
archive->Load(true);
else
archive->CreateArchive(40000);
auto lst = Directory::ListFiles("Extract");
for (auto item : lst)
{
auto fileData = DiskFile::ReadAllBytes(item);
archive->AddFile(StringHelper::Split(item, "Extract/")[1], fileData.data(), fileData.size());
}
}
}
typedef struct Data {
std::vector<char> fileData;
std::string filePath;
size_t size;
} Data;
typedef struct DataU {
std::vector<uint8_t> fileData;
std::string filePath;
size_t size;
} DataU;
static void ExporterProgramEnd()
{
uint32_t crc = 0xFFFFFFFF;
const uint8_t endianness = (uint8_t)Endianness::Big;
std::vector<uint16_t> portVersion = {};
std::vector<std::string> versionParts = StringHelper::Split(portVersionString, ".");
// If a major.minor.patch string was not passed in, fallback to 0 0 0
if (versionParts.size() != 3) {
portVersion = { 0, 0, 0 };
} else {
// Parse version values to number
for (const auto& val : versionParts) {
uint16_t num = 0;
try {
num = (uint16_t)std::stoi(val, nullptr);
} catch (std::invalid_argument &e) {
num = 0;
} catch (std::out_of_range &e) {
num = 0;
}
portVersion.push_back(num);
}
}
MemoryStream *portVersionStream = new MemoryStream();
BinaryWriter portVerWriter(portVersionStream);
portVerWriter.SetEndianness(Endianness::Big);
portVerWriter.Write(endianness);
portVerWriter.Write(portVersion[0]); // Major
portVerWriter.Write(portVersion[1]); // Minor
portVerWriter.Write(portVersion[2]); // Patch
portVerWriter.Close();
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
{
std::string romPath = Globals::Instance->baseRomPath.string();
std::vector<uint8_t> romData = DiskFile::ReadAllBytes(romPath);
BitConverter::RomToBigEndian(romData.data(), romData.size());
crc = BitConverter::ToUInt32BE(romData, 0x10);
printf("Creating version file...\n");
// Get crc from rom
MemoryStream *versionStream = new MemoryStream();
BinaryWriter writer(versionStream);
writer.SetEndianness(Endianness::Big);
writer.Write(endianness);
writer.Write(crc);
writer.Close();
printf("Created version file.\n");
printf("Generating OTR Archive...\n");
archive = std::make_shared<ExporterArchiveO2R>(archiveFileName, true);
archive->CreateArchive(40000);
printf("Adding game version file.\n");
auto versionStreamBuffer = versionStream->ToVector();
archive->AddFile("version", (void*)versionStreamBuffer.data(), versionStream->GetLength());
printf("Adding portVersion file.\n");
auto portVersionStreamBuffer = portVersionStream->ToVector();
archive->AddFile("portVersion", (void*)portVersionStreamBuffer.data(), portVersionStream->GetLength());
for (const auto& item : files)
{
std::string fName = item.first;
if (fName.find("gTitleZeldaShieldLogoMQTex") != std::string::npos && !ZRom(romPath).IsMQ())
{
size_t pos = 0;
if ((pos = fName.find("gTitleZeldaShieldLogoMQTex", 0)) != std::string::npos)
{
fName.replace(pos, 27, "gTitleZeldaShieldLogoTex");
}
}
const auto& fileData = item.second;
archive->AddFile(fName, (void*)fileData.data(), fileData.size());
}
archive = nullptr;
}
delete fileWriter;
files.clear();
// Generate custom otr file for extra assets
if (customAssetsPath == "" || customArchiveFileName == "" || DiskFile::Exists(customArchiveFileName)) {
printf("No Custom Assets path or otr file name provided, otr file already exists. Nothing to do.\n");
return;
}
if (!customAssetsPath.ends_with("/")) {
customAssetsPath += "/";
}
const auto& lst = Directory::ListFiles(customAssetsPath);
printf("Generating Custom OTR Archive...\n");
auto customOtr = std::make_unique<ExporterArchiveO2R>(customArchiveFileName, true);
customOtr->CreateArchive(40000);
printf("Adding portVersion file.\n");
auto portVersionStreamBuffer = portVersionStream->ToVector();
customOtr->AddFile("portVersion", (void*)portVersionStreamBuffer.data(), portVersionStream->GetLength());
std::vector<Data> dataVec;
std::vector<DataU> dataVec2;
for (const auto& item : lst)
{
size_t filenameSepAt = item.find_last_of("/\\");
const std::string filename = item.substr(filenameSepAt + 1);
if (std::count(filename.begin(), filename.end(), '.') >= 2)
{
size_t extensionSepAt = filename.find_last_of(".");
size_t formatSepAt = filename.find_last_of(".", extensionSepAt - 1);
const std::string extension = filename.substr(extensionSepAt + 1);
const std::string format = filename.substr(formatSepAt + 1, extensionSepAt - formatSepAt - 1);
std::string afterPath = item.substr(0, filenameSepAt + formatSepAt + 1);
if (extension == "png" && (format == "rgba32" || format == "rgb5a1" || format == "i4" || format == "i8" || format == "ia4" || format == "ia8" || format == "ia16" || format == "ci4" || format == "ci8"))
{
ZTexture tex(nullptr);
Globals::Instance->buildRawTexture = true;
tex.FromPNG(item, ZTexture::GetTextureTypeFromString(format));
printf("customOtr->AddFile(%s)\n", StringHelper::Split(afterPath, customAssetsPath)[1].c_str());
OTRExporter_Texture exporter;
MemoryStream* stream = new MemoryStream();
BinaryWriter writer(stream);
exporter.Save(&tex, "", &writer);
std::string src = tex.GetBodySourceCode();
writer.Write((char *)src.c_str(), src.size());
std::vector<char> fileData = stream->ToVector();
dataVec.push_back({ fileData, StringHelper::Split(afterPath, customAssetsPath)[1], fileData.size() });
continue;
}
}
if (item.find("accessibility") != std::string::npos)
{
std::string extension = filename.substr(filename.find_last_of(".") + 1);
if (extension == "json")
{
const auto &fileData = DiskFile::ReadAllBytes(item);
printf("Adding accessibility texts %s\n", StringHelper::Split(item, customAssetsPath)[1].c_str());
dataVec2.push_back({fileData,
StringHelper::Split(item, customAssetsPath)[1], fileData.size() });
}
continue;
}
const auto& fileData = DiskFile::ReadAllBytes(item);
printf("customOtr->AddFile(%s)\n", StringHelper::Split(item, customAssetsPath)[1].c_str());
dataVec2.push_back({ fileData, StringHelper::Split(item, customAssetsPath)[1], fileData.size() });
}
for (auto& d : dataVec) {
customOtr->AddFile(d.filePath, d.fileData.data(), d.size);
}
for (auto& d : dataVec2) {
customOtr->AddFile(d.filePath, d.fileData.data(), d.size);
}
printf("Done\n");
// For O2Rs the zip file MUST be closed while the vectors are still valid so we need to close the file in this function.
customOtr = nullptr;
}
static void ExporterParseArgs(int argc, char* argv[], int& i)
{
std::string arg = argv[i];
if (arg == "--otrfile") {
archiveFileName = argv[i + 1];
i++;
} else if (arg == "--customOtrFile") {
customArchiveFileName = argv[i + 1];
i++;
} else if (arg == "--customAssetsPath") {
customAssetsPath = argv[i + 1];
i++;
} else if (arg == "--portVer") {
portVersionString = argv[i + 1];
i++;
}
}
static bool ExporterProcessFileMode(ZFileMode fileMode)
{
// Do whatever work is associated with these custom file modes...
// Return true to indicate one of our own file modes is being processed
if (fileMode == (ZFileMode)ExporterFileMode::BuildOTR)
return true;
return false;
}
static void ExporterFileBegin(ZFile* file)
{
fileStart = std::chrono::steady_clock::now();
MemoryStream* stream = new MemoryStream();
fileWriter = new BinaryWriter(stream);
}
static void ExporterFileEnd(ZFile* file)
{
// delete fileWriter;
}
static void ExporterResourceEnd(ZResource* res, BinaryWriter& writer)
{
auto streamShared = writer.GetStream();
MemoryStream* strem = (MemoryStream*)streamShared.get();
auto start = std::chrono::steady_clock::now();
if (res->GetName() != "")
{
std::string oName = res->parent->GetOutName();
std::string rName = res->GetName();
std::string prefix = OTRExporter_DisplayList::GetPrefix(res);
//auto xmlFilePath = res->parent->GetXmlFilePath();
//prefix = StringHelper::Split(StringHelper::Split(xmlFilePath.string(), "xml\\")[1], ".xml")[0];
if (StringHelper::Contains(oName, "_scene"))
{
auto split = StringHelper::Split(oName, "_");
oName = "";
for (size_t i = 0; i < split.size() - 1; i++)
oName += split[i] + "_";
oName += "scene";
}
else if (StringHelper::Contains(oName, "_room"))
{
if (Globals::Instance->game != ZGame::MM_RETAIL)
oName = StringHelper::Split(oName, "_room")[0] + "_scene";
else
oName = StringHelper::Split(oName, "_room")[0];
}
std::string fName = "";
if (prefix != "")
fName = StringHelper::Sprintf("%s/%s/%s", prefix.c_str(), oName.c_str(), rName.c_str());
else
fName = StringHelper::Sprintf("%s/%s", oName.c_str(), rName.c_str());
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
{
std::unique_lock Lock(fileMutex);
files[fName] = strem->ToVector();
}
else
DiskFile::WriteAllBytes("Extract/" + fName, strem->ToVector());
}
auto end = std::chrono::steady_clock::now();
size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
//if (diff > 10)
//printf("Exported Resource End %s in %zums\n", res->GetName().c_str(), diff);
}
static void ExporterProcessCompilable(tinyxml2::XMLElement* reader)
{
std::string nodeName = reader->Name();
}
static void ExporterXMLBegin()
{
}
static void ExporterXMLEnd()
{
}
void AddFile(std::string fName, std::vector<char> data)
{
if (Globals::Instance->fileMode != ZFileMode::ExtractDirectory)
DiskFile::WriteAllBytes("Extract/" + fName, data);
else
{
std::unique_lock Lock(fileMutex);
files[fName] = data;
}
}
void ImportExporters()
{
// In this example we set up a new exporter called "EXAMPLE".
// By running ZAPD with the argument -se EXAMPLE, we tell it that we want to use this exporter for our resources.
ExporterSet* exporterSet = new ExporterSet();
exporterSet->processFileModeFunc = ExporterProcessFileMode;
exporterSet->parseFileModeFunc = ExporterParseFileMode;
exporterSet->processCompilableFunc = ExporterProcessCompilable;
exporterSet->parseArgsFunc = ExporterParseArgs;
exporterSet->beginFileFunc = ExporterFileBegin;
exporterSet->endFileFunc = ExporterFileEnd;
exporterSet->beginXMLFunc = ExporterXMLBegin;
exporterSet->endXMLFunc = ExporterXMLEnd;
exporterSet->resSaveFunc = ExporterResourceEnd;
exporterSet->endProgramFunc = ExporterProgramEnd;
exporterSet->exporters[ZResourceType::Background] = new OTRExporter_Background();
exporterSet->exporters[ZResourceType::Texture] = new OTRExporter_Texture();
exporterSet->exporters[ZResourceType::Room] = new OTRExporter_Room();
exporterSet->exporters[ZResourceType::AltHeader] = new OTRExporter_Room();
exporterSet->exporters[ZResourceType::Scene] = new OTRExporter_Room();
exporterSet->exporters[ZResourceType::CollisionHeader] = new OTRExporter_Collision();
exporterSet->exporters[ZResourceType::DisplayList] = new OTRExporter_DisplayList();
exporterSet->exporters[ZResourceType::PlayerAnimationData] = new OTRExporter_PlayerAnimationExporter();
exporterSet->exporters[ZResourceType::Skeleton] = new OTRExporter_Skeleton();
exporterSet->exporters[ZResourceType::Limb] = new OTRExporter_SkeletonLimb();
exporterSet->exporters[ZResourceType::Animation] = new OTRExporter_Animation();
exporterSet->exporters[ZResourceType::Cutscene] = new OTRExporter_Cutscene();
exporterSet->exporters[ZResourceType::Vertex] = new OTRExporter_Vtx();
exporterSet->exporters[ZResourceType::Array] = new OTRExporter_Array();
exporterSet->exporters[ZResourceType::Path] = new OTRExporter_Path();
exporterSet->exporters[ZResourceType::Text] = new OTRExporter_Text();
#ifdef GAME_MM
exporterSet->exporters[ZResourceType::TextMM] = new OTRExporter_TextMM();
exporterSet->exporters[ZResourceType::KeyFrameSkel] = new OTRExporter_CKeyFrameSkel();
exporterSet->exporters[ZResourceType::KeyFrameAnimation] = new OTRExporter_CKeyFrameAnim();
exporterSet->exporters[ZResourceType::TextureAnimation] = new OTRExporter_TextureAnimation();
#endif
exporterSet->exporters[ZResourceType::Blob] = new OTRExporter_Blob();
exporterSet->exporters[ZResourceType::Mtx] = new OTRExporter_MtxExporter();
exporterSet->exporters[ZResourceType::Audio] = new OTRExporter_Audio();
Globals::AddExporter("OTR", exporterSet);
InitVersionInfo();
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include <libultraship/bridge.h>
#include "ExporterArchive.h"
extern std::shared_ptr<ExporterArchive> archive;
extern std::map<std::string, std::vector<char>> files;
void AddFile(std::string fName, std::vector<char> data);

View File

@@ -0,0 +1,13 @@
#include "MtxExporter.h"
void OTRExporter_MtxExporter::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZMtx* mtx = (ZMtx*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(Fast::ResourceType::Matrix));
for (size_t i = 0; i < 4; i++)
for (size_t j = 0; j < 4; j++)
//TODO possibly utilize the array class better
writer->Write(mtx->mtx[i][j]);
}

View File

@@ -0,0 +1,10 @@
#include "ZResource.h"
#include "ZMtx.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_MtxExporter : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,27 @@
#include "PathExporter.h"
#include "../ZAPD/ZFile.h"
#include "Globals.h"
void OTRExporter_Path::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZPath* path = (ZPath*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Path));
writer->Write((uint32_t)path->pathways.size());
for (size_t k = 0; k < path->pathways.size(); k++)
{
writer->Write((uint32_t)path->pathways[k].points.size());
if (Globals::Instance->game == ZGame::MM_RETAIL) {
writer->Write(path->pathways[k].unk1);
writer->Write(path->pathways[k].unk2);
}
for (size_t i = 0; i < path->pathways[k].points.size(); i++)
{
writer->Write(path->pathways[k].points[i].scalars[0].scalarData.s16);
writer->Write(path->pathways[k].points[i].scalars[1].scalarData.s16);
writer->Write(path->pathways[k].points[i].scalars[2].scalarData.s16);
}
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "ZResource.h"
#include "ZPath.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Path : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,21 @@
#include "PlayerAnimationExporter.h"
#include <libultraship/bridge.h>
void OTRExporter_PlayerAnimationExporter::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZPlayerAnimationData* anim = (ZPlayerAnimationData*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_PlayerAnimation));
auto start = std::chrono::steady_clock::now();
writer->Write((uint32_t)anim->limbRotData.size());
for (size_t i = 0; i < anim->limbRotData.size(); i++)
writer->Write(anim->limbRotData[i]);
auto end = std::chrono::steady_clock::now();
size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
//printf("Exported Player Anim %s in %zums\n", anim->GetName().c_str(), diff);
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include "ZResource.h"
#include "ZTexture.h"
#include "ZPlayerAnimationData.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_PlayerAnimationExporter : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,636 @@
#define NO_GDI
#define WIN32_LEAN_AND_MEAN
#include "RoomExporter.h"
#include "Utils/BinaryWriter.h"
#include "Utils/MemoryStream.h"
#include <Utils/DiskFile.h>
#include <ZRoom/Commands/SetMesh.h>
#include <ZRoom/Commands/SetWind.h>
#include <ZRoom/Commands/SetTimeSettings.h>
#include <ZRoom/Commands/SetSkyboxModifier.h>
#include <ZRoom/Commands/SetSoundSettings.h>
#include <ZRoom/Commands/SetCameraSettings.h>
#include <ZRoom/Commands/SetRoomBehavior.h>
#include <ZRoom/Commands/SetCsCamera.h>
#include <ZRoom/Commands/SetRoomList.h>
#include <ZRoom/Commands/SetCollisionHeader.h>
#include <ZRoom/Commands/SetEntranceList.h>
#include <ZRoom/Commands/SetSpecialObjects.h>
#include <ZRoom/Commands/SetStartPositionList.h>
#include <ZRoom/Commands/SetSkyboxSettings.h>
#include <ZRoom/Commands/SetLightingSettings.h>
#include <ZRoom/Commands/SetLightList.h>
#include <ZRoom/Commands/SetEchoSettings.h>
#include <ZRoom/Commands/SetObjectList.h>
#include <ZRoom/Commands/SetAlternateHeaders.h>
#include "CollisionExporter.h"
#include "DisplayListExporter.h"
#include <libultraship/bridge.h>
#include <Globals.h>
#include <ZRoom/Commands/SetExitList.h>
#include <ZRoom/Commands/SetPathways.h>
#include "TextureExporter.h"
#include "Main.h"
#include <ZRoom/Commands/SetCutscenes.h>
#include "CutsceneExporter.h"
#include <ZRoom/Commands/SetTransitionActorList.h>
#include <ZRoom/Commands/SetCutsceneEntryList.h>
#include <ZRoom/Commands/SetAnimatedMaterialList.h>
#include <ZRoom/Commands/SetMinimapList.h>
#include <ZRoom/Commands/SetMinimapChests.h>
#include "TextureAnimationExporter.h"
#include "PathExporter.h"
#undef FindResource
void OTRExporter_Room::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZRoom* room = (ZRoom*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Room));
writer->Write((uint32_t)room->commands.size());
for (size_t i = 0; i < room->commands.size(); i++)
{
ZRoomCommand* cmd = room->commands[i];
writer->Write((uint32_t)cmd->cmdID);
switch (cmd->cmdID)
{
case RoomCommand::SetTransitionActorList:
{
SetTransitionActorList* cmdTrans = (SetTransitionActorList*)cmd;
writer->Write((uint32_t)cmdTrans->transitionActors.size());
for (const TransitionActorEntry& entry : cmdTrans->transitionActors)
{
writer->Write(entry.frontObjectRoom);
writer->Write(entry.frontTransitionReaction);
writer->Write(entry.backObjectRoom);
writer->Write(entry.backTransitionReaction);
writer->Write(entry.actorNum);
writer->Write(entry.posX);
writer->Write(entry.posY);
writer->Write(entry.posZ);
writer->Write(entry.rotY);
writer->Write(entry.initVar);
}
}
break;
case RoomCommand::SetActorList:
{
SetActorList* cmdSetActorList = (SetActorList*)cmd;
// There are instance of the amount of actors in the file differing from the size listed in the command.
// This can cause issues if we export actors with garbage data, so let's trust the command size
writer->Write((uint32_t)cmdSetActorList->numActors);
for (const auto& entry : cmdSetActorList->actorList->actors)
{
writer->Write(entry.actorNum);
writer->Write(entry.posX);
writer->Write(entry.posY);
writer->Write(entry.posZ);
writer->Write(entry.rotX);
writer->Write(entry.rotY);
writer->Write(entry.rotZ);
writer->Write(entry.params);
}
}
break;
case RoomCommand::SetWind:
{
SetWind* cmdSetWind = (SetWind*)cmd;
writer->Write(cmdSetWind->windWest); // 0x04
writer->Write(cmdSetWind->windVertical); // 0x05
writer->Write(cmdSetWind->windSouth); // 0x06
writer->Write(cmdSetWind->clothFlappingStrength); // 0x07
}
break;
case RoomCommand::SetTimeSettings:
{
SetTimeSettings* cmdTime = (SetTimeSettings*)cmd;
writer->Write(cmdTime->hour); // 0x04
writer->Write(cmdTime->min); // 0x05
writer->Write(cmdTime->unk); // 0x06
}
break;
case RoomCommand::SetSkyboxModifier:
{
SetSkyboxModifier* cmdSkybox = (SetSkyboxModifier*)cmd;
writer->Write(cmdSkybox->disableSky); // 0x04
writer->Write(cmdSkybox->disableSunMoon); // 0x05
}
break;
case RoomCommand::SetEchoSettings:
{
SetEchoSettings* cmdEcho = (SetEchoSettings*)cmd;
writer->Write((uint8_t)cmdEcho->echo); // 0x07
}
break;
case RoomCommand::SetSoundSettings:
{
SetSoundSettings* cmdSound = (SetSoundSettings*)cmd;
writer->Write((uint8_t)cmdSound->reverb); // 0x01
writer->Write(cmdSound->nightTimeSFX); // 0x06
writer->Write(cmdSound->musicSequence); // 0x07
}
break;
case RoomCommand::SetSkyboxSettings:
{
SetSkyboxSettings* cmdSkybox = (SetSkyboxSettings*)cmd;
writer->Write((uint8_t)cmdSkybox->unk1); // 0x01
writer->Write((uint8_t)cmdSkybox->skyboxNumber); // 0x04
writer->Write((uint8_t)cmdSkybox->cloudsType); // 0x05
writer->Write((uint8_t)cmdSkybox->isIndoors); // 0x06
}
break;
case RoomCommand::SetRoomBehavior:
{
SetRoomBehavior* cmdRoom = (SetRoomBehavior*)cmd;
if (Globals::Instance->game == ZGame::MM_RETAIL) {
writer->Write(cmdRoom->gameplayFlags);
writer->Write(cmdRoom->currRoomUnk2);
writer->Write(cmdRoom->currRoomUnk5);
writer->Write(cmdRoom->msgCtxUnk);
writer->Write(cmdRoom->enablePosLights);
writer->Write(cmdRoom->kankyoContextUnkE2);
} else {
writer->Write((uint8_t)cmdRoom->gameplayFlags); // 0x01
writer->Write(cmdRoom->gameplayFlags2); // 0x04
}
}
break;
case RoomCommand::SetCsCamera:
{
SetCsCamera* cmdCsCam = (SetCsCamera*)cmd;
writer->Write((uint32_t)cmdCsCam->cameras.size());
segptr_t arrBase = cmdCsCam->cameras[0].segmentOffset;
for (const auto& c : cmdCsCam->cameras) {
writer->Write(c.type);
writer->Write(c.numPoints);
for (int16_t i = 0; i < c.numPoints; i++) {
writer->Write(cmdCsCam->points[((c.segmentOffset - arrBase) / 6) + i].scalars[0].scalarData.s16);
writer->Write(cmdCsCam->points[((c.segmentOffset - arrBase) / 6) + i].scalars[1].scalarData.s16);
writer->Write(cmdCsCam->points[((c.segmentOffset - arrBase) / 6) + i].scalars[2].scalarData.s16);
}
}
}
break;
case RoomCommand::SetMesh:
{
SetMesh* cmdMesh = (SetMesh*)cmd;
writer->Write((uint8_t)cmdMesh->data); // 0x01
writer->Write(cmdMesh->meshHeaderType);
if (cmdMesh->meshHeaderType == 0 || cmdMesh->meshHeaderType == 2)
{
RoomShapeCullable* poly = (RoomShapeCullable*)cmdMesh->polyType.get();
writer->Write(poly->num);
for (int i = 0; i < poly->num; i++)
WritePolyDList(writer, room, &poly->polyDLists[i]);
}
else if (cmdMesh->meshHeaderType == 1)
{
PolygonType1* poly = (PolygonType1*)cmdMesh->polyType.get();
writer->Write(poly->format);
auto test = (RoomShapeDListsEntry*)&poly->polyDLists[0];
Declaration* dListDeclOpa = poly->parent->GetDeclaration(GETSEGOFFSET(test->opa));
Declaration* dListDeclXlu = poly->parent->GetDeclaration(GETSEGOFFSET(test->xlu));
if (test->opa != 0)
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclOpa->declName.c_str()));
else
writer->Write("");
if (test->xlu != 0)
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclXlu->declName.c_str()));
else
writer->Write("");
if (poly->format == 2)
{
writer->Write((uint32_t)poly->count);
for (int i = 0; i < poly->count; i++)
{
writer->Write(poly->multiList[i].unk_00);
writer->Write(poly->multiList[i].id);
Declaration* bgDecl = poly->parent->GetDeclarationRanged(GETSEGOFFSET(poly->multiList[i].source));
writer->Write(OTRExporter_DisplayList::GetPathToRes(poly->multiList[i].sourceBackground, bgDecl->declName));
writer->Write(poly->multiList[i].unk_0C);
writer->Write(poly->multiList[i].tlut);
writer->Write(poly->multiList[i].width);
writer->Write(poly->multiList[i].height);
writer->Write(poly->multiList[i].fmt);
writer->Write(poly->multiList[i].siz);
writer->Write(poly->multiList[i].mode0);
writer->Write(poly->multiList[i].tlutCount);
}
}
else
{
writer->Write((uint32_t)1);
writer->Write(poly->single.unk_00);
writer->Write(poly->single.id);
Declaration* bgDecl = poly->parent->GetDeclarationRanged(GETSEGOFFSET(poly->single.source));
writer->Write(OTRExporter_DisplayList::GetPathToRes(poly->single.sourceBackground, bgDecl->declName));
writer->Write(poly->single.unk_0C);
writer->Write(poly->single.tlut);
writer->Write(poly->single.width);
writer->Write(poly->single.height);
writer->Write(poly->single.fmt);
writer->Write(poly->single.siz);
writer->Write(poly->single.mode0);
writer->Write(poly->single.tlutCount);
}
if (poly->dlist != 0)
WritePolyDList(writer, room, &poly->polyDLists[0]);
}
}
break;
case RoomCommand::SetCameraSettings:
//case RoomCommand::SetWorldMapVisited: MM command but you can't have 0x19 twice in a switch
{
if (Globals::Instance->game != ZGame::MM_RETAIL) {
SetCameraSettings* cmdCam = (SetCameraSettings*)cmd;
writer->Write((uint8_t)cmdCam->cameraMovement); // 0x01
writer->Write(cmdCam->mapHighlight); // 0x04
}
}
break;
case RoomCommand::SetLightList:
{
SetLightList* cmdLight = (SetLightList*)cmd;
writer->Write((uint32_t)cmdLight->lights.size());
for (size_t i = 0; i < cmdLight->lights.size(); i++)
{
writer->Write(cmdLight->lights[i].type);
writer->Write(cmdLight->lights[i].x);
writer->Write(cmdLight->lights[i].y);
writer->Write(cmdLight->lights[i].z);
writer->Write(cmdLight->lights[i].r);
writer->Write(cmdLight->lights[i].g);
writer->Write(cmdLight->lights[i].b);
writer->Write(cmdLight->lights[i].drawGlow);
writer->Write(cmdLight->lights[i].radius);
}
}
break;
case RoomCommand::SetLightingSettings:
{
SetLightingSettings* cmdLight = (SetLightingSettings*)cmd;
writer->Write((uint32_t)cmdLight->settings.size()); // 0x01
for (const LightingSettings& setting : cmdLight->settings)
{
writer->Write(setting.ambientClrR);
writer->Write(setting.ambientClrG);
writer->Write(setting.ambientClrB);
writer->Write(setting.diffuseClrA_R);
writer->Write(setting.diffuseClrA_G);
writer->Write(setting.diffuseClrA_B);
writer->Write(setting.diffuseDirA_X);
writer->Write(setting.diffuseDirA_Y);
writer->Write(setting.diffuseDirA_Z);
writer->Write(setting.diffuseClrB_R);
writer->Write(setting.diffuseClrB_G);
writer->Write(setting.diffuseClrB_B);
writer->Write(setting.diffuseDirB_X);
writer->Write(setting.diffuseDirB_Y);
writer->Write(setting.diffuseDirB_Z);
writer->Write(setting.fogClrR);
writer->Write(setting.fogClrG);
writer->Write(setting.fogClrB);
writer->Write(setting.unk);
writer->Write(setting.drawDistance);
}
}
break;
case RoomCommand::SetRoomList:
{
SetRoomList* cmdRoom = (SetRoomList*)cmd;
writer->Write((uint32_t)cmdRoom->romfile->numRooms); // 0x01
for (size_t i = 0;i < cmdRoom->romfile->numRooms; i++)
{
//std::string roomName = StringHelper::Sprintf("%s/%s_room_%i", (StringHelper::Split(room->GetName(), "_")[0] + "_scene").c_str(), StringHelper::Split(room->GetName(), "_scene")[0].c_str(), i);
std::string roomName;
if (Globals::Instance->game != ZGame::MM_RETAIL)
roomName = OTRExporter_DisplayList::GetPathToRes(room, StringHelper::Sprintf("%s_room_%i", StringHelper::Split(room->GetName(), "_scene")[0].c_str(), i));
else
{
// Alt headers use the rooms from their parent room. For example we want SPOT00/SPOT00_room_00, not SPOT00/SPOT00Set_00A050_room_00
if (room->zroomType == ZResourceType::AltHeader)
roomName = OTRExporter_DisplayList::GetPathToRes(room, StringHelper::Sprintf("%s_room_%02d", cmd->parent->GetName().c_str(), i));
else
roomName = OTRExporter_DisplayList::GetPathToRes(room, StringHelper::Sprintf("%s_room_%02d", StringHelper::Split(room->GetName(), "_scene")[0].c_str(), i));
}
writer->Write(roomName);
writer->Write(cmdRoom->romfile->rooms[i].virtualAddressStart);
writer->Write(cmdRoom->romfile->rooms[i].virtualAddressEnd);
}
}
break;
case RoomCommand::SetCollisionHeader:
{
SetCollisionHeader* cmdCollHeader = (SetCollisionHeader*)cmd;
Declaration* colHeaderDecl = room->parent->GetDeclaration(cmdCollHeader->segmentOffset);
std::string path = OTRExporter_DisplayList::GetPathToRes(room, colHeaderDecl->declName);
writer->Write(path);
}
break;
case RoomCommand::SetEntranceList:
{
SetEntranceList* cmdEntrance = (SetEntranceList*)cmd;
writer->Write((uint32_t)cmdEntrance->entrances.size());
for (Spawn entry : cmdEntrance->entrances)
{
writer->Write((uint8_t)entry.startPositionIndex);
writer->Write((uint8_t)entry.roomToLoad);
}
}
break;
case RoomCommand::SetSpecialObjects:
{
SetSpecialObjects* cmdSpecObj = (SetSpecialObjects*)cmd;
writer->Write((uint8_t)cmdSpecObj->elfMessage); // 0x01
writer->Write((uint16_t)cmdSpecObj->globalObject); // 0x06
}
break;
case RoomCommand::SetStartPositionList:
{
SetStartPositionList* cmdStartPos = (SetStartPositionList*)cmd;
uint32_t baseStreamEnd = writer->GetStream().get()->GetLength();
writer->Write((uint32_t)cmdStartPos->actors.size()); // 0x01
for (const ActorSpawnEntry& entry : cmdStartPos->actors)
{
writer->Write(entry.actorNum);
writer->Write(entry.posX);
writer->Write(entry.posY);
writer->Write(entry.posZ);
writer->Write(entry.rotX);
writer->Write(entry.rotY);
writer->Write(entry.rotZ);
writer->Write(entry.params);
}
}
break;
case RoomCommand::SetAlternateHeaders:
{
SetAlternateHeaders* cmdHeaders = (SetAlternateHeaders*)cmd;
writer->Write((uint32_t)cmdHeaders->headers.size());
for (size_t i = 0; i < cmdHeaders->headers.size(); i++)
{
uint32_t seg = cmdHeaders->headers[i] & 0xFFFFFFFF;
std::string headerName = "";
bool foundDecl = Globals::Instance->GetSegmentedPtrName(seg, room->parent, "", headerName, res->parent->workerID);
if (headerName == "NULL")
writer->Write("");
else
{
std::string name = OTRExporter_DisplayList::GetPathToRes(room, headerName);
writer->Write(name);
}
}
}
break;
case RoomCommand::SetExitList:
{
SetExitList* cmdExit = (SetExitList*)cmd;
writer->Write((uint32_t)cmdExit->exits.size());
for (size_t i = 0; i < cmdExit->exits.size(); i++)
writer->Write(cmdExit->exits[i]);
}
break;
case RoomCommand::SetObjectList:
{
SetObjectList* cmdSetObjectList = (SetObjectList*)cmd;
writer->Write((uint32_t)cmdSetObjectList->objects.size());
for (size_t i = 0; i < cmdSetObjectList->objects.size(); i++)
writer->Write(cmdSetObjectList->objects[i]);
}
break;
case RoomCommand::SetCutscenes:
{
SetCutscenes* cmdSetCutscenes = (SetCutscenes*)cmd;
std::string listName;
if (Globals::Instance->game == ZGame::MM_RETAIL) {
writer->Seek(-4, SeekOffsetType::Current);
writer->Write((uint32_t)RoomCommand::SetCutscenesMM);
writer->Write(cmdSetCutscenes->numCutscenes);
for (size_t i = 0; i < cmdSetCutscenes->cutsceneEntries.size(); i++) {
Globals::Instance->GetSegmentedPtrName(cmdSetCutscenes->cutsceneEntries[i].segmentPtr, room->parent, "CutsceneData", listName, res->parent->workerID);
std::string fName = OTRExporter_DisplayList::GetPathToRes(room, listName);
writer->Write(fName);
writer->Write(cmdSetCutscenes->cutsceneEntries[i].exit);
writer->Write(cmdSetCutscenes->cutsceneEntries[i].entrance);
writer->Write(cmdSetCutscenes->cutsceneEntries[i].flag);
MemoryStream* csStream = new MemoryStream();
BinaryWriter csWriter = BinaryWriter(csStream);
OTRExporter_Cutscene cs;
ZResource* newCs = res->parent->FindResource(cmdSetCutscenes->cutsceneEntries[i].segmentPtr & 0x00FFFFFF);
cs.Save((ZCutscene*)newCs, "", &csWriter);
AddFile(fName, csStream->ToVector());
}
}
else {
Globals::Instance->GetSegmentedPtrName(cmdSetCutscenes->cmdArg2, room->parent, "CutsceneData", listName, res->parent->workerID);
std::string fName = OTRExporter_DisplayList::GetPathToRes(room, listName);
writer->Write(fName);
MemoryStream* csStream = new MemoryStream();
BinaryWriter csWriter = BinaryWriter(csStream);
OTRExporter_Cutscene cs;
cs.Save(cmdSetCutscenes->cutscenes[0], "", &csWriter);
AddFile(fName, csStream->ToVector());
}
}
break;
case RoomCommand::SetPathways:
{
SetPathways* cmdSetPathways = (SetPathways*)cmd;
writer->Write((uint32_t)cmdSetPathways->pathwayList.pathways.size());
for (size_t i = 0; i < cmdSetPathways->pathwayList.pathways.size(); i++)
{
Declaration* decl = room->parent->GetDeclaration(GETSEGOFFSET(cmdSetPathways->pathwayList.pathways[i].listSegmentAddress));
//std::string path = StringHelper::Sprintf("%s\\%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), decl->varName.c_str());
std::string path = OTRExporter_DisplayList::GetPathToRes(room, decl->declName);
writer->Write(path);
MemoryStream* pathStream = new MemoryStream();
BinaryWriter pathWriter = BinaryWriter(pathStream);
OTRExporter_Path pathExp;
pathExp.Save(&cmdSetPathways->pathwayList, outPath, &pathWriter);
AddFile(path, pathStream->ToVector());
}
}
break;
case RoomCommand::EndMarker:
break;
case RoomCommand::SetActorCutsceneList:
{
SetActorCutsceneList* list = (SetActorCutsceneList*)cmd;
writer->Write((uint32_t)list->cutscenes.size());
for (const auto& e : list->cutscenes) {
writer->Write(e.priority);
writer->Write(e.length);
writer->Write(e.csCamId);
writer->Write(e.scriptIndex);
writer->Write(e.additionalCsId);
writer->Write(e.endSfx);
writer->Write(e.customValue);
writer->Write(e.hudVisibility);
writer->Write(e.endCam);
writer->Write(e.letterboxSize);
}
break;
}
#ifdef GAME_MM
case RoomCommand::SetAnimatedMaterialList: {
SetAnimatedMaterialList* list = (SetAnimatedMaterialList*)cmd;
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmd->cmdArg2, cmd->parent, "AnimatedMaterial", listName,
res->parent->workerID);
listName = OTRExporter_DisplayList::GetPathToRes(room, listName);
writer->Write(listName);
MemoryStream* animatedMatStream = new MemoryStream();
BinaryWriter animatedMatWriter = BinaryWriter(animatedMatStream);
OTRExporter_TextureAnimation texAnim;
texAnim.Save(&list->textureAnimation, outPath, &animatedMatWriter);
AddFile(listName, animatedMatStream->ToVector());
break;
}
#endif
case RoomCommand::SetMinimapList: {
SetMinimapList* list = (SetMinimapList*)cmd;
writer->Write((uint32_t)list->minimaps.size());
writer->Write(list->scale);
for (const auto& m : list->minimaps) {
writer->Write(m.unk0);
writer->Write(m.unk2);
writer->Write(m.unk4);
writer->Write(m.unk6);
writer->Write(m.unk8);
}
break;
}
case RoomCommand::SetMinimapChests: {
SetMinimapChests* chests = (SetMinimapChests*)cmd;
writer->Write((uint32_t)chests->chests.size());
for (const auto& c : chests->chests) {
writer->Write(c.unk0);
writer->Write(c.unk2);
writer->Write(c.unk4);
writer->Write(c.unk6);
writer->Write(c.unk8);
}
break;
}
default:
printf("UNIMPLEMENTED COMMAND: 0x%02X\n", (int)cmd->cmdID);
break;
}
}
}
void OTRExporter_Room::WritePolyDList(BinaryWriter* writer, ZRoom* room, RoomShapeDListsEntry* dlist)
{
writer->Write(dlist->polyType);
switch (dlist->polyType)
{
case 2:
writer->Write(dlist->x);
writer->Write(dlist->y);
writer->Write(dlist->z);
writer->Write(dlist->unk_06);
[[fallthrough]];
default:
//writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(res).c_str(), dListDeclOpa->varName.c_str()));
if (dlist->opaDList != nullptr)
{
auto opaDecl = room->parent->GetDeclaration(GETSEGOFFSET(dlist->opaDList->GetRawDataIndex()));
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), opaDecl->declName.c_str()));
}
else
writer->Write("");
if (dlist->xluDList != nullptr)
{
auto xluDecl = room->parent->GetDeclaration(GETSEGOFFSET(dlist->xluDList->GetRawDataIndex()));
writer->Write(StringHelper::Sprintf("%s/%s", OTRExporter_DisplayList::GetParentFolderName(room).c_str(), xluDecl->declName.c_str()));
}
else
writer->Write("");
break;
}
}

View File

@@ -0,0 +1,15 @@
#pragma once
#define NO_GDI
#define WIN32_LEAN_AND_MEAN
#include "ZResource.h"
#include "Exporter.h"
#include "ZRoom/ZRoom.h"
class RoomShapeDListsEntry;
class OTRExporter_Room : public OTRExporter
{
public:
void WritePolyDList(BinaryWriter* writer, ZRoom* room, RoomShapeDListsEntry* dlist);
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,39 @@
#include "SkeletonExporter.h"
#include <libultraship/bridge.h>
#include <Globals.h>
#include "DisplayListExporter.h"
void OTRExporter_Skeleton::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZSkeleton* skel = (ZSkeleton*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Skeleton));
writer->Write((uint8_t)skel->type);
writer->Write((uint8_t)skel->limbType);
writer->Write((uint32_t)skel->limbCount);
writer->Write((uint32_t)skel->dListCount);
writer->Write((uint8_t)skel->limbsTable->limbType);
writer->Write((uint32_t)skel->limbsTable->count);
for (size_t i = 0; i < skel->limbsTable->count; i++)
{
Declaration* skelDecl = skel->parent->GetDeclarationRanged(GETSEGOFFSET(skel->limbsTable->limbsAddresses[i]));
std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(skel->limbsTable->limbsAddresses[i], skel->parent, "", name, res->parent->workerID);
if (foundDecl)
{
if (name.at(0) == '&')
name.erase(0, 1);
writer->Write(OTRExporter_DisplayList::GetPathToRes(res, name));
}
else
{
writer->Write("");
}
}
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "ZResource.h"
#include "ZTexture.h"
#include "ZDisplayList.h"
#include "ZSkeleton.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Skeleton : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,180 @@
#include "SkeletonLimbExporter.h"
#include "DisplayListExporter.h"
#include <libultraship/bridge.h>
#include <Globals.h>
void OTRExporter_SkeletonLimb::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZLimb* limb = (ZLimb*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_SkeletonLimb));
writer->Write((uint8_t)limb->type);
writer->Write((uint8_t)limb->skinSegmentType);
if (limb->skinSegmentType == ZLimbSkinType::SkinType_Normal && limb->type == ZLimbType::Skin)
{
auto childDecl = limb->parent->GetDeclaration(GETSEGOFFSET(limb->skinSegment));
if (childDecl != nullptr)
writer->Write(OTRExporter_DisplayList::GetPathToRes(limb, childDecl->declName));
else
writer->Write("");
}
else
{
writer->Write("");
}
writer->Write((uint16_t)limb->segmentStruct.totalVtxCount);
writer->Write((uint32_t)limb->segmentStruct.limbModifications_arr.size());
for (auto item : limb->segmentStruct.limbModifications_arr)
{
writer->Write(item.unk_4);
writer->Write((uint32_t)item.skinVertices_arr.size());
for (auto item2 : item.skinVertices_arr)
{
writer->Write(item2.index);
writer->Write(item2.s);
writer->Write(item2.t);
writer->Write(item2.normX);
writer->Write(item2.normY);
writer->Write(item2.normZ);
writer->Write(item2.alpha);
}
writer->Write((uint32_t)item.limbTransformations_arr.size());
for (auto item2 : item.limbTransformations_arr)
{
writer->Write(item2.limbIndex);
writer->Write(item2.x);
writer->Write(item2.y);
writer->Write(item2.z);
writer->Write(item2.scale);
}
}
if (limb->segmentStruct.dlist != SEGMENTED_NULL)
{
auto skinGfxDecl = limb->parent->GetDeclaration(GETSEGOFFSET(limb->segmentStruct.dlist));
if (skinGfxDecl != nullptr)
{
writer->Write(OTRExporter_DisplayList::GetPathToRes(limb, skinGfxDecl->declName));
}
else
{
writer->Write("");
}
}
else
{
writer->Write("");
}
writer->Write(limb->legTransX);
writer->Write(limb->legTransY);
writer->Write(limb->legTransZ);
writer->Write(limb->rotX);
writer->Write(limb->rotY);
writer->Write(limb->rotZ);
if (limb->childPtr != 0)
{
std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->childPtr, limb->parent, "", name, res->parent->workerID);
if (foundDecl)
{
if (name.at(0) == '&')
name.erase(0, 1);
writer->Write(OTRExporter_DisplayList::GetPathToRes(limb, name));
}
else
{
writer->Write("");
}
}
else
{
writer->Write("");
}
if (limb->siblingPtr != 0)
{
std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->siblingPtr, limb->parent, "", name, res->parent->workerID);
if (foundDecl)
{
if (name.at(0) == '&')
name.erase(0, 1);
writer->Write(OTRExporter_DisplayList::GetPathToRes(limb, name));
}
else
{
writer->Write("");
}
}
else
{
writer->Write("");
}
if (limb->dListPtr != 0)
{
std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->dListPtr, limb->parent, "", name, res->parent->workerID);
if (foundDecl)
{
if (name.at(0) == '&')
name.erase(0, 1);
ZFile* assocFile = Globals::Instance->GetSegment(GETSEGNUM(limb->dListPtr), res->parent->workerID);
writer->Write(OTRExporter_DisplayList::GetPathToRes(assocFile->resources[0], name));
}
else
{
writer->Write("");
}
}
else
{
writer->Write("");
}
if (limb->dList2Ptr != 0)
{
std::string name;
bool foundDecl = Globals::Instance->GetSegmentedPtrName(limb->dList2Ptr, limb->parent, "", name, res->parent->workerID);
if (foundDecl)
{
if (name.at(0) == '&')
name.erase(0, 1);
ZFile* assocFile = Globals::Instance->GetSegment(GETSEGNUM(limb->dList2Ptr), res->parent->workerID);
writer->Write(OTRExporter_DisplayList::GetPathToRes(assocFile->resources[0], name));
}
else
{
writer->Write("");
}
}
else
{
writer->Write("");
}
writer->Write(limb->transX);
writer->Write(limb->transY);
writer->Write(limb->transZ);
writer->Write(limb->childIndex);
writer->Write(limb->siblingIndex);
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "ZResource.h"
#include "ZTexture.h"
#include "ZDisplayList.h"
#include "ZSkeleton.h"
#include "ZLimb.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_SkeletonLimb : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,19 @@
#include "TextExporter.h"
#include "../ZAPD/ZFile.h"
void OTRExporter_Text::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZText* txt = (ZText*)res;
WriteHeader(txt, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::SOH_Text));
writer->Write((uint32_t)txt->messages.size());
for (size_t i = 0; i < txt->messages.size(); i++)
{
writer->Write(txt->messages[i].id);
writer->Write(txt->messages[i].textboxType);
writer->Write(txt->messages[i].textboxYPos);
writer->Write(txt->messages[i].msg);
}
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "ZResource.h"
#include "ZText.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Text : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,25 @@
#ifdef GAME_MM
#include "TextMMExporter.h"
#include "../ZAPD/ZFile.h"
void OTRExporter_TextMM::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZTextMM* txt = (ZTextMM*)res;
WriteHeader(txt, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::TSH_TextMM));
writer->Write((uint32_t)txt->messages.size());
for (size_t i = 0; i < txt->messages.size(); i++)
{
writer->Write(txt->messages[i].id);
writer->Write(txt->messages[i].textboxType);
writer->Write(txt->messages[i].textboxYPos);
writer->Write(txt->messages[i].icon);
writer->Write(txt->messages[i].nextMessageID);
writer->Write(txt->messages[i].firstItemCost);
writer->Write(txt->messages[i].secondItemCost);
writer->Write(txt->messages[i].msg);
}
}
#endif

View File

@@ -0,0 +1,13 @@
#pragma once
#ifdef GAME_MM
#include "ZResource.h"
#include "ZTextMM.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_TextMM : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};
#endif

View File

@@ -0,0 +1,126 @@
#ifdef GAME_MM
#define NO_GDI
#define WIN32_LEAN_AND_MEAN
#include "ZFile.h"
#include <Globals.h>
#include "TextureAnimationExporter.h"
#include "DisplayListExporter.h"
#include <spdlog/spdlog.h>
#undef FindResource
void OTRExporter_TextureAnimation::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
auto* anim = (ZTextureAnimation*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(SOH::ResourceType::TSH_TexAnim), 0);
writer->Write((uint32_t)anim->entries.size());
for (const auto& e : anim->entries) {
auto* params = (ZTextureAnimationParams*)res->parent->FindResource(Seg2Filespace(e.paramsPtr, res->parent->baseAddress));
writer->Write(e.segment);
writer->Write((int16_t)e.type);
switch ((TextureAnimationParamsType)e.type) {
case TextureAnimationParamsType::SingleScroll:
case TextureAnimationParamsType::DualScroll: {
auto* scrollParams = (TextureScrollingParams*)params;
writer->Write(scrollParams->rows[0].xStep);
writer->Write(scrollParams->rows[0].yStep);
writer->Write(scrollParams->rows[0].width);
writer->Write(scrollParams->rows[0].height);
if (scrollParams->count == 2) {
writer->Write(scrollParams->rows[1].xStep);
writer->Write(scrollParams->rows[1].yStep);
writer->Write(scrollParams->rows[1].width);
writer->Write(scrollParams->rows[1].height);
}
break;
}
case TextureAnimationParamsType::ColorChange:
case TextureAnimationParamsType::ColorChangeLERP:
case TextureAnimationParamsType::ColorChangeLagrange: {
auto* colorParams = (TextureColorChangingParams*)params;
writer->Write(colorParams->animLength);
writer->Write(colorParams->colorListCount);
if (colorParams->frameDataListAddress != 0) { // NULL
writer->Write((uint16_t)colorParams->frameDataList.size());
for (const auto f : colorParams->frameDataList) {
writer->Write(f);
}
} else {
writer->Write((uint16_t)0);
}
if (colorParams->primColorListAddress != 0) { // NULL
writer->Write((uint16_t)colorParams->primColorList.size());
for (const auto prim : colorParams->primColorList) {
writer->Write(prim.r);
writer->Write(prim.g);
writer->Write(prim.b);
writer->Write(prim.a);
writer->Write(prim.lodFrac);
}
} else {
writer->Write((uint16_t)0);
}
if (colorParams->envColorListAddress != 0) { // NULL
writer->Write((uint16_t)colorParams->envColorList.size());
for (const auto env : colorParams->envColorList) {
writer->Write(env.r);
writer->Write(env.g);
writer->Write(env.b);
writer->Write(env.a);
}
} else {
writer->Write((uint16_t)0);
}
break;
}
case TextureAnimationParamsType::TextureCycle: {
auto* cycleParams = (TextureCyclingParams*)params;
writer->Write(cycleParams->cycleLength);
// Texture list may or may not be the same size as the index list, so we need to write the size of the list for the importer
writer->Write((uint32_t)cycleParams->textureList.size());
for (const auto t : cycleParams->textureList) {
std::string name;
bool found = Globals::Instance->GetSegmentedPtrName(GETSEGOFFSET(t), res->parent, "", name, res->parent->workerID);
if (!found) {
ZTexture* tex = (ZTexture*)res->parent->FindResource(t & 0x00FFFFFF);
if (tex != nullptr) {
name = tex->GetName();
found = true;
}
}
if (found)
{
if (name.at(0) == '&')
name.erase(0, 1);
writer->Write(OTRExporter_DisplayList::GetPathToRes(res, name));
}
else
{
spdlog::error("Texture not found: 0x{:X}", t);
writer->Write("");
}
}
for (const auto index : cycleParams->textureIndexList) {
writer->Write(index);
}
break;
}
case TextureAnimationParamsType::Empty: {
writer->Write(SEGMENTED_NULL);
break;
}
}
}
}
#endif

View File

@@ -0,0 +1,15 @@
#pragma once
#ifdef GAME_MM
#include "ZResource.h"
#include "ZTextureAnimation.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_TextureAnimation : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};
#endif

View File

@@ -0,0 +1,32 @@
#include "TextureExporter.h"
#include "../ZAPD/ZFile.h"
void OTRExporter_Texture::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZTexture* tex = (ZTexture*)res;
WriteHeader(tex, outPath, writer, static_cast<uint32_t>(Fast::ResourceType::Texture));
auto start = std::chrono::steady_clock::now();
//printf("Exporting Texture %s\n", tex->GetName().c_str());
writer->Write((uint32_t)tex->GetTextureType());
writer->Write((uint32_t)tex->GetWidth());
writer->Write((uint32_t)tex->GetHeight());
writer->Write((uint32_t)tex->GetRawDataSize());
if (tex->parent != nullptr) {
auto data = tex->parent->GetRawData();
writer->Write((char*)data.data() + tex->GetRawDataIndex(), tex->GetRawDataSize());
}
auto end = std::chrono::steady_clock::now();
size_t diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
//printf("Exported Texture %s in %zums\n", tex->GetName().c_str(), diff);
//if (diff > 2)
//printf("Export took %lms\n", diff);
}

View File

@@ -0,0 +1,12 @@
#pragma once
#include "ZResource.h"
#include "ZTexture.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Texture : public OTRExporter
{
public:
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,29 @@
#include "VersionInfo.h"
#include <libultraship/bridge.h>
#ifdef GAME_MM
#include "../../mm/2s2h/resource/type/2shResourceType.h"
#elif GAME_OOT
#include "../../soh/soh/resource/type/SohResourceType.h"
#endif
std::map<uint32_t, uint32_t> resourceVersions;
void InitVersionInfo()
{
resourceVersions = std::map<uint32_t, uint32_t> {
{ static_cast<uint32_t>(SOH::ResourceType::SOH_Animation), 0 },
{ static_cast<uint32_t>(Fast::ResourceType::Texture), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_PlayerAnimation), 0 },
{ static_cast<uint32_t>(Fast::ResourceType::DisplayList), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_Room), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_CollisionHeader), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_Skeleton), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_SkeletonLimb), 0 },
{ static_cast<uint32_t>(Fast::ResourceType::Matrix), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_Path), 0 },
{ static_cast<uint32_t>(Fast::ResourceType::Vertex), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_Cutscene), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_Array), 0 },
{ static_cast<uint32_t>(SOH::ResourceType::SOH_Text), 0 },
{ static_cast<uint32_t>(Ship::ResourceType::Blob), 0 },
};
}

View File

@@ -0,0 +1,8 @@
#pragma once
#include <map>
#include <vector>
#include <ship/resource/Resource.h>
#include <fast/resource/ResourceType.h>
extern std::map<uint32_t, uint32_t> resourceVersions;

View File

@@ -0,0 +1,44 @@
#include "VtxExporter.h"
#include <libultraship/bridge.h>
#include "VersionInfo.h"
void OTRExporter_Vtx::SaveArr(ZResource* res, const fs::path& outPath, const std::vector<ZResource*>& vec, BinaryWriter* writer)
{
WriteHeader(res, outPath, writer, static_cast<uint32_t>(Fast::ResourceType::Vertex));
for (auto& res: vec) {
ZVtx* vtx = (ZVtx*)res;
writer->Write(vtx->x);
writer->Write(vtx->y);
writer->Write(vtx->z);
writer->Write(vtx->flag);
writer->Write(vtx->s);
writer->Write(vtx->t);
writer->Write(vtx->r);
writer->Write(vtx->g);
writer->Write(vtx->b);
writer->Write(vtx->a);
}
}
void OTRExporter_Vtx::Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer)
{
ZVtx* vtx = (ZVtx*)res;
WriteHeader(res, outPath, writer, static_cast<uint32_t>(Fast::ResourceType::Vertex));
writer->Write((uint32_t)1); //Yes I'm hard coding it to one, it *should* be fine.
writer->Write(vtx->x);
writer->Write(vtx->y);
writer->Write(vtx->z);
writer->Write(vtx->flag);
writer->Write(vtx->s);
writer->Write(vtx->t);
writer->Write(vtx->r);
writer->Write(vtx->g);
writer->Write(vtx->b);
writer->Write(vtx->a);
}

View File

@@ -0,0 +1,13 @@
#pragma once
#include "ZResource.h"
#include "ZVtx.h"
#include "Exporter.h"
#include <Utils/BinaryWriter.h>
class OTRExporter_Vtx : public OTRExporter
{
public:
void SaveArr(ZResource* res, const fs::path& outPath, const std::vector<ZResource*>&, BinaryWriter* writer);
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
};

View File

@@ -0,0 +1,32 @@
#ifndef COMMAND_MACROS_BASE_H
#define COMMAND_MACROS_BASE_H
/**
* Command Base macros intended for use in designing of more specific command macros
* Each macro packs bytes (B), halfwords (H) and words (W, for consistency) into a single word
*/
#define _SHIFTL(v, s, w) \
((unsigned int) (((unsigned int)(v) & ((0x01 << (w)) - 1)) << (s)))
#define _SHIFTR(v, s, w) \
((unsigned int)(((unsigned int)(v) >> (s)) & ((0x01 << (w)) - 1)))
//#define CMD_BBBB(a, b, c, d) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 8, 8) | _SHIFTL(d, 0, 8))
#define CMD_BBBB(a, b, c, d) (_SHIFTL(d, 24, 8) | _SHIFTL(c, 16, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(a, 0, 8))
//#define CMD_BBH(a, b, c) (_SHIFTL(a, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(c, 0, 16))
#define CMD_BBH(a, b, c) (_SHIFTL(a, 0, 8) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 16, 16))
//#define CMD_HBB(a, b, c) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 8, 8) | _SHIFTL(c, 0, 8))
#define CMD_HBB(a, b, c) (_SHIFTL(c, 24, 8) | _SHIFTL(b, 16, 8) | _SHIFTL(a, 0, 16))
//#define CMD_HH(a, b) (_SHIFTL(a, 16, 16) | _SHIFTL(b, 0, 16))
#define CMD_HH(a, b) (_SHIFTL(b, 16, 16) | _SHIFTL(a, 0, 16))
#define CMD_W(a) (a)
#define CMD_F(a) {(a)}
#define CMD_PTR(a) (u32)(a)
#endif

View File

@@ -0,0 +1,290 @@
#ifndef Z64CUTSCENE_H
#define Z64CUTSCENE_H
#if 0
#include <libultraship/libultra.h>
typedef struct {
/* 0x00 */ u16 entrance; // entrance index upon which the cutscene should trigger
/* 0x02 */ u8 ageRestriction; // 0 for adult only, 1 for child only, 2 for both ages
/* 0x03 */ u8 flag; // eventChkInf flag bound to the entrance cutscene
/* 0x04 */ void* segAddr; // segment offset location of the cutscene
} EntranceCutscene; // size = 0x8
typedef struct {
/* 0x00 */ s8 continueFlag;
/* 0x01 */ s8 cameraRoll;
/* 0x02 */ u16 nextPointFrame;
/* 0x04 */ f32 viewAngle; // in degrees
/* 0x08 */ Vec3s pos;
} CutsceneCameraPoint; // size = 0x10
typedef struct {
/* 0x00 */ Vec3f at;
/* 0x0C */ Vec3f eye;
/* 0x18 */ s16 roll;
/* 0x1A */ s16 fov;
} CutsceneCameraAngle; // size = 0x1C
typedef struct {
/* 0x0 */ CutsceneCameraPoint* atPoints;
/* 0x4 */ CutsceneCameraPoint* eyePoints;
/* 0x8 */ s16 relativeToPlayer;
} CutsceneCameraMove; // size = 0xC
typedef struct {
/* 0x00 */ u16 base;
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
} CsCmdBase; // size = 0x6
typedef struct {
/* 0x00 */ u8 unk_00;
/* 0x01 */ u8 setting;
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
} CsCmdEnvLighting; // size = 0x6
typedef struct {
/* 0x00 */ u8 unk_00;
/* 0x01 */ u8 sequence;
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
} CsCmdMusicChange; // size = 0x6
typedef struct {
/* 0x00 */ u16 type;
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
} CsCmdMusicFade; // size = 0x6
typedef struct {
/* 0x00 */ u16 unk_00;
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
/* 0x06 */ u8 unk_06;
/* 0x07 */ u8 unk_07;
/* 0x08 */ u8 unk_08;
} CsCmdUnknown9; // size = 0xA
typedef struct {
/* 0x00 */ u16 unk_00;
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
/* 0x06 */ u8 hour;
/* 0x07 */ u8 minute;
} CsCmdDayTime; // size = 0x8
typedef struct {
/* 0x00 */ u16 base;
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
/* 0x06 */ u16 type;
/* 0x08 */ u16 textId1;
/* 0x0A */ u16 textId2;
} CsCmdTextbox; // size = 0xC
typedef struct {
/* 0x00 */ u16 action; // "dousa"
/* 0x02 */ u16 startFrame;
/* 0x04 */ u16 endFrame;
union {
/* 0x06 */ Vec3s rot;
/* 0x06 */ Vec3us urot;
};
/* 0x0C */ Vec3i startPos;
/* 0x18 */ Vec3i endPos;
/* 0x24 */ Vec3i normal;
} CsCmdActorAction; // size = 0x30
#endif
typedef enum {
CS_STATE_IDLE,
CS_STATE_SKIPPABLE_INIT,
CS_STATE_SKIPPABLE_EXEC,
CS_STATE_UNSKIPPABLE_INIT,
CS_STATE_UNSKIPPABLE_EXEC
} CutsceneState;
typedef enum {
CS_CMD_00 = 0x0000,
CS_CMD_CAM_EYE = 0x0001,
CS_CMD_CAM_AT = 0x0002,
CS_CMD_MISC = 0x0003,
CS_CMD_SET_LIGHTING = 0x0004,
CS_CMD_CAM_EYE_REL_TO_PLAYER = 0x0005,
CS_CMD_CAM_AT_REL_TO_PLAYER = 0x0006,
CS_CMD_07 = 0x0007,
CS_CMD_08 = 0x0008,
CS_CMD_09 = 0x0009,
CS_CMD_TEXTBOX = 0x0013,
CS_CMD_SET_PLAYER_ACTION = 0x000A,
CS_CMD_SET_ACTOR_ACTION_1 = 0x000F,
CS_CMD_SET_ACTOR_ACTION_2 = 0x000E,
CS_CMD_SET_ACTOR_ACTION_3 = 0x0019,
CS_CMD_SET_ACTOR_ACTION_4 = 0x001D,
CS_CMD_SET_ACTOR_ACTION_5 = 0x001E,
CS_CMD_SET_ACTOR_ACTION_6 = 0x002C,
CS_CMD_SET_ACTOR_ACTION_7 = 0x001F,
CS_CMD_SET_ACTOR_ACTION_8 = 0x0031,
CS_CMD_SET_ACTOR_ACTION_9 = 0x003E,
CS_CMD_SET_ACTOR_ACTION_10 = 0x008F,
CS_CMD_SCENE_TRANS_FX = 0x002D,
CS_CMD_NOP = 0x000B,
CS_CMD_PLAYBGM = 0x0056,
CS_CMD_STOPBGM = 0x0057,
CS_CMD_FADEBGM = 0x007C,
CS_CMD_SETTIME = 0x008C,
CS_CMD_TERMINATOR = 0x03E8,
CS_CMD_END = 0xFFFF
} CutsceneCmd;
/**
* Special type for blocks of cutscene data, asm-processor checks
* arrays for CutsceneData type and converts floats within the array
* to their IEEE-754 representation. The array must close with };
* on its own line.
*
* Files that contain this type that are included in other C files
* must include an 'EARLY' qualifier to inform asm-processor that it
* must recursively process that include.
*
* Example: #include "file.c" EARLY
*/
typedef union CutsceneData {
int i;
float f;
short s[2];
char b[4];
} CutsceneData;
#define CS_CMD_CONTINUE 0
#define CS_CMD_STOP -1
// TODO confirm correctness, clarify names
typedef enum {
/* 0x00 */ INVALID_DESTINATION_0,
/* 0x01 */ CUTSCENE_MAP_GANON_HORSE,
/* 0x02 */ CUTSCENE_MAP_THREE_GODESSES_POST_DEKU_TREE,
/* 0x03 */ GERUDO_VALLEY_DIN,
/* 0x04 */ DEATH_MOUNTAIN_TRAIL_NAYRU,
/* 0x05 */ KOKIRI_FOREST_FARORE,
/* 0x06 */ CUTSCENE_MAP_TRIFORCE_CREATION,
/* 0x07 */ KOKIRI_FOREST_RECEIVE_KOKIRI_EMERALD,
/* 0x08 */ TEMPLE_OF_TIME_AFTER_USE_MS,
/* 0x09 */ GERUDO_VALLEY_DIN_2,
/* 0x0A */ LINKS_HOUSE_INTRO,
/* 0x0B */ KOKIRI_FOREST_INTRO,
/* 0x0C */ DEATH_MOUNTAIN_TRAIL_AFTER_GORON_RUBY,
/* 0x0D */ ZORAS_FOUNTAIN_AFTER_ZORAS_SAPPHIRE,
/* 0x0E */ KOKIRI_FOREST_AFTER_KOKIRI_EMERALD,
/* 0x0F */ TEMPLE_OF_TIME_KOKIRI_EMERALD, //unused
/* 0x10 */ TEMPLE_OF_TIME_GORON_RUBY, //unused
/* 0x11 */ TEMPLE_OF_TIME_ZORAS_SAPPHIRE, //unused
/* 0x12 */ TEMPLE_OF_TIME_AFTER_USE_MS_FIRST,
/* 0x13 */ DEATH_MOUNTAIN_TRAIL_AFTER_INTRO,
/* 0x14 */ INVALID_DESTINATION_14,
/* 0x15 */ LAKE_HYLIA_WATER_RISES,
/* 0x16 */ DESERT_COLOSSUS_REQUIEM,
/* 0x17 */ CUTSCENE_MAP_CURSE_YOU,
/* 0x18 */ JABU_JABU_INTRO,
/* 0x19 */ CHAMBER_OF_SAGES_LIGHT_MEDALLION,
/* 0x1A */ TEMPLE_OF_TIME_KOKIRI_EMERALD_2, //duplicate of 0x000F
/* 0x1B */ TEMPLE_OF_TIME_GORON_RUBY_2, //duplicate of 0x0010
/* 0x1C */ TEMPLE_OF_TIME_ZORAS_SAPPHIRE_2, //duplicate of 0x0011
/* 0x1D */ CHAMBER_OF_SAGES_FOREST_MEDALLION,
/* 0x1E */ CHAMBER_OF_SAGES_FIRE_MEDALLION,
/* 0x1F */ CHAMBER_OF_SAGES_WATER_MEDALLION,
/* 0x20 */ HYRULE_FIELD_FLASHBACK, //lacs part 4
/* 0x21 */ HYRULE_FIELD_AFTER_LAKE_HYLIA_OWL,
/* 0x22 */ CUTSCENE_MAP_GANON_AFTER_USE_MS,
/* 0x23 */ HYRULE_FIELD_INTRO_ZELDA_ESCAPE,
/* 0x24 */ INVALID_DESTINATION_24,
/* 0x25 */ INVALID_DESTINATION_25,
/* 0x26 */ CUTSCENE_MAP_SHEIKAH_LEGEND, //lacs part 2
/* 0x27 */ TEMPLE_OF_TIME_ZELDA_REVEAL, //lacs part 3
/* 0x28 */ TEMPLE_OF_TIME_GET_LIGHT_ARROWS, //lacs part 5
/* 0x29 */ LAKE_HYLIA_AFTER_BLUE_WARP,
/* 0x2A */ KAKARIKO_VILLAGE_DRAIN_WELL,
/* 0x2B */ WINDMILL_AFTER_DRAIN_WELL,
/* 0x2C */ TEMPLE_OF_TIME_AFTER_DOOR_OF_TIME_OPENS,
/* 0x2D */ INVALID_DESTINATION_2D,
/* 0x2E */ TEMPLE_OF_TIME_AFTER_USE_MS_FIRST_2, // duplicate of 0x0012
/* 0x2F */ KAKARIKO_VILLAGE_NOCTURNE_PART_2,
/* 0x30 */ DESERT_COLOSSUS_AFTER_REQUIEM,
/* 0x31 */ TEMPLE_OF_TIME_AFTER_LIGHT_ARROWS,
/* 0x32 */ KAKARIKO_VILLAGE_AFTER_NOCTURNE,
/* 0x33 */ HYRULE_FIELD_IMPA_ESCORT_CS,
/* 0x34 */ TEMPLE_OF_TIME_SONG_OF_TIME,
/* 0x35 */ HYRULE_FIELD_AFTER_SONG_OF_TIME,
/* 0x36 */ GERUDO_VALLEY_CREDITS,
/* 0x37 */ GERUDO_FORTRESS_CREDITS,
/* 0x38 */ KAKARIKO_VILLAGE_CREDITS,
/* 0x39 */ DEATH_MOUNTAIN_TRAIL_CREDITS_1,
/* 0x3A */ GORON_CITY_CREDITS, // unused?
/* 0x3B */ LAKE_HYLIA_CREDITS,
/* 0x3C */ ZORAS_FOUNTAIN_CREDITS, // unused
/* 0x3D */ ZORAS_DOMAIN_CREDITS,
/* 0x3E */ KOKIRI_FOREST_CREDITS_1,
/* 0x3F */ KOKIRI_FOREST_CREDITS_2,
/* 0x40 */ HYRULE_FIELD_CREDITS,
/* 0x41 */ LON_LON_RANCH_CREDITS_1,
/* 0x42 */ KAKARIKO_VILLAGE_AFTER_TRAIL_OWL,
/* 0x43 */ HTRULE_FIELD_UNUSED_ENTRANCE,
/* 0x44 */ CUTSCENE_MAP_FIRE,
/* 0x45 */ KOKIRI_FOREST_POST_FOREST_MEDALLION,
/* 0x46 */ DEATH_MOUNTAIN_TRAIL_CREDITS_2,
/* 0x47 */ TEMPLE_OF_TIME_CREDITS,
/* 0x48 */ ZELDAS_COURTYARD_CREDITS,
/* 0x49 */ LON_LON_RANCH_CREDITS_1_2, // duplicate of 0x0041
/* 0x4A */ LON_LON_RANCH_CREDITS_2,
/* 0x4B */ LON_LON_RANCH_CREDITS_3,
/* 0x4C */ LON_LON_RANCH_CREDITS_4,
/* 0x4D */ LON_LON_RANCH_CREDITS_5,
/* 0x4E */ LON_LON_RANCH_CREDITS_6,
/* 0x4F */ LON_LON_RANCH_NO_CS_1,
/* 0x50 */ LON_LON_RANCH_NO_CS_2,
/* 0x51 */ LON_LON_RANCH_NO_CS_3,
/* 0x52 */ LON_LON_RANCH_NO_CS_4,
/* 0x53 */ LON_LON_RANCH_NO_CS_5,
/* 0x54 */ LON_LON_RANCH_NO_CS_6,
/* 0x55 */ LON_LON_RANCH_NO_CS_7,
/* 0x56 */ LON_LON_RANCH_NO_CS_8,
/* 0x57 */ LON_LON_RANCH_NO_CS_9,
/* 0x58 */ LON_LON_RANCH_NO_CS_10,
/* 0x59 */ LON_LON_RANCH_NO_CS_11,
/* 0x5A */ LON_LON_RANCH_NO_CS_12,
/* 0x5B */ LON_LON_RANCH_NO_CS_13,
/* 0x5C */ LON_LON_RANCH_NO_CS_14,
/* 0x5D */ LON_LON_RANCH_NO_CS_15,
/* 0x5E */ LON_LON_RANCH_NO_CS_EPONAS_SONG,
/* 0x5F */ CONDITIONAL_DESTINATION, // TODO more descriptive name?
/* 0x60 */ DESERT_COLOSSUS_SPIRIT_BLUE_WARP,
/* 0x61 */ GRAVEYARD_AFTER_SHADOW_BLUE_WARP,
/* 0x62 */ DEATH_MOUNTAIN_CRATER_AFTER_FIRE_BLUE_WARP,
/* 0x63 */ SACRED_FOREST_MEADOW_AFTER_FOREST_BLUE_WARP,
/* 0x64 */ KOKIRI_FOREST_AFTER_FOREST_BLUE_WARP,
/* 0x65 */ DESERT_COLOSSUS_AFTER_SILVER_GAUNTLETS,
/* 0x66 */ TEMPLE_OF_TIME_FRONT_OF_PEDESTAL,
/* 0x67 */ HYRULE_FIELD_TITLE_SCREEN,
/* 0x68 */ SPIRIT_TEMPLE_BOSS_TITLE_SCREEN,
/* 0x69 */ GRAVEYARD_SUNS_SONG,
/* 0x6A */ ROYAL_FAMILYS_TOMB_SUNS_SONG,
/* 0x6B */ GANONS_CASTLE_AFTER_FOREST_TRIAL,
/* 0x6C */ GANONS_CASTLE_AFTER_WATER_TRIAL,
/* 0x6D */ GANONS_CASTLE_AFTER_SHADOW_TRIAL,
/* 0x6E */ GANONS_CASTLE_AFTER_FIRE_TRIAL,
/* 0x6F */ GANONS_CASTLE_AFTER_LIGHT_TRIAL,
/* 0x70 */ GANONS_CASTLE_AFTER_SPIRIT_TRIAL,
/* 0x71 */ GANONS_CASTLE_DISPEL_BARRIER_IF_CONDITIONS,
/* 0x72 */ HYRULE_FIELD_INTRO,
/* 0x73 */ HYRULE_FIELD_AFTER_IMPA_ESCORT,
/* 0x74 */ DESERT_COLOSSUS_SPIRIT_BLUE_WARP_2,
/* 0x75 */ HYRULE_FIELD_SKY,
/* 0x76 */ GANON_BATTLE_TOWER_COLLAPSE,
/* 0x77 */ ZELDAS_COURTYARD_RECEIVE_LETTER
} CutsceneTerminatorDestination;
#endif

View File

@@ -0,0 +1,448 @@
#ifndef Z64CUTSCENE_COMMANDS_H
#define Z64CUTSCENE_COMMANDS_H
#include "command_macros_base.h"
#include "z64cutscene.h"
/**
* ARGS
* s32 totalEntries (e), s32 endFrame (n)
* FORMAT
* eeeeeeee nnnnnnnn
* size = 0x8
*/
#define CS_BEGIN_CUTSCENE(totalEntries, endFrame) CMD_W(totalEntries), CMD_W(endFrame)
/**
* ARGS
* s16 startFrame (s), s16 endFrame (e)
* FORMAT
* 00000001 0001ssss eeee0000
* size = 0xC
*/
#define CS_CAM_POS_LIST CS_CAM_EYE_LIST
#define CS_CAM_EYE_LIST(startFrame, endFrame) \
CS_CMD_CAM_EYE, CMD_HH(0x0001, startFrame), CMD_HH(endFrame, 0x0000)
/**
* ARGS
* s8 continueFlag (c), s8 roll (r), s16 frame (f), f32 viewAngle (a),
* s16 xPos (x), s16 yPos (y), s16 zPos (z)
* FORMAT
* Capital U is Unused
* ccrrffff aaaaaaaa xxxxyyyy zzzzUUUU
* size = 0x10
*/
#define CS_CAM_POS CS_CAM_EYE
#define CS_CAM_EYE(continueFlag, roll, frame, viewAngle, xPos, yPos, zPos, unused) \
CMD_BBH(continueFlag, roll, frame), CMD_F(viewAngle), CMD_HH(xPos, yPos), CMD_HH(zPos, unused)
/**
* ARGS
* s16 startFrame (s), s16 endFrame (e)
* FORMAT
* 00000002 0001ssss eeee0000
* size = 0xC
*/
#define CS_CAM_FOCUS_POINT_LIST CS_CAM_AT_LIST
#define CS_CAM_AT_LIST(startFrame, endFrame) \
CS_CMD_CAM_AT, CMD_HH(0x0001, startFrame), CMD_HH(endFrame, 0x0000)
/**
* ARGS
* s8 continueFlag (c), s8 roll (r), s16 frame (f), f32 viewAngle (a),
* s16 xPos (x), s16 yPos (y), s16 zPos (z)
* FORMAT
* Capital U is Unused
* ccrrffff aaaaaaaa xxxxyyyy zzzzUUUU
* size = 0x10
*/
#define CS_CAM_FOCUS_POINT CS_CAM_AT
#define CS_CAM_AT(continueFlag, roll, frame, viewAngle, xPos, yPos, zPos, unused) \
CMD_BBH(continueFlag, roll, frame), CMD_F(viewAngle), CMD_HH(xPos, yPos), CMD_HH(zPos, unused)
/**
* ARGS
* s32 entries (e)
* FORMAT
* 00000003 eeeeeeee
* size = 0x8
*/
#define CS_MISC_LIST(entries) CS_CMD_MISC, CMD_W(entries)
/**
* ARGS
* s16 unk (u), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused
* uuuussss eeeeUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU
* size = 0x30
*/
#define CS_MISC(unk, startFrame, endFrame, unused0, unused1, unused2, unused3, unused4, unused5, unused6, unused7, unused8, unused9, unused10) \
CMD_HH(unk, startFrame), CMD_HH(endFrame, unused0), \
CMD_W(unused1), CMD_W(unused2), CMD_W(unused3), CMD_W(unused4), CMD_W(unused5), \
CMD_W(unused6), CMD_W(unused7), CMD_W(unused8), CMD_W(unused9), CMD_W(unused10)
/**
* ARGS
* s32 entries (e)
* FORMAT
* 00000004 eeeeeeee
* size = 0x8
*/
#define CS_LIGHTING_LIST(entries) CS_CMD_SET_LIGHTING, CMD_W(entries)
/**
* ARGS
* s16 setting (m), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused
* mmmmssss eeeeUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU 00000000 00000000 00000000
* size = 0x30
*/
#define CS_LIGHTING(setting, startFrame, endFrame, unused0, unused1, unused2, unused3, unused4, unused5, unused6, unused7) \
CMD_HH(setting, startFrame), CMD_HH(endFrame, unused0), \
CMD_W(unused1), CMD_W(unused2), CMD_W(unused3), CMD_W(unused4), CMD_W(unused5), \
CMD_W(unused6), CMD_W(unused7), 0x00000000, 0x00000000, 0x00000000
/**
* ARGS
* s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused , may be consistently zero
* 00000005 0001ssss eeee0000
* size = 0xC
*/
#define CS_CAM_POS_PLAYER_LIST CS_CAM_EYE_REL_TO_PLAYER_LIST
#define CS_CAM_EYE_REL_TO_PLAYER_LIST(startFrame, endFrame) \
CS_CMD_CAM_EYE_REL_TO_PLAYER, CMD_HH(0x0001, startFrame), CMD_HH(endFrame, 0x0000)
/**
* ARGS
* s8 continueFlag (c), s8 roll (r), s16 frame (f), f32 viewAngle (a),
* s16 xPos (x), s16 yPos (y), s16 zPos (z)
* FORMAT
* Capital U is Unused
* ccrrffff aaaaaaaa xxxxyyyy zzzzUUUU
* size = 0x10
*/
#define CS_CAM_POS_PLAYER CS_CAM_EYE_REL_TO_PLAYER
#define CS_CAM_EYE_REL_TO_PLAYER(continueFlag, roll, frame, viewAngle, xPos, yPos, zPos, unused) \
CMD_BBH(continueFlag, roll, frame), CMD_F(viewAngle), CMD_HH(xPos, yPos), CMD_HH(zPos, unused)
/**
* ARGS
* s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused , may be consistently zero
* 00000006 0001ssss eeee0000
* size = 0xC
*/
#define CS_CAM_FOCUS_POINT_PLAYER_LIST CS_CAM_AT_REL_TO_PLAYER_LIST
#define CS_CAM_AT_REL_TO_PLAYER_LIST(startFrame, endFrame) \
CS_CMD_CAM_AT_REL_TO_PLAYER, CMD_HH(0x0001, startFrame), CMD_HH(endFrame, 0x0000)
/**
* ARGS
* s8 continueFlag (c), s8 roll (r), s16 frame (f), f32 viewAngle (a),
* s16 xPos (x), s16 yPos (y), s16 zPos (z)
* FORMAT
* Capital U is Unused
* ccrrffff aaaaaaaa xxxxyyyy zzzzUUUU
* size = 0x10
*/
#define CS_CAM_FOCUS_POINT_PLAYER CS_CAM_AT_REL_TO_PLAYER
#define CS_CAM_AT_REL_TO_PLAYER(continueFlag, roll, frame, viewAngle, xPos, yPos, zPos, unused) \
CMD_BBH(continueFlag, roll, frame), CMD_F(viewAngle), CMD_HH(xPos, yPos), CMD_HH(zPos, unused)
/**
* ARGS
* s16 unk (u), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused
* 00000007 uuuussss eeeeUUUU
* size = 0xC
*/
#define CS_CMD_07_LIST(unk, startFrame, endFrame, unused) \
CS_CMD_07, CMD_HH(unk, startFrame), CMD_HH(endFrame, unused)
/**
* ARGS
* s8 continueFlag (c), s8 roll (r), s16 frame (f), f32 viewAngle (a),
* s16 xPos (x), s16 yPos (y), s16 zPos (z)
* FORMAT
* Capital U is Unused
* ccrrffff aaaaaaaa xxxxyyyy zzzzUUUU
* size = 0x10
*/
#define CS_CMD_07(continueFlag, roll, frame, viewAngle, xPos, yPos, zPos, unused) \
CMD_BBH(continueFlag, roll, frame), CMD_F(viewAngle), CMD_HH(xPos, yPos), CMD_HH(zPos, unused)
/**
* ARGS
* s16 unk (u), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused
* 00000008 uuuussss eeeeUUUU
* size = 0xC
*/
#define CS_CMD_08_LIST(unk, startFrame, endFrame, unused) \
CS_CMD_08, CMD_HH(unk, startFrame), CMD_HH(endFrame, unused)
/**
* ARGS
* s8 continueFlag (c), s8 roll (r), s16 frame (f), f32 viewAngle (a),
* s16 xPos (x), s16 yPos (y), s16 zPos (z)
* FORMAT
* Capital U is Unused
* ccrrffff aaaaaaaa xxxxyyyy zzzzUUUU
* size = 0x10
*/
#define CS_CMD_08(continueFlag, roll, frame, viewAngle, xPos, yPos, zPos, unused) \
CMD_BBH(continueFlag, roll, frame), CMD_F(viewAngle), CMD_HH(xPos, yPos), CMD_HH(zPos, unused)
/**
* ARGS
* s32 entries (e)
* FORMAT
* 00000009 eeeeeeee
* size = 0x8
*/
#define CS_CMD_09_LIST(entries) CS_CMD_09, CMD_W(entries)
/**
* ARGS
* s16 unk (u), s16 startFrame (s), s16 endFrame (e), s16 unk2 (v), s16 unk3 (w), s16 unk4 (x)
* FORMAT
* Capital U is Unused
* uuuussss eeeevvww xxUUUUUU
* size = 0xC
*/
#define CS_CMD_09(unk, startFrame, endFrame, unk2, unk3, unk4, unused0, unused1) \
CMD_HH(unk, startFrame), CMD_HBB(endFrame, unk2, unk3), CMD_BBH(unk4, unused0, unused1)
/**
* ARGS
* s32 cmdType (c), s32 entries (e)
* FORMAT
* cccccccc eeeeeeee
* size = 0x8
*/
#define CS_UNK_DATA_LIST(cmdType, entries) CMD_W(cmdType), CMD_W(entries)
/**
* ARGS
* s32 unk1 (a), s32 unk2 (b), s32 unk3 (c), s32 unk4 (d), s32 unk5 (e), s32 unk6 (f),
* s32 unk7 (g), s32 unk8 (h), s32 unk9 (i), s32 unk10 (j), s32 unk11 (k), s32 unk12 (l)
* FORMAT
* aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh iiiiiiii jjjjjjjj kkkkkkkk llllllll
* size = 0x30
*/
#define CS_UNK_DATA(unk1, unk2, unk3, unk4, unk5, unk6, unk7, unk8, unk9, unk10, unk11, unk12) \
CMD_W(unk1), CMD_W(unk2), CMD_W(unk3), CMD_W(unk4), CMD_W(unk5), CMD_W(unk6), \
CMD_W(unk7), CMD_W(unk8), CMD_W(unk9), CMD_W(unk10), CMD_W(unk11), CMD_W(unk12)
/**
* ARGS
* s32 cmdType (c), s32 entries (e)
* FORMAT
* cccccccc eeeeeeee
* size = 0x8
*/
#define CS_NPC_ACTION_LIST(cmdType, entries) CMD_W(cmdType), CMD_W(entries)
/**
* ARGS
* s16 npcAction (a), s16 startFrame (s), s16 endFrame (e),
* s16 rotX (u), s16 rotY (v), s16 rotZ (w),
* s32 startX (i), s32 startY (j), s32 startZ (k),
* s32 endX (l), s32 endY (m), s32 endZ (n),
* f32 normX (x), f32 normY (y), f32 normZ (z),
* FORMAT
* aaaassss eeeeuuuu vvvvwwww iiiiiiii jjjjjjjj kkkkkkkk llllllll mmmmmmmm nnnnnnnn xxxxxxxx yyyyyyyy zzzzzzzz
* size = 0x30
*/
#define CS_NPC_ACTION(npcAction, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ) \
CMD_HH(npcAction, startFrame), CMD_HH(endFrame, rotX), CMD_HH(rotY, rotZ), \
CMD_W(startX), CMD_W(startY), CMD_W(startZ), \
CMD_W(endX), CMD_W(endY), CMD_W(endZ), \
CMD_F(normX), CMD_F(normY), CMD_F(normZ)
/**
* ARGS
* s32 cmdType (c), s32 entries (e)
* FORMAT
* cccccccc eeeeeeee
* size = 0x8
*/
#define CS_PLAYER_ACTION_LIST(entries) CS_CMD_SET_PLAYER_ACTION, CMD_W(entries)
/**
* ARGS
* s16 linkAction (a), s16 startFrame (s), s16 endFrame (e),
* s16 rotX (u), s16 rotY (v), s16 rotZ (w),
* s32 startX (i), s32 startY (j), s32 startZ (k),
* s32 endX (l), s32 endY (m), s32 endZ (n),
* f32 normX (x), f32 normY (y), f32 normZ (z),
* FORMAT
* aaaassss eeeeuuuu vvvvwwww iiiiiiii jjjjjjjj kkkkkkkk llllllll mmmmmmmm nnnnnnnn xxxxxxxx yyyyyyyy zzzzzzzz
* size = 0x30
*/
#define CS_PLAYER_ACTION(linkAction, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ) \
CS_NPC_ACTION(linkAction, startFrame, endFrame, rotX, rotY, rotZ, startX, startY, startZ, endX, endY, endZ, normX, normY, normZ)
/**
* ARGS
* s32 entries (e)
* FORMAT
* 00000013 eeeeeeee
* size = 0x8
*/
#define CS_TEXT_LIST(entries) CS_CMD_TEXTBOX, CMD_W(entries)
/**
* ARGS
* s16 messageId (i), s16 startFrame (s), s16 endFrame (e), s16 type (o),
* s16 topOptionBranch (y), s16 bottomOptionBranch (n)
* FORMAT
* iiiissss eeeeoooo yyyynnnn
* size = 0xC
*/
#define CS_TEXT_DISPLAY_TEXTBOX(messageId, startFrame, endFrame, type, topOptionBranch, bottomOptionBranch) \
CMD_HH(messageId, startFrame), CMD_HH(endFrame, type), CMD_HH(topOptionBranch, bottomOptionBranch)
/**
* ARGS
* s16 startFrame (s), s16 endFrame (e)
* FORMAT
* FFFFssss eeeeFFFF FFFFFFFF
* size = 0xC
*/
#define CS_TEXT_NONE(startFrame, endFrame) \
CS_TEXT_DISPLAY_TEXTBOX(0xFFFF, startFrame, endFrame, 0xFFFF, 0xFFFF, 0xFFFF)
/**
* ARGS
* s16 ocarinaSongAction (o), s16 startFrame (s), s16 endFrame (e), s16 topOptionBranch (i)
* FORMAT
* oooossss eeee0002 iiiiFFFF
* size = 0xC
*/
#define CS_TEXT_LEARN_SONG(ocarinaSongAction, startFrame, endFrame, messageId) \
CS_TEXT_DISPLAY_TEXTBOX(ocarinaSongAction, startFrame, endFrame, 0x0002, messageId, 0xFFFF)
/**
* ARGS
* s16 transitionType (t), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused , endFrame duplicate
* 0000002D 00000001 ttttssss eeeeUUUU
* size = 0x10
*/
#define CS_SCENE_TRANS_FX(transitionType, startFrame, endFrame) \
CS_CMD_SCENE_TRANS_FX, 0x00000001, CMD_HH(transitionType, startFrame), CMD_HH(endFrame, endFrame)
/**
* ARGS
* s32 entries (e)
* FORMAT
* 00000056 eeeeeeee
* size = 0x8
*/
#define CS_PLAY_BGM_LIST(entries) CS_CMD_PLAYBGM, CMD_W(entries)
/**
* ARGS
* s16 sequence (q), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused
* qqqqssss eeeeUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU 00000000 00000000 00000000
* size = 0x30
*/
#define CS_PLAY_BGM(sequence, startFrame, endFrame, unused0, unused1, unused2, unused3, unused4, unused5, unused6, unused7) \
CMD_HH(sequence, startFrame), CMD_HH(endFrame, unused0), \
CMD_W(unused1), CMD_W(unused2), CMD_W(unused3), CMD_W(unused4), CMD_W(unused5), \
CMD_W(unused6), CMD_W(unused7), 0x00000000, 0x00000000, 0x00000000
/**
* ARGS
* s32 entries (e)
* FORMAT
* 00000057 eeeeeeee
* size = 0x8
*/
#define CS_STOP_BGM_LIST(entries) CS_CMD_STOPBGM, CMD_W(entries)
/**
* ARGS
* s16 sequence (q), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused
* uuqqssss eeeeUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU 00000000 00000000 00000000
* size = 0x30
*/
#define CS_STOP_BGM(sequence, startFrame, endFrame, unused0, unused1, unused2, unused3, unused4, unused5, unused6, unused7) \
CMD_HH(sequence, startFrame), CMD_HH(endFrame, unused0), \
CMD_W(unused1), CMD_W(unused2), CMD_W(unused3), CMD_W(unused4), CMD_W(unused5), \
CMD_W(unused6), CMD_W(unused7), 0x00000000, 0x00000000, 0x00000000
/**
* ARGS
* s32 entries (e)
* FORMAT
* 0000007C eeeeeeee
* size = 0x8
*/
#define CS_FADE_BGM_LIST(entries) CS_CMD_FADEBGM, CMD_W(entries)
/**
* ARGS
* s16 fadeType (t), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused
* ttttssss eeeeUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU UUUUUUUU 00000000 00000000 00000000
* size = 0x30
*/
#define CS_FADE_BGM(fadeType, startFrame, endFrame, unused0, unused1, unused2, unused3, unused4, unused5, unused6, unused7) \
CMD_HH(fadeType, startFrame), CMD_HH(endFrame, unused0), \
CMD_W(unused1), CMD_W(unused2), CMD_W(unused3), CMD_W(unused4), CMD_W(unused5), \
CMD_W(unused6), CMD_W(unused7), 0x00000000, 0x00000000, 0x00000000
/**
* ARGS
* s32 entries (e)
* FORMAT
* 0000008C eeeeeeee
* size = 0x8
*/
#define CS_TIME_LIST(entries) CS_CMD_SETTIME, CMD_W(entries)
/**
* ARGS
* s16 unk (u), s16 startFrame (s), s16 endFrame (e), s8 hour (h), s8 min (m)
* FORMAT
* Capital U is Unused
* uuuussss eeeehhmm UUUUUUUU
* size = 0xC
*/
#define CS_TIME(unk, startFrame, endFrame, hour, min, unused) \
CMD_HH(unk, startFrame), \
CMD_HBB(endFrame, hour, min), \
CMD_W(unused)
/**
* ARGS
* CutsceneTerminatorDestination dest (d), s16 startFrame (s), s16 endFrame (e)
* FORMAT
* Capital U is Unused , endFrame duplicate
* 000003E8 00000001 ddddssss eeeeUUUU
* size = 0x10
*/
#define CS_TERMINATOR(dest, startFrame, endFrame) \
CS_CMD_TERMINATOR, 0x00000001, CMD_HH(dest, startFrame), CMD_HH(endFrame, endFrame)
/**
* Marks the end of a cutscene
*/
#define CS_END() 0xFFFFFFFF, 0x00000000
#endif

View File

@@ -0,0 +1,29 @@
{
"file1": "File 1",
"file2": "File 2",
"file3": "File 3",
"options": "Options",
"copy": "Copy",
"erase": "Erase",
"quit": "Quit",
"confirm": "Yes",
"end": "End",
"hyphen": "Hyphen",
"period": "Period",
"space": "Space",
"backspace": "Backspace",
"capital_letter": "Capital $0",
"audio_stereo": "Sound - Stereo",
"audio_mono": "Sound - Mono",
"audio_headset": "Sound - Headset",
"audio_surround": "Sound - Surround",
"target_switch": "Targeting Mode - Switch",
"target_hold": "Targeting Mode - Hold",
"language_english": "Language - English",
"language_german": "Language - German",
"language_french": "Language - French",
"quest_sel_vanilla": "Quest - Original",
"quest_sel_mq": "Quest - Master Quest",
"quest_sel_randomizer": "Quest - Randomizer",
"quest_sel_boss_rush": "Quest - Boss Rush"
}

View File

@@ -0,0 +1,29 @@
{
"file1": "Fichier 1",
"file2": "Fichier 2",
"file3": "Fichier 3",
"options": "Options",
"copy": "Copier",
"erase": "Effacer",
"quit": "Retour",
"confirm": "Oui",
"end": "Fin",
"hyphen": "Trait d'union",
"period": "Point",
"space": "Espace",
"backspace": "Retour arrière",
"capital_letter": "Majuscule $0",
"audio_stereo": "Son - Stéréo",
"audio_mono": "Son - Mono",
"audio_headset": "Son - Casque",
"audio_surround": "Son - Surround",
"target_switch": "Visée - Fixe",
"target_hold": "Visée - Maintenue",
"language_english": "Langue - Anglaise",
"language_german": "Langue - Allemande",
"language_french": "Langue - Français",
"quest_sel_vanilla": "Quête - Originale",
"quest_sel_mq": "Quête - Master Quest",
"quest_sel_randomizer": "Quête - Randomizer",
"quest_sel_boss_rush": "Quête - Boss Rush"
}

View File

@@ -0,0 +1,29 @@
{
"file1": "Datei 1",
"file2": "Datei 2",
"file3": "Datei 3",
"options": "Optionen",
"copy": "Kopieren",
"erase": "Löschen",
"quit": "Zurück",
"confirm": "Ja",
"end": "Ende",
"hyphen": "Bindestrich",
"period": "Punkt",
"space": "Raum",
"backspace": "Rücktaste",
"capital_letter": "Großbuchstabe $0",
"audio_stereo": "Sound - Stereo",
"audio_mono": "Sound - Mono",
"audio_headset": "Sound - Kopfhörer",
"audio_surround": "Sound - Surround",
"target_switch": "Zielerfassung - Einmal drücken",
"target_hold": "Zielerfassung - Trigger halten",
"language_english": "Sprache - Englisch",
"language_german": "Sprache - Deutsch",
"language_french": "Sprache - Französisch",
"quest_sel_vanilla": "Quest - Original",
"quest_sel_mq": "Quest - Master Quest",
"quest_sel_randomizer": "Quest - Randomizer",
"quest_sel_boss_rush": "Quest - Bosse Rush"
}

View File

@@ -0,0 +1,231 @@
{
"health": "Health - $0 Hearts",
"magic": "Magic - $0",
"rupees": "Rupees - $0",
"floor": "Floor $0",
"basement": "Basement $0",
"item_menu": "Select Item",
"map_menu": "Map - $0",
"quest_menu": "Quest Status",
"equip_menu": "Equipment",
"overworld": "Overworld",
"equipped": "$0 - Equipped",
"save_prompt": "Would you like to save?",
"game_saved": "Game saved",
"assigned_to": "Assigned to $0",
"0": "Deku Stick - $0",
"1": "Deku Nut - $0",
"2": "Bomb - $0",
"3": "Fairy Bow - $0",
"4": "Fire Arrow",
"5": "Din's Fire",
"6": "Fairy Slingshot - $0",
"7": "Fairy Ocarina",
"8": "Ocarina of Time",
"9": "Bombchu - $0",
"10": "Hookshot",
"11": "Longshot",
"12": "Ice Arrow",
"13": "Farore's Wind",
"14": "Boomerang",
"15": "Lens of Truth",
"16": "Magic Beans - $0",
"17": "Megaton Hammer",
"18": "Light Arrow",
"19": "Nayru's Love",
"20": "Empty Bottle",
"21": "Red Potion",
"22": "Green Potion",
"23": "Blue Potion",
"24": "Fairy",
"25": "Fish",
"26": "Milk Bottle",
"27": "Ruto's Letter",
"28": "Blue Fire",
"29": "Bugs",
"30": "Big Poe",
"31": "Milk Bottle (Half)",
"32": "Poe",
"33": "Weird Egg",
"34": "Chicken",
"35": "Zelda's Letter",
"36": "Keaton Mask",
"37": "Skull Mask",
"38": "Spooky Mask",
"39": "Bunny Mask",
"40": "Goron Mask",
"41": "Zora Mask",
"42": "Gerudo Mask",
"43": "Mask of Truth",
"44": "Sold Out",
"45": "Pocket Egg",
"46": "Pocket Cucco",
"47": "Cojiro",
"48": "Odd Mushroom",
"49": "Odd Potion",
"50": "Saw",
"51": "Broken Sword",
"52": "Prescription",
"53": "Eyeball Frog",
"54": "Eyedrops",
"55": "Claim Check",
"56": "Bow Fire Arrow",
"57": "Bow Ice Arrow",
"58": "Bow Light Arrow",
"59": "Kokiri Sword",
"60": "Master Sword",
"61": "Giant's Knife",
"62": "Deku Shield",
"63": "Hylian Shield",
"64": "Mirror Shield",
"65": "Kokiri Tunic",
"66": "Goron Tunic",
"67": "Zora Tunic",
"68": "Kokiri Boots",
"69": "Iron Boots",
"70": "Hover Boots",
"71": "Bullet Bag (Holds 30)",
"72": "Bullet Bag (Holds 40)",
"73": "Bullet Bag (Holds 50)",
"74": "Quiver (Holds 30)",
"75": "Quiver (Holds 40)",
"76": "Quiver (Holds 50)",
"77": "Bomb Bag (Holds 20)",
"78": "Bomb Bag (Holds 30)",
"79": "Bomb Bag (Holds 40)",
"80": "Goron's Bracelet",
"81": "Silver Gauntlets",
"82": "Golden Gauntlets",
"83": "Silver Scale",
"84": "Golden Scale",
"85": "Giant's Knife (Broken)",
"86": "WALLET ADULT",
"87": "Giant's Wallet",
"88": "Deku Seeds",
"89": "Fishing Pole",
"90": "Minuet of Forest",
"91": "Bolero of Fire",
"92": "Serenade of Water",
"93": "Requiem of Spirit",
"94": "Nocturne of Shadow",
"95": "Prelude of Light",
"96": "Zelda's Lullaby",
"97": "Epona's Song",
"98": "Saria's Song",
"99": "Sun's Song",
"100": "Song of Time",
"101": "Song of Storms",
"102": "Forest Medallion",
"103": "Fire Medallion",
"104": "Water Medallion",
"105": "Spirit Medallion",
"106": "Shadow Medallion",
"107": "Light Medallion",
"108": "Kokiri's Emerald",
"109": "Goron's Ruby",
"110": "Zora Sapphire",
"111": "Stone of Agony",
"112": "Gerudo's Card",
"113": "Skulltula Token - $0",
"114": "Piece of Heart - $0",
"115": "Piece of Heart",
"116": "Boss Key",
"117": "Compass",
"118": "Dungeon Map",
"119": "Small Key",
"120": "MAGIC SMALL",
"121": "MAGIC LARGE",
"122": "Biggoron's Sword",
"123": "INVALID 1",
"124": "INVALID 2",
"125": "INVALID 3",
"126": "INVALID 4",
"127": "INVALID 5",
"128": "INVALID 6",
"129": "INVALID 7",
"130": "Milk",
"131": "Recovery Heart",
"132": "Green Rupee",
"133": "Blue Rupee",
"134": "Red Rupee",
"135": "Purple Rupee",
"136": "Gold Rupee",
"137": "INVALID 8",
"138": "STICKS 5",
"139": "STICKS 10",
"140": "NUTS 5",
"141": "NUTS 10",
"142": "BOMBS 5",
"143": "BOMBS 10",
"144": "BOMBS 20",
"145": "BOMBS 30",
"146": "ARROWS SMALL",
"147": "ARROWS MEDIUM",
"148": "ARROWS LARGE",
"149": "SEEDS 30",
"150": "BOMBCHUS 5",
"151": "BOMBCHUS 20",
"152": "STICK UPGRADE 20",
"153": "STICK UPGRADE 30",
"154": "NUT UPGRADE 30",
"155": "NUT UPGRADE 40",
"255": "",
"256": "Haunted Wasteland",
"257": "Gerudos Fortress",
"258": "Gerudo Valley",
"259": "Hylia Lakeside",
"260": "Lon Lon Ranch",
"261": "Market",
"262": "Hyrule Field",
"263": "Death Mountain",
"264": "Kakariko Village",
"265": "Lost Woods",
"266": "Kokiri Forest",
"267": "Zoras Domain",
"268": "",
"269": "",
"270": "",
"271": "",
"272": "",
"273": "",
"274": "",
"275": "",
"276": "",
"277": "",
"278": "",
"279": "",
"280": "",
"281": "",
"282": "",
"283": "",
"284": "",
"285": "",
"286": "",
"287": "",
"288": "",
"289": "",
"290": "",
"291": "",
"292": "Hyrule Field",
"293": "Kakariko Village",
"294": "Graveyard",
"295": "Zoras River",
"296": "Kokiri Forest",
"297": "Sacred Forest Meadow",
"298": "Lake Hylia",
"299": "Zoras Domain",
"300": "Zoras Fountain",
"301": "Gerudo Valley",
"302": "Lost Woods",
"303": "Desert Colossus",
"304": "Gerudo's Fortress",
"305": "Haunted Wasteland",
"306": "Market",
"307": "Hyrule Castle",
"308": "Death Mountain Trail",
"309": "Death Mountain Crater",
"310": "Goron City",
"311": "Lon Lon Ranch",
"312": "Question Mark",
"313": "Ganon's Castle"
}

View File

@@ -0,0 +1,231 @@
{
"health": "Vie - $0 Coeurs",
"magic": "Magie - $0",
"rupees": "Rubis - $0",
"floor": "Étage $0",
"basement": "Sous-sol $0",
"item_menu": "Inventaire",
"map_menu": "Carte - $0",
"quest_menu": "Statut de la quête",
"equip_menu": "Equipment",
"overworld": "Surmonde",
"equipped": "$0 - Équipé",
"save_prompt": "Voulez-vous sauvegarder?",
"game_saved": "Jeu sauvegardé",
"assigned_to": "Assigné au $0",
"0": "Bâton Mojo - $0",
"1": "Noix Mojo - $0",
"2": "Bombes - $0",
"3": "Arc des Fées - $0",
"4": "Flèche de Feu",
"5": "Feu de Din",
"6": "Lance-Pierre des Fées - $0",
"7": "Ocarina des Fées",
"8": "Ocarina of Temps",
"9": "Missiles Teigneux - $0",
"10": "Grappin",
"11": "Super Grappin",
"12": "Flèche de Glace",
"13": "Vent de Farore",
"14": "Boomerang",
"15": "Monocle de Vérité",
"16": "Haricot Magique - $0",
"17": "Masse des Titans",
"18": "Flèche de Lumière",
"19": "Amour de Nayru",
"20": "Bouteille Vide",
"21": "Potion Rouge",
"22": "Potion Verte",
"23": "Potion Bleue",
"24": "Fée",
"25": "Poisson",
"26": "Lait de Lon Lon",
"27": "Lettre de Ruto",
"28": "Flammme Bleue",
"29": "Insectes",
"30": "Âme",
"31": "Lait de Lon Lon (moitié)",
"32": "Esprit",
"33": "Oeuf Curieux",
"34": "Poulet",
"35": "Lettre de Zelda",
"36": "Masque du Renard",
"37": "Masque de Mort",
"38": "Masque d'Effroi",
"39": "Masque du Lapin",
"40": "Masque de Goron",
"41": "Masque de Zora",
"42": "Masque de Gerudo",
"43": "Masque de Vérité",
"44": "VENDU",
"45": "Oeuf de Poche",
"46": "Cocotte de poche",
"47": "P'tit Poulet",
"48": "Champignon suspect",
"49": "Mixture suspecte",
"50": "Scie du chasseur",
"51": "Épée de Goron (brisée)",
"52": "Ordonnance",
"53": "Crapaud-qui-louche",
"54": "Gouttes",
"55": "Certificat",
"56": "Arc et Flèche de Feu",
"57": "Arc et Flèche de Glace",
"58": "Arc et Flèche de Lumière",
"59": "Épée Kokiri",
"60": "Épée de Légende",
"61": "Lame des Géants",
"62": "Bouclier Mojo",
"63": "Bouclier Hylien",
"64": "Bouclier Miroir",
"65": "Tunique Kokiri",
"66": "Tunique Goron",
"67": "Tunique Zora",
"68": "Bottes Kokiri",
"69": "Bottes de plomb",
"70": "Bottes des airs",
"71": "Sac de graines (Contient 30)",
"72": "Sac de graines (Contient 40)",
"73": "Sac de graines (Contient 50)",
"74": "Carquois (Contient 30)",
"75": "Carquois (Contient 40)",
"76": "Carquois (Contient 50)",
"77": "Sac de bombes (Contient 20)",
"78": "Sac de bombes (Contient 30)",
"79": "Sac de bombes (Contient 40)",
"80": "Bracelet Goron",
"81": "Gantelets d'argent",
"82": "Gentelets d'or",
"83": "Écaille d'argent",
"84": "Écaille d'or",
"85": "Lame des Géants (Brisée)",
"86": "GRANDE BOURSE",
"87": "Bourse de Géant",
"88": "Deku Seeds",
"89": "Canne à pèche",
"90": "Menuet des Bois",
"91": "Boléro du Feu",
"92": "Sérénade de l'Eau",
"93": "Requiem des Esprits",
"94": "Nocturne de l'Ombre",
"95": "Prélude de la Lumière",
"96": "Berceuse de Zelda",
"97": "Chant d'Epona",
"98": "Chant de Saria",
"99": "Chant du Soleil",
"100": "Chant du Temps",
"101": "Chant des Tempêtes",
"102": "Médaillon de la Forêt",
"103": "Médaillon du Feu",
"104": "Médaillon de l'Eau",
"105": "Médaillon de l'Esprit",
"106": "Médaillon de l'Ombre",
"107": "Médaillon de la Lumière",
"108": "Émeraude Kokiri",
"109": "Rubis Goron",
"110": "Saphir Zora",
"111": "Pierre de Souffrance",
"112": "Carte Gerudo",
"113": "Skulltula d'or - $0",
"114": "Quart de Coeur - $0",
"115": "Quart de Coeur",
"116": "Clé d'or",
"117": "Boussole",
"118": "Carte du Donjon",
"119": "Petite Clé",
"120": "PETITE BOUTEILLE DE MAGIE",
"121": "GRANDE BOUTEILLE DE MAGIE",
"122": "Épée de Biggoron",
"123": "INVALIDE 1",
"124": "INVALIDE 2",
"125": "INVALIDE 3",
"126": "INVALIDE 4",
"127": "INVALIDE 5",
"128": "INVALIDE 6",
"129": "INVALIDE 7",
"130": "Lait de Lon Lon",
"131": "Coeur de Vie",
"132": "Rubis Vert",
"133": "Rubis Bleu",
"134": "Rubis Rouge",
"135": "Rubis Pourpre",
"136": "Énorme Rubis",
"137": "INVALIDE 8",
"138": "BÂTON MOJO 5",
"139": "BÂTON MOJO 10",
"140": "NOIX MOJO 5",
"141": "NOIX MOJO 10",
"142": "BOMBES 5",
"143": "BOMBES 10",
"144": "BOMBES 20",
"145": "BOMBES 30",
"146": "ARROWS SMALL",
"147": "ARROWS MEDIUM",
"148": "ARROWS LARGE",
"149": "GRAINES MOJO 30",
"150": "MISSILES TEIGNEUX 5",
"151": "MISSILES TEIGNEUX 20",
"152": "AMÉLIORATION BÂTON MOJO 20",
"153": "AMÉLIORATION BÂTON MOJO 30",
"154": "AMÉLIORATION NOIX MOJO 30",
"155": "AMÉLIORATION NOIX MOJO 40",
"255": "",
"256": "Désert Hanté",
"257": "Forteresse Gerudo",
"258": "Vallée Gerudo",
"259": "Laboratoire du Lac",
"260": "Ranch Lon Lon",
"261": "Place du Marché",
"262": "Plaine d'Hyrule",
"263": "Montagne du Péril",
"264": "Village Cocorico",
"265": "Bois Perdus",
"266": "Forêt Kokiri",
"267": "Domaine Zora",
"268": "",
"269": "",
"270": "",
"271": "",
"272": "",
"273": "",
"274": "",
"275": "",
"276": "",
"277": "",
"278": "",
"279": "",
"280": "",
"281": "",
"282": "",
"283": "",
"284": "",
"285": "",
"286": "",
"287": "",
"288": "",
"289": "",
"290": "",
"291": "",
"292": "Plaine d'Hyrule",
"293": "Village Cocorico",
"294": "Cimetière",
"295": "Rivière Zora",
"296": "Forêt Kokiri",
"297": "Bosquet Sacré",
"298": "Lac Hylia",
"299": "Domaine Zora",
"300": "Fountaine Zora",
"301": "Vallée Gerudo",
"302": "Bois Perdus",
"303": "Colosse du Désert",
"304": "Forteresse Gerudo",
"305": "Désert Hanté",
"306": "Place du Marché",
"307": "Château d'Hyrule",
"308": "Chemin du Péril",
"309": "Cratère du Péril",
"310": "Village Goron",
"311": "Ranch Lon Lon",
"312": "Point d'interrogation",
"313": "Château de Ganon"
}

View File

@@ -0,0 +1,231 @@
{
"health": "Energie - $0 Herzen",
"magic": "Magie - $0",
"rupees": "Rubine - $0",
"floor": "Etage $0",
"basement": "Keller $0",
"item_menu": "Gegenstände",
"map_menu": "Karte - $0",
"quest_menu": "Quest Status",
"equip_menu": "Ausrüstung",
"overworld": "Überwelt",
"equipped": "$0 - Ausgerüstet",
"save_prompt": "Spielstand sichern?",
"game_saved": "Spielstand gesichert",
"assigned_to": "$0 zugeordnet",
"0": "Deku-Stab - $0",
"1": "Deku-Nuß - $0",
"2": "Bombe - $0",
"3": "Feen-Bogen - $0",
"4": "Feuer-Pfeil",
"5": "Dins Feuerinferno",
"6": "Feen-Schleuder - $0",
"7": "Feen-Okarina",
"8": "Okarina der Zeit",
"9": "Krabbelmine - $0",
"10": "Fanghaken",
"11": "Enterhaken",
"12": "Eis-Pfeil",
"13": "Farores Donnersturm",
"14": "Bumerang",
"15": "Auge der Wahrheit",
"16": "Wundererbsen - $0",
"17": "Stahlhammer",
"18": "Licht-Pfeil",
"19": "Nayrus Umarmung",
"20": "Flasche",
"21": "Rotes Elixier",
"22": "Grünes Elixier",
"23": "Blaues Elixier",
"24": "Fee",
"25": "Fisch",
"26": "Milch",
"27": "Brief",
"28": "Blaues Feuer",
"29": "Käfer",
"30": "Nachtschwärmer",
"31": "Milch (1/2)",
"32": "Irrlicht",
"33": "Seltsames Ei",
"34": "Huhn",
"35": "Zeldas Brief",
"36": "Fuchs-Maske",
"37": "Schädel-Maske",
"38": "Geister-Maske",
"39": "Hasenohren",
"40": "Goronen-Maske",
"41": "Zora-Maske",
"42": "Gerudo-Maske",
"43": "Maske des Wissens",
"44": "Verkauft",
"45": "Ei",
"46": "Kiki",
"47": "Henni",
"48": "Schimmelpilz",
"49": "Modertrank",
"50": "Säge",
"51": "Goronen-Schwert (zerbrochen)",
"52": "Rezept",
"53": "Glotzfrosch",
"54": "Augentropfen",
"55": "Zertifikat",
"56": "Bogen Feuer-Pfeil",
"57": "Bogen Eis-Pfeil",
"58": "Bogen Licht-Pfeil",
"59": "Kokiri-Schwert",
"60": "Master-Schwert",
"61": "Langschwert",
"62": "Deku-schild",
"63": "Hylia-Schild",
"64": "Spiegel-Schild",
"65": "Kokiri-Rüstung",
"66": "Goronen-Rüstung",
"67": "Zora-Rüstung",
"68": "Lederstiefel",
"69": "Eisenstiefel",
"70": "Gleitstiefel",
"71": "Munitionstasche (30)",
"72": "Munitionstasche (40)",
"73": "Munitionstasche (50)",
"74": "Köcher (30)",
"75": "Köcher (40)",
"76": "Köcher (50)",
"77": "Bombentasche (20)",
"78": "Bombentasche (30)",
"79": "Bombentasche (40)",
"80": "Goronen-Armband",
"81": "Krafthandschuh",
"82": "Titanhandschuh",
"83": "Silberschuppe",
"84": "Goldschuppe",
"85": "Langschwert (gebrochen)",
"86": "Große Börse",
"87": "Riesenbörse",
"88": "Deku-Kerne",
"89": "Angel",
"90": "Menuett des Waldes",
"91": "Bolero des Feuers",
"92": "Serenade des Wassers",
"93": "Requiem der Geister",
"94": "Nocturne des Schattens",
"95": "Kantate des Lichts",
"96": "Zeldas Wiegenlied",
"97": "Eponas Lied",
"98": "Salias Lied",
"99": "Hymne der Sonne",
"100": "Hymne der Zeit",
"101": "Song of Storms",
"102": "Amulett des Waldes",
"103": "Amulett des Feuers",
"104": "Amulett des Wassers",
"105": "Amulett der Geister",
"106": "Amulett des Schattens",
"107": "Amulett des Lichts",
"108": "Kokiri-Smaragd",
"109": "Goronen-Opal",
"110": "Zora-Saphir",
"111": "Stein des Wissens",
"112": "Gerudo-Paß",
"113": "Skulltula-Symbol - $0",
"114": "Herzteil - $0",
"115": "Herzteil",
"116": "Master-Schlüssel",
"117": "Kompaß",
"118": "Labyrinth-Karte",
"119": "Kleiner Schlüssel",
"120": "MAGIE KLEIN",
"121": "MAGIE GROß",
"122": "Biggoron-Schwert",
"123": "UNGÜLTIG 1",
"124": "UNGÜLTIG 2",
"125": "UNGÜLTIG 3",
"126": "UNGÜLTIG 4",
"127": "UNGÜLTIG 5",
"128": "UNGÜLTIG 6",
"129": "UNGÜLTIG 7",
"130": "Milch",
"131": "Herz",
"132": "ein Rubin",
"133": "5 Rubine",
"134": "20 Rubine",
"135": "50 Rubine",
"136": "200 Rubine",
"137": "UNGÜLTIG 8",
"138": "STÄBE 5",
"139": "STÄBE 10",
"140": "NÜSSE 5",
"141": "NÜSSE 10",
"142": "BOMBEN 5",
"143": "BOMBEN 10",
"144": "BOMBEN 20",
"145": "BOMBEN 30",
"146": "PFEILE KLEIN",
"147": "PFEILE MITTEL",
"148": "PFEILE GROß",
"149": "KERNE 30",
"150": "KRABBELMINEN 5",
"151": "KRABBELMINEN 20",
"152": "STAB UPGRADE 20",
"153": "STAB UPGRADE 30",
"154": "NUß UPGRADE 30",
"155": "NUß UPGRADE 40",
"255": "",
"256": "Gespensterwüste",
"257": "Gerudo-Festung",
"258": "Gerudotal",
"259": "Hylia-See",
"260": "Lon Lon-Farm",
"261": "Marktplatz",
"262": "Hylianische Steppe",
"263": "Todesberg",
"264": "Kakariko",
"265": "Verlorene Wälder",
"266": "Kokiri-Wald",
"267": "Zoras Reich",
"268": "",
"269": "",
"270": "",
"271": "",
"272": "",
"273": "",
"274": "",
"275": "",
"276": "",
"277": "",
"278": "",
"279": "",
"280": "",
"281": "",
"282": "",
"283": "",
"284": "",
"285": "",
"286": "",
"287": "",
"288": "",
"289": "",
"290": "",
"291": "",
"292": "Hylianische Steppe",
"293": "Kakariko",
"294": "Friedhof",
"295": "Zora-Fluss",
"296": "Kokiri-Wald",
"297": "Heilige Lichtung",
"298": "Hylia-See",
"299": "Zoras Reich",
"300": "Zoras Quelle",
"301": "Gerudotal",
"302": "Verlorene Wälder",
"303": "Wüstenkoloss",
"304": "Gerudo-Festung",
"305": "Gespensterwüste",
"306": "Marktplatz",
"307": "Schloß Hyrule",
"308": "Pfad zum Todesberg",
"309": "Todeskrater",
"310": "Goronia",
"311": "Lon Lon-Farm",
"312": "Fragezeichen",
"313": "Teufelsturm"
}

View File

@@ -0,0 +1,24 @@
{
"minutes_plural" : "$0 minutes",
"minutes_singular" : "$0 minute",
"seconds_plural" : "$0 seconds",
"seconds_singular" : "$0 second",
"input_button_a": "the A button",
"input_button_b": "the B button",
"input_button_c": "the C button",
"input_button_l": "the L button",
"input_button_r": "the R button",
"input_button_z": "the Z button",
"input_button_c_up": "C Up",
"input_button_c_down": "C Down",
"input_button_c_left": "C Left",
"input_button_c_right": "C Right",
"input_analog_stick": "the Analog Stick",
"input_d_pad": "the D-Pad",
"input_d_pad_up": "D-Pad Up",
"input_d_pad_down": "D-Pad Down",
"input_d_pad_left": "D-Pad Left",
"input_d_pad_right": "D-Pad Right",
"yes": "Yes",
"no": "No"
}

View File

@@ -0,0 +1,24 @@
{
"minutes_plural" : "$0 minutes",
"minutes_singular" : "$0 minute",
"seconds_plural" : "$0 secondes",
"seconds_singular" : "$0 seconde",
"input_button_a": "le bouton A",
"input_button_b": "le bouton B",
"input_button_c": "le bouton C",
"input_button_l": "le bouton L",
"input_button_r": "le bouton R",
"input_button_z": "le bouton Z",
"input_button_c_up": "C Haut",
"input_button_c_down": "C Bas",
"input_button_c_left": "C Gauche",
"input_button_c_right": "C Droit",
"input_analog_stick": "le Stick Analogique",
"input_d_pad": "D-Pad",
"input_d_pad_up": "D-Pad Haut",
"input_d_pad_down": "D-Pad Bas",
"input_d_pad_left": "D-Pad Gauche",
"input_d_pad_right": "D-Pad Droit",
"yes": "Oui",
"no": "Non"
}

View File

@@ -0,0 +1,24 @@
{
"minutes_plural" : "$0 Minuten",
"minutes_singular" : "eine Minute",
"seconds_plural" : "$0 Sekunden",
"seconds_singular" : "eine Sekunde",
"input_button_a": "den A-Knopf",
"input_button_b": "den B-Knopf",
"input_button_c": "den C-Knopf",
"input_button_l": "den L-Knopf",
"input_button_r": "den R-Knopf",
"input_button_z": "den Z-Knopf",
"input_button_c_up": "C Oben",
"input_button_c_down": "C Unten",
"input_button_c_left": "C Links",
"input_button_c_right": "C Rechts",
"input_analog_stick": "den Analog-Stick",
"input_d_pad": "das Steuerkreuz",
"input_d_pad_up": "Steuerkreuz Oben",
"input_d_pad_down": "Steuerkreuz Unten",
"input_d_pad_left": "Steuerkreuz Links",
"input_d_pad_right": "Steuerkreuz Rechts",
"yes": "Ja",
"no": "Nein"
}

View File

@@ -0,0 +1,112 @@
{
"0": "Inside the Deku Tree",
"1": "Dodongo's Cavern",
"2": "Inside Jabu-Jabu's Belly",
"3": "Forest Temple",
"4": "Fire Temple",
"5": "Water Temple",
"6": "Spirit Temple",
"7": "Shadow Temple",
"8": "Bottom of The Well",
"9": "Ice Cavern",
"10": "", // Stairs to Ganondorf's Lair (No title card)
"11": "Gerudo Training Ground",
"12": "Thieves' Hideout",
"13": "Ganon's Castle",
"14": "", // Escape from Ganon's Castle (No title card)
"15": "", // Escape from Ganon's Castle 5 (No title card)x
"16": "Treasure Box Shop",
"17": "Parasitic Armored Arachnid - Gohma",
"18": "Infernal Dinosaur - King Dodongo",
"19": "Bio-electric Anemone - Barinade",
"20": "Evil Spirit from Beyond - Phantom Ganon",
"21": "Subterranean Lava Dragon - Volvagia",
"22": "Giant Aquatic Amoeba - Morpha",
"23": "Sorceress Sisters - Twinrova",
"24": "Phantom Shadow Beast - Bongo Bongo",
"25": "Great King of Evil - Ganondorf",
"26": "",
"27": "", // Entrance to Market (No title card)
"28": "",
"29": "",
"30": "Back Alley",
"31": "Back Alley",
"32": "Market",
"33": "Market",
"34": "Market",
"35": "", // Temple of Time Exterior (No title card)
"36": "SCENE_SHRINE_N",
"37": "SCENE_SHRINE_R",
"38": "", // House of the Know-it-All Brothers (No title card)
"39": "", // House of Twins (No title card)
"40": "", // House of the Great Mido (No title card)
"41": "", // Saria's House (No title card)
"42": "", // Kakariko House 1 (No title card)
"43": "", // Back Alley House 1 (No title card)
"44": "Bazaar",
"45": "Kokiri Shop",
"46": "Goron Shop",
"47": "Zora Shop",
"48": "", // Closed Shop (No title card)
"49": "Potion Shop",
"50": "", // Bombchu Shop (No title card)
"51": "Happy Mask Shop",
"52": "", // Link's House (No title card)
"53": "", // Dog Lady's House (No title card)
"54": "Stable",
"55": "", // Impa's House (No title card)
"56": "Lakeside Laboratory",
"57": "", // Running Man's Tent (No title card)
"58": "Gravekeepers Hut",
"59": "Great Fairy's Fountain",
"60": "Fairy's Fountain",
"61": "Great Fairy's Fountain",
"62": "", // Grottos (No title card)
"63": "", // Tomb 1 (No title card)
"64": "", // Tomb 2 (No title card)
"65": "Royal Family's Tomb",
"66": "Shooting Gallery",
"67": "Temple of Time",
"68": "Chamber of The Sages",
"69": "Castle Courtyard",
"70": "Castle Courtyard",
"71": "", // Goddesses Cutscene (No title card)
"72": "Unknown Place",
"73": "Fishing Pond",
"74": "Castle Courtyard",
"75": "Bombchu Bowling Alley",
"76": "", // Lon Lon Ranch House/Silo (No title card)
"77": "", // Guard House (No title card)
"78": "", // Potion Shop (No title card)
"79": "Ganon",
"80": "House of Skulltula",
"81": "Hyrule Field",
"82": "Kakariko Village",
"83": "Graveyard",
"84": "Zora's River",
"85": "Kokiri Forest",
"86": "Sacred Forest Meadow",
"87": "Lake Hylia",
"88": "Zoras Domain",
"89": "Zoras Fountain",
"90": "Gerudo Valley",
"91": "Lost Woods",
"92": "Desert Colossus",
"93": "Gerudo's Fortress",
"94": "Haunted Wasteland",
"95": "Hyrule Castle",
"96": "Death Mountain Trail",
"97": "Death Mountain Crater",
"98": "Goron City",
"99": "Lon Lon Ranch",
"100": "",
"101": "", // Debug: Test Map (No title card)
"102": "", // Debug: Test Room (No title card)
"103": "", // Debug: Depth Test (No title card)
"104": "", // Debug: Stalfos Miniboss Room (No title card)
"105": "", // Debug: Stalfos Boss Room (No title card)
"106": "", // Debug: Dark Link Room (No title card)
"107": "",
"108": "", // Debug: SRD Room (No title card)
"109": "" // Debug: Treasure Chest Warp (No title card)
}

View File

@@ -0,0 +1,112 @@
{
"0": "Abre Mojo",
"1": "Caverne Dodongo",
"2": "Ventre de Jabu-Jabu",
"3": "Temple de la Forêt",
"4": "Temple du Feu",
"5": "Temple de l'Eau",
"6": "Temple de l'Esprit",
"7": "Temple de l'Ombre",
"8": "Puits",
"9": "Caverne Polaire",
"10": "", // Escaliers vers le Repaire de Ganondorf (No title card)
"11": "Gymnase Gerudo",
"12": "Repaire des Voleurs",
"13": "Tour de Ganon",
"14": "", // Fuite du Château de Ganon (No title card)
"15": "", // Fuite du Château de Ganon 5 (No title card)
"16": "Chasse aux Trésors",
"17": "Monstre Insectoide Géant - Gohma",
"18": "Dinosaure Infernal - King Dodongo",
"19": "Anémone Bio-Electrique - Barinade",
"20": "Esprit Maléfique de l'Au-Delà - Ganon Spectral",
"21": "Dragon des Profondeurs - Volcania",
"22": "Amibe Aquatique Géante - Morpha",
"23": "Sorcières Jumelles - Duo Maléfique",
"24": "Monstre de l'Ombre - Bongo Bongo",
"25": "Seigneur du Malin - Ganondorf",
"26": "",
"27": "", // Entrée vers le Marché (No title card)
"28": "",
"29": "",
"30": "Ruelle",
"31": "Ruelle",
"32": "Place du Marché",
"33": "Place du Marché",
"34": "Place du Marché",
"35": "", // Extérieur du Temple du Temps (No title card)
"36": "SCENE_SHRINE_N",
"37": "SCENE_SHRINE_R",
"38": "", // Cabane des Frères Je-Sais-Tout (No title card)
"39": "", // Cabane des Jumelles (No title card)
"40": "", // Cabane du Grand Mido (No title card)
"41": "", // Cabane de Saria (No title card)
"42": "", // Maison du Village Cocorico 1 (No title card)
"43": "", // Maison de la Ruelle 1 (No title card)
"44": "Bazar",
"45": "Boutique Kokiri",
"46": "Boutique Goron",
"47": "Boutique Zora",
"48": "", // Magasin Fermé (No title card)
"49": "Apothicaire",
"50": "", // Magasin de Missiles (No title card)
"51": "Foire aux Masques",
"52": "", // Cabane de Link (No title card)
"53": "", // Dog Lady's House (No title card)
"54": "Étable",
"55": "", // Maison d'Impa (No title card)
"56": "Laboratoire du Lac",
"57": "", // Tente du Marathonien (No title card)
"58": "Cabane du fossoyeur",
"59": "Fountaine Royale des Fées",
"60": "Fountaine des Fées",
"61": "Fountaine Royale des Fées",
"62": "", // Grottes (No title card)
"63": "", // Tombe 1 (No title card)
"64": "", // Tombe 2 (No title card)
"65": "Tombe Royale",
"66": "Jeu d'adresse",
"67": "Temple du Temps",
"68": "Sanctuaire des Sages",
"69": "Cour du Château",
"70": "Cour du Château",
"71": "", // Goddesses Cutscene (No title card)
"72": "Endroit Inconnu",
"73": "Étang",
"74": "Cour du Château",
"75": "Bowling Teigneux",
"76": "", // Lon Lon Ranch House/Silo (No title card)
"77": "", // Guard House (No title card)
"78": "", // Potion Shop (No title card)
"79": "Ganon",
"80": "Maison des Araignées",
"81": "Plaine d'Hyrule",
"82": "Village Cocorico",
"83": "Cimetière",
"84": "Fleuve Zora",
"85": "Forêt Kokiri",
"86": "Bosquet Sacré",
"87": "Lac Hylia",
"88": "Domaine Zora",
"89": "Fontaine Zora",
"90": "Vallée Gerudo",
"91": "Bois Perdu",
"92": "Colosse du Désert",
"93": "Forteresse Gerudo",
"94": "Désert Hanté",
"95": "Château d'Hyrule",
"96": "Chemin du Péril",
"97": "Cratère du Péril",
"98": "Village Goron",
"99": "Ranch Lon Lon",
"100": "",
"101": "", // Debug: Test Map (No title card)
"102": "", // Debug: Test Room (No title card)
"103": "", // Debug: Depth Test (No title card)
"104": "", // Debug: Stalfos Miniboss Room (No title card)
"105": "", // Debug: Stalfos Boss Room (No title card)
"106": "", // Debug: Dark Link Room (No title card)
"107": "",
"108": "", // Debug: SRD Room (No title card)
"109": "" // Debug: Treasure Chest Warp (No title card)
}

View File

@@ -0,0 +1,112 @@
{
"0": "Im Deku-Baum",
"1": "Dodongos Höhle",
"2": "Jabu-Jabus Bauch",
"3": "Waldtempel",
"4": "Feuertempel",
"5": "Wassertempel",
"6": "Geistertempel",
"7": "Schattentempel",
"8": "Grund des Brunnens",
"9": "Eishöhle",
"10": "", // Treppe zu Ganondorfs Verließ (Keine Title-Card)
"11": "Gerudo-Arena",
"12": "Diebesversteck",
"13": "Ganons Schloß",
"14": "", // Flucht aus Ganons Schloß (Keine Title-Card)
"15": "", // Flucht aus Ganons Schloß 5 (Keine Title-Card)
"16": "Truhenlotterie",
"17": "Gepanzerter Spinnenparasit - Gohma",
"18": "Infernosaurus - King Dodongo",
"19": "Elektroterristrisches Biotentakel - Barinade",
"20": "Reitendes Unheil - Phantom-Ganon",
"21": "Subterraner Lavadrachoid - Volvagia",
"22": "Aquamöbes Wassertentakel - Morpha",
"23": "Höllische Hexenarmada - Killa Ohmaz",
"24": "Bestialische Schattenmonstrosität - Bongo Bongo",
"25": "Großmeister des Bösen - Ganondorf",
"26": "",
"27": "", // Eingang zum Marktplatz (Keine Title-Card)
"28": "",
"29": "",
"30": "Seitenstraße",
"31": "Seitenstraße",
"32": "Marktplatz",
"33": "Marktplatz",
"34": "Marktplatz",
"35": "", // Vor der Zitadelle der Zeit (Keine Title-Card)
"36": "SCENE_SHRINE_N",
"37": "SCENE_SHRINE_R",
"38": "", // Haus der Allwissenden Brüder (Keine Title-Card)
"39": "", // Haus der Zwillinge (Keine Title-Card)
"40": "", // Midos Haus (Keine Title-Card)
"41": "", // Salias Haus (Keine Title-Card)
"42": "", // Kakariko Haus 1 (Keine Title-Card)
"43": "", // Steinstraßen Haus 1 (Keine Title-Card)
"44": "Basar",
"45": "Kokiri-Laden",
"46": "Goronen-Laden",
"47": "Zora-Laden",
"48": "", // Geschlossener Laden (Keine Title-Card)
"49": "Magie-Laden",
"50": "", // Krabbelminen-Laden (Keine Title-Card)
"51": "Maskenhändler",
"52": "", // Links Haus (Keine Title-Card)
"53": "", // Haus der Hunde-Dame (Keine Title-Card)
"54": "Stall",
"55": "", // Impas Haus (Keine Title-Card)
"56": "Hylia-See Laboratorium",
"57": "", // Zelt des Rennläufers (Keine Title-Card)
"58": "Hütte des Totengräbers",
"59": "Feen-Quelle",
"60": "Feen-Brunnen",
"61": "Feen-Quelle",
"62": "", // Grotten (Keine Title-Card)
"63": "", // Grab 1 (Keine Title-Card)
"64": "", // Grab 2 (Keine Title-Card)
"65": "Königsgrab",
"66": "Schießbude",
"67": "Zitadelle der Zeit",
"68": "Halle der Weisen",
"69": "Burghof",
"70": "Burghof",
"71": "", // Göttinnen Cutscene (Keine Title-Card)
"72": "Unbekannter Ort",
"73": "Fischweiher",
"74": "Burghof",
"75": "Minenbowlingbahn",
"76": "", // Lon Lon-Farm Haus/Silo (Keine Title-Card)
"77": "", // Wachposten (Keine Title-Card)
"78": "", // Magie-Laden (Keine Title-Card)
"79": "Ganon",
"80": "Skulltulas Haus",
"81": "Hylianische Steppe",
"82": "Kakariko",
"83": "Friedhof",
"84": "Zora-Fluß",
"85": "Kokiri-Wald",
"86": "Waldlichtung",
"87": "Hylia-See",
"88": "Zoras Reich",
"89": "Zoras Quelle",
"90": "Gerudotal",
"91": "Verlorene Wälder",
"92": "Wüstenkoloss",
"93": "Gerudo-Festung",
"94": "Geisterwüste",
"95": "Schloß Hyrule",
"96": "Pfad zum Todesberg",
"97": "Todeskrater",
"98": "Goronia",
"99": "Lon Lon-Farm",
"100": "",
"101": "", // Debug: Test Karte (Keine Title-Card)
"102": "", // Debug: Test Raum (Keine Title-Card)
"103": "", // Debug: Tiefen Test (Keine Title-Card)
"104": "", // Debug: Stalfos-Ritter Miniboss Raum (Keine Title-Card)
"105": "", // Debug: Stalfos-Ritter Boss Raum (Keine Title-Card)
"106": "", // Debug: Schwarzer Link Raum (Keine Title-Card)
"107": "",
"108": "", // Debug: SRD Raum (Keine Title-Card)
"109": "" // Debug: Schatzkisten Teleport (Keine Title-Card)
}

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,5 @@
<DisplayList Version="0">
<Grayscale Enabled="false"/>
<EndDisplayList/>
</DisplayList>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -0,0 +1,13 @@
<DisplayList Version="0">
<CallDisplayList Path="objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_edges"/>
<CallDisplayList Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_0"/>
<CallDisplayList Path="objects/object_triforce_completed/mat_gTriforcePieceCompletedDL_f3dlite_triforce_surface"/>
<CallDisplayList Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_tri_1"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View File

@@ -0,0 +1,58 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="4" V01="3" V02="0"/>
<Triangle1 V00="5" V01="3" V02="4"/>
<Triangle1 V00="5" V01="4" V02="6"/>
<Triangle1 V00="4" V01="7" V02="6"/>
<Triangle1 V00="7" V01="8" V02="6"/>
<Triangle1 V00="7" V01="9" V02="8"/>
<Triangle1 V00="6" V01="8" V02="1"/>
<Triangle1 V00="6" V01="1" V02="3"/>
<Triangle1 V00="10" V01="6" V02="3"/>
<Triangle1 V00="10" V01="3" V02="11"/>
<Triangle1 V00="5" V01="11" V02="3"/>
<Triangle1 V00="5" V01="6" V02="10"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="12" V01="14" V02="15"/>
<LoadVertices Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0" VertexBufferIndex="0" VertexOffset="16" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="4" V01="0" V02="3"/>
<Triangle1 V00="4" V01="3" V02="5"/>
<Triangle1 V00="6" V01="0" V02="4"/>
<Triangle1 V00="7" V01="0" V02="6"/>
<Triangle1 V00="7" V01="6" V02="1"/>
<Triangle1 V00="6" V01="8" V02="1"/>
<Triangle1 V00="7" V01="1" V02="9"/>
<Triangle1 V00="10" V01="9" V02="1"/>
<Triangle1 V00="10" V01="1" V02="0"/>
<Triangle1 V00="7" V01="10" V02="0"/>
<Triangle1 V00="11" V01="12" V02="13"/>
<Triangle1 V00="11" V01="13" V02="14"/>
<Triangle1 V00="13" V01="15" V02="14"/>
<LoadVertices Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0" VertexBufferIndex="0" VertexOffset="32" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="4" V01="3" V02="2"/>
<Triangle1 V00="2" V01="5" V02="4"/>
<Triangle1 V00="2" V01="6" V02="5"/>
<Triangle1 V00="7" V01="5" V02="6"/>
<Triangle1 V00="6" V01="8" V02="7"/>
<Triangle1 V00="7" V01="8" V02="9"/>
<Triangle1 V00="7" V01="9" V02="10"/>
<Triangle1 V00="11" V01="10" V02="9"/>
<Triangle1 V00="0" V01="11" V02="9"/>
<Triangle1 V00="0" V01="12" V02="11"/>
<Triangle1 V00="7" V01="4" V02="5"/>
<Triangle1 V00="13" V01="4" V02="5"/>
<Triangle1 V00="13" V01="5" V02="6"/>
<Triangle1 V00="13" V01="6" V02="14"/>
<Triangle1 V00="13" V01="14" V02="15"/>
<LoadVertices Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_0" VertexBufferIndex="0" VertexOffset="48" Count="4"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<EndDisplayList/>
</DisplayList>

View File

@@ -0,0 +1,7 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_triforce_completed/gTriforcePieceCompletedDL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="6"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="3" V01="4" V02="5"/>
<EndDisplayList/>
</DisplayList>

View File

@@ -0,0 +1,54 @@
<Vertex Version="0">
<Vtx X="883" Y="-475" Z="103" S="344" T="380" R="103" G="6" B="75" A="255"/>
<Vtx X="809" Y="-497" Z="100" S="304" T="393" R="1" G="143" B="58" A="255"/>
<Vtx X="884" Y="-496" Z="96" S="345" T="393" R="78" G="166" B="46" A="255"/>
<Vtx X="856" Y="-477" Z="114" S="328" T="380" R="25" G="227" B="121" A="255"/>
<Vtx X="0" Y="945" Z="114" S="-58" T="-321" R="177" G="83" B="55" A="255"/>
<Vtx X="0" Y="870" Z="116" S="-58" T="-283" R="221" G="3" B="122" A="255"/>
<Vtx X="-856" Y="-477" Z="114" S="-437" T="380" R="231" G="227" B="121" A="255"/>
<Vtx X="-883" Y="-475" Z="103" S="-452" T="380" R="153" G="6" B="75" A="255"/>
<Vtx X="-809" Y="-497" Z="100" S="-412" T="393" R="255" G="143" B="58" A="255"/>
<Vtx X="-884" Y="-496" Z="96" S="-453" T="392" R="178" G="166" B="46" A="255"/>
<Vtx X="-817" Y="-464" Z="116" S="-414" T="369" R="254" G="251" B="127" A="255"/>
<Vtx X="817" Y="-464" Z="116" S="304" T="369" R="2" G="251" B="127" A="255"/>
<Vtx X="883" Y="-475" Z="-106" S="-460" T="380" R="103" G="6" B="181" A="255"/>
<Vtx X="884" Y="-496" Z="-99" S="-461" T="393" R="78" G="166" B="210" A="255"/>
<Vtx X="809" Y="-497" Z="-103" S="-420" T="393" R="1" G="143" B="198" A="255"/>
<Vtx X="856" Y="-477" Z="-117" S="-444" T="380" R="25" G="227" B="135" A="255"/>
<Vtx X="-856" Y="-477" Z="-117" S="320" T="380" R="231" G="227" B="135" A="255"/>
<Vtx X="856" Y="-477" Z="-117" S="-444" T="380" R="25" G="227" B="135" A="255"/>
<Vtx X="809" Y="-497" Z="-103" S="-420" T="393" R="1" G="143" B="198" A="255"/>
<Vtx X="-809" Y="-497" Z="-103" S="296" T="393" R="255" G="143" B="198" A="255"/>
<Vtx X="-883" Y="-475" Z="-106" S="336" T="380" R="153" G="6" B="181" A="255"/>
<Vtx X="-884" Y="-496" Z="-99" S="337" T="392" R="178" G="166" B="210" A="255"/>
<Vtx X="0" Y="945" Z="-117" S="-58" T="-321" R="177" G="83" B="201" A="255"/>
<Vtx X="0" Y="870" Z="-120" S="-58" T="-283" R="228" G="24" B="134" A="255"/>
<Vtx X="883" Y="-475" Z="-106" S="-460" T="380" R="103" G="6" B="181" A="255"/>
<Vtx X="817" Y="-464" Z="-120" S="-421" T="369" R="1" G="254" B="129" A="255"/>
<Vtx X="-817" Y="-464" Z="-120" S="297" T="369" R="255" G="254" B="129" A="255"/>
<Vtx X="-884" Y="-496" Z="-99" S="-149" T="-277" R="178" G="166" B="210" A="255"/>
<Vtx X="-809" Y="-497" Z="-103" S="-149" T="-277" R="255" G="143" B="198" A="255"/>
<Vtx X="809" Y="-497" Z="-103" S="-149" T="-277" R="1" G="143" B="198" A="255"/>
<Vtx X="884" Y="-496" Z="96" S="-149" T="-277" R="78" G="166" B="46" A="255"/>
<Vtx X="884" Y="-496" Z="-99" S="-149" T="-277" R="78" G="166" B="210" A="255"/>
<Vtx X="884" Y="-496" Z="96" S="-149" T="-277" R="78" G="166" B="46" A="255"/>
<Vtx X="884" Y="-496" Z="-99" S="-149" T="-277" R="78" G="166" B="210" A="255"/>
<Vtx X="883" Y="-475" Z="-106" S="-149" T="-277" R="103" G="6" B="181" A="255"/>
<Vtx X="883" Y="-475" Z="103" S="-149" T="-277" R="103" G="6" B="75" A="255"/>
<Vtx X="0" Y="945" Z="114" S="107" T="-277" R="177" G="83" B="55" A="255"/>
<Vtx X="0" Y="945" Z="-1" S="107" T="-149" R="169" G="92" B="0" A="255"/>
<Vtx X="0" Y="945" Z="-117" S="107" T="-277" R="177" G="83" B="201" A="255"/>
<Vtx X="-883" Y="-475" Z="103" S="-149" T="-277" R="153" G="6" B="75" A="255"/>
<Vtx X="-883" Y="-475" Z="-106" S="-149" T="-277" R="153" G="6" B="181" A="255"/>
<Vtx X="-884" Y="-496" Z="-99" S="-149" T="-277" R="178" G="166" B="210" A="255"/>
<Vtx X="-884" Y="-496" Z="96" S="-149" T="-277" R="178" G="166" B="46" A="255"/>
<Vtx X="-809" Y="-497" Z="100" S="-149" T="-277" R="255" G="143" B="58" A="255"/>
<Vtx X="809" Y="-497" Z="100" S="-149" T="-277" R="1" G="143" B="58" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="107" T="-149" R="165" G="0" B="89" A="255"/>
<Vtx X="0" Y="870" Z="-120" S="107" T="-277" R="221" G="3" B="134" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="235" T="-149" R="0" G="0" B="127" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="107" T="-149" R="165" G="0" B="89" A="255"/>
<Vtx X="0" Y="874" Z="-1" S="235" T="-149" R="0" G="0" B="127" A="255"/>
<Vtx X="0" Y="870" Z="116" S="107" T="-277" R="221" G="3" B="122" A="255"/>
<Vtx X="0" Y="945" Z="114" S="107" T="-277" R="177" G="83" B="55" A="255"/>
</Vertex>

View File

@@ -0,0 +1,8 @@
<Vertex Version="0">
<Vtx X="0" Y="870" Z="-120" S="-280" T="103" R="228" G="24" B="134" A="255"/>
<Vtx X="817" Y="-464" Z="-120" S="75" T="-550" R="1" G="254" B="129" A="255"/>
<Vtx X="-817" Y="-464" Z="-120" S="438" T="103" R="255" G="254" B="129" A="255"/>
<Vtx X="0" Y="870" Z="116" S="-280" T="103" R="221" G="3" B="122" A="255"/>
<Vtx X="-817" Y="-464" Z="116" S="438" T="103" R="254" G="251" B="127" A="255"/>
<Vtx X="817" Y="-464" Z="116" S="75" T="-550" R="2" G="251" B="127" A="255"/>
</Vertex>

View File

@@ -0,0 +1,21 @@
<DisplayList Version="0">
<PipeSync/>
<SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_TEXEL0" D0="G_CCMUX_TEXEL0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_TEXTURE_GEN="1" G_SHADING_SMOOTH="1" />
<ClearGeometryMode G_CULL_FRONT="1" G_TEXTURE_GEN_LINEAR="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_FOG_SHADE_A="1" G_RM_AA_ZB_OPA_SURF2="1" />
<Texture S="1966" T="1966" Level="0" Tile="0" On="1"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_triforce_completed/noise_tex" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Line="0" TMem="0" Tile="7" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<LoadSync/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="1023" Dxt="256"/>
<PipeSync/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b" Line="8" TMem="0" Tile="0" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="124" Lrt="124"/>
<SetPrimColor M="0" L="0" R="255" G="195" B="0" A="255"/>
<EndDisplayList/>
</DisplayList>

View File

@@ -0,0 +1,21 @@
<DisplayList Version="0">
<PipeSync/>
<SetCombineLERP A0="G_CCMUX_TEXEL0" B0="G_CCMUX_0" C0="G_CCMUX_TEXEL0" D0="G_CCMUX_TEXEL0" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_1" A1="G_CCMUX_COMBINED" B1="G_CCMUX_0" C1="G_CCMUX_PRIMITIVE" D1="G_CCMUX_0" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_COMBINED"/>
<SetGeometryMode G_ZBUFFER="1" G_SHADE="1" G_CULL_BACK="1" G_FOG="1" G_LIGHTING="1" G_TEXTURE_GEN="1" G_SHADING_SMOOTH="1" />
<ClearGeometryMode G_CULL_FRONT="1" G_TEXTURE_GEN_LINEAR="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_H" Sft="4" Length="20" G_AD_NOISE="1" G_CD_MAGICSQ="1" G_CK_NONE="1" G_TC_FILT="1" G_TF_BILERP="1" G_TL_TILE="1" G_TD_CLAMP="1" G_TP_PERSP="1" G_CYC_2CYCLE="1" G_PM_NPRIMITIVE="1" />
<SetOtherMode Cmd="G_SETOTHERMODE_L" Sft="0" Length="32" G_AC_NONE="1" G_ZS_PIXEL="1" G_RM_FOG_SHADE_A="1" G_RM_AA_ZB_OPA_SURF2="1" />
<Texture S="2621" T="1311" Level="0" Tile="0" On="1"/>
<SetTextureLUT Mode="G_TT_NONE"/>
<TileSync/>
<SetTextureImage Path="objects/object_triforce_completed/noise_tex" Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Width="1"/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b_LOAD_BLOCK" Line="0" TMem="0" Tile="7" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<LoadSync/>
<LoadBlock Tile="7" Uls="0" Ult="0" Lrs="1023" Dxt="256"/>
<PipeSync/>
<SetTile Format="G_IM_FMT_RGBA" Size="G_IM_SIZ_16b" Line="8" TMem="0" Tile="0" Palette="0" Cms0="G_TX_WRAP" Cms1="G_TX_NOMIRROR" Cmt0="G_TX_WRAP" Cmt1="G_TX_NOMIRROR" MaskS="5" ShiftS="0" MaskT="5" ShiftT="0"/>
<SetTileSize T="0" Uls="0" Ult="0" Lrs="124" Lrt="124"/>
<SetPrimColor M="0" L="0" R="255" G="195" B="0" A="255"/>
<EndDisplayList/>
</DisplayList>

View File

@@ -0,0 +1,15 @@
<DisplayList Version="0">
<CallDisplayList Path="objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_surface"/>
<CallDisplayList Path="objects/object_triforce_piece_0/gTriforcePiece0DL_tri_0"/>
<CallDisplayList Path="objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_triforce_edges"/>
<CallDisplayList Path="objects/object_triforce_piece_0/gTriforcePiece0DL_tri_1"/>
<CallDisplayList Path="objects/object_triforce_piece_0/mat_gTriforcePiece0DL_f3dlite_shard_edge"/>
<CallDisplayList Path="objects/object_triforce_piece_0/gTriforcePiece0DL_tri_2"/>
<PipeSync/>
<SetGeometryMode G_LIGHTING="1" />
<ClearGeometryMode G_TEXTURE_GEN="1" />
<SetCombineLERP A0="G_CCMUX_0" B0="G_CCMUX_0" C0="G_CCMUX_0" D0="G_CCMUX_SHADE" Aa0="G_ACMUX_0" Ab0="G_ACMUX_0" Ac0="G_ACMUX_0" Ad0="G_ACMUX_ENVIRONMENT" A1="G_CCMUX_0" B1="G_CCMUX_0" C1="G_CCMUX_0" D1="G_CCMUX_SHADE" Aa1="G_ACMUX_0" Ab1="G_ACMUX_0" Ac1="G_ACMUX_0" Ad1="G_ACMUX_ENVIRONMENT"/>
<Texture S="65535" T="65535" Level="0" Tile="0" On="0"/>
<EndDisplayList/>
</DisplayList>

View File

@@ -0,0 +1,17 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_0" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<Triangle1 V00="1" V01="3" V02="4"/>
<Triangle1 V00="1" V01="4" V02="5"/>
<Triangle1 V00="5" V01="4" V02="6"/>
<Triangle1 V00="5" V01="6" V02="7"/>
<Triangle1 V00="8" V01="9" V02="10"/>
<Triangle1 V00="8" V01="10" V02="11"/>
<Triangle1 V00="11" V01="10" V02="12"/>
<Triangle1 V00="10" V01="13" V02="12"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="12" V01="14" V02="15"/>
<EndDisplayList/>
</DisplayList>

View File

@@ -0,0 +1,18 @@
<DisplayList Version="0">
<LoadVertices Path="objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_1" VertexBufferIndex="0" VertexOffset="0" Count="16"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="2" V02="3"/>
<Triangle1 V00="4" V01="0" V02="3"/>
<Triangle1 V00="4" V01="3" V02="5"/>
<Triangle1 V00="6" V01="7" V02="8"/>
<Triangle1 V00="6" V01="9" V02="7"/>
<Triangle1 V00="10" V01="7" V02="9"/>
<Triangle1 V00="10" V01="11" V02="7"/>
<Triangle1 V00="12" V01="13" V02="14"/>
<Triangle1 V00="12" V01="15" V02="13"/>
<LoadVertices Path="objects/object_triforce_piece_0/gTriforcePiece0DL_vtx_1" VertexBufferIndex="0" VertexOffset="16" Count="4"/>
<Triangle1 V00="0" V01="1" V02="2"/>
<Triangle1 V00="0" V01="3" V02="1"/>
<EndDisplayList/>
</DisplayList>

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