subrepo:
  subdir:   "ZAPDTR"
  merged:   "a53a53ea4"
upstream:
  origin:   "https://github.com/HarbourMasters/ZAPDTR.git"
  branch:   "master"
  commit:   "a53a53ea4"
git-subrepo:
  version:  "0.4.1"
  origin:   "???"
  commit:   "???"
This commit is contained in:
M4xw 2022-03-22 02:54:48 +01:00
parent f52a2a6406
commit 5dda5762ba
217 changed files with 47152 additions and 0 deletions

84
ZAPDTR/.clang-format Normal file
View File

@ -0,0 +1,84 @@
---
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlinesLeft: false
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: InlineOnly
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: true
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
BeforeCatch: true
BeforeElse: true
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: false
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 100
CommentPragmas: '^ (IWYU pragma:|NOLINT)'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ForEachMacros: [ ]
IncludeCategories:
- Regex: '^<[Ww]indows\.h>$'
Priority: 1
- Regex: '^<'
Priority: 2
- Regex: '^"'
Priority: 3
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Latest
TabWidth: 4
UseTab: AlignWithSpaces
...

341
ZAPDTR/.gitignore vendored Normal file
View File

@ -0,0 +1,341 @@
## 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

12
ZAPDTR/.gitrepo Normal file
View File

@ -0,0 +1,12 @@
; DO NOT EDIT (unless you know what you are doing)
;
; This subdirectory is a git "subrepo", and this file is maintained by the
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
;
[subrepo]
remote = https://github.com/HarbourMasters/ZAPDTR.git
branch = master
commit = a53a53ea4216b926253dde2c942ae0ca6e2f2ccd
parent = f52a2a6406eb1bbd2b631c65923d879a83983ccb
method = rebase
cmdver = 0.4.1

View File

@ -0,0 +1,74 @@
#include "CollisionExporter.h"
void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]] fs::path outPath,
BinaryWriter* writer)
{
ZCollisionHeader* col = (ZCollisionHeader*)res;
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(col->numVerts);
writer->Write(col->vtxAddress);
writer->Write(col->numPolygons);
writer->Write(col->polyAddress);
writer->Write(col->polyTypeDefAddress);
writer->Write(col->camDataAddress);
writer->Write(col->numWaterBoxes);
writer->Write(col->waterBoxAddress);
writer->Write(col->vtxSegmentOffset);
writer->Write(col->polySegmentOffset);
writer->Write(col->polyTypeDefSegmentOffset);
writer->Write(col->camDataSegmentOffset);
writer->Write(col->waterBoxSegmentOffset);
uint32_t oldOffset = writer->GetBaseAddress();
writer->Seek(col->vtxSegmentOffset, SeekOffsetType::Start);
for (uint16_t i = 0; i < col->vertices.size(); i++)
{
for (uint32_t j = 0; j < col->vertices[i].dimensions; j++)
{
writer->Write(col->vertices[i].scalars[j].scalarData.s16);
}
}
writer->Seek(col->polySegmentOffset, SeekOffsetType::Start);
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].a);
writer->Write(col->polygons[i].b);
writer->Write(col->polygons[i].c);
writer->Write(col->polygons[i].d);
}
writer->Seek(col->polyTypeDefSegmentOffset, SeekOffsetType::Start);
for (uint16_t i = 0; i < col->polygonTypes.size(); i++)
writer->Write(col->polygonTypes[i]);
writer->Seek(col->camDataSegmentOffset, SeekOffsetType::Start);
for (auto entry : col->camData->entries)
{
writer->Write(entry->cameraSType);
writer->Write(entry->numData);
writer->Write(entry->cameraPosDataSeg);
}
writer->Seek(oldOffset, SeekOffsetType::Start);
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "ZCollision.h"
#include "ZResource.h"
class ExporterExample_Collision : public ZResourceExporter
{
public:
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
};

View File

@ -0,0 +1,160 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{65608eb0-1a47-45ad-ab66-192fb64c762c}</ProjectGuid>
<RootNamespace>ExporterTest</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>ExporterExample</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<IncludePath>$(ProjectDir)..\ZAPD\;$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="CollisionExporter.h" />
<ClInclude Include="TextureExporter.h" />
<ClInclude Include="RoomExporter.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CollisionExporter.cpp" />
<ClCompile Include="TextureExporter.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="RoomExporter.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="TextureExporter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RoomExporter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CollisionExporter.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="TextureExporter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RoomExporter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CollisionExporter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,79 @@
#include "CollisionExporter.h"
#include "Globals.h"
#include "RoomExporter.h"
#include "TextureExporter.h"
enum class ExporterFileMode
{
ModeExample1 = (int)ZFileMode::Custom + 1,
ModeExample2 = (int)ZFileMode::Custom + 2,
ModeExample3 = (int)ZFileMode::Custom + 3,
};
static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileMode)
{
if (buildMode == "me1")
fileMode = (ZFileMode)ExporterFileMode::ModeExample1;
else if (buildMode == "me2")
fileMode = (ZFileMode)ExporterFileMode::ModeExample2;
else if (buildMode == "me3")
fileMode = (ZFileMode)ExporterFileMode::ModeExample3;
}
static void ExporterParseArgs([[maybe_unused]] int argc, char* argv[], int& i)
{
std::string arg = argv[i];
if (arg == "--do-x")
{
}
else if (arg == "--do-y")
{
}
}
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::ModeExample1)
return true;
else if (fileMode == (ZFileMode)ExporterFileMode::ModeExample2)
return true;
else if (fileMode == (ZFileMode)ExporterFileMode::ModeExample3)
return true;
return false;
}
static void ExporterFileBegin(ZFile* file)
{
printf("ExporterFileBegin() called on ZFile %s.\n", file->GetName().c_str());
}
static void ExporterFileEnd(ZFile* file)
{
printf("ExporterFileEnd() called on ZFile %s.\n", file->GetName().c_str());
}
static 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->parseArgsFunc = ExporterParseArgs;
exporterSet->beginFileFunc = ExporterFileBegin;
exporterSet->endFileFunc = ExporterFileEnd;
exporterSet->exporters[ZResourceType::Texture] = new ExporterExample_Texture();
exporterSet->exporters[ZResourceType::Room] = new ExporterExample_Room();
exporterSet->exporters[ZResourceType::CollisionHeader] = new ExporterExample_Collision();
Globals::AddExporter("EXAMPLE", exporterSet);
}
// When ZAPD starts up, it will automatically call the below function, which in turn sets up our
// exporters.
REGISTER_EXPORTER(ImportExporters);

View File

@ -0,0 +1,28 @@
# Only used for standalone compilation, usually inherits these from the main makefile
CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17
SRC_DIRS := $(shell find . -type d -not -path "*build*")
CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp))
H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h))
O_FILES := $(foreach f,$(CPP_FILES:.cpp=.o),build/$f)
LIB := ExporterTest.a
# create build directories
$(shell mkdir -p $(foreach dir,$(SRC_DIRS),build/$(dir)))
all: $(LIB)
clean:
rm -rf build $(LIB)
format:
clang-format-11 -i $(CPP_FILES) $(H_FILES)
.PHONY: all clean format
build/%.o: %.cpp
$(CXX) $(CXXFLAGS) $(OPTFLAGS) -I ./ -I ../ZAPD -I ../ZAPDUtils -I ../lib/tinyxml2 -c $(OUTPUT_OPTION) $<
$(LIB): $(O_FILES)
$(AR) rcs $@ $^

View File

@ -0,0 +1,372 @@
#include "RoomExporter.h"
#include "CollisionExporter.h"
#include "Utils/BinaryWriter.h"
#include "Utils/File.h"
#include "Utils/MemoryStream.h"
#include "ZRoom/Commands/SetCameraSettings.h"
#include "ZRoom/Commands/SetCollisionHeader.h"
#include "ZRoom/Commands/SetCsCamera.h"
#include "ZRoom/Commands/SetEchoSettings.h"
#include "ZRoom/Commands/SetEntranceList.h"
#include "ZRoom/Commands/SetLightingSettings.h"
#include "ZRoom/Commands/SetMesh.h"
#include "ZRoom/Commands/SetRoomBehavior.h"
#include "ZRoom/Commands/SetRoomList.h"
#include "ZRoom/Commands/SetSkyboxModifier.h"
#include "ZRoom/Commands/SetSkyboxSettings.h"
#include "ZRoom/Commands/SetSoundSettings.h"
#include "ZRoom/Commands/SetSpecialObjects.h"
#include "ZRoom/Commands/SetStartPositionList.h"
#include "ZRoom/Commands/SetTimeSettings.h"
#include "ZRoom/Commands/SetWind.h"
void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* writer)
{
ZRoom* room = dynamic_cast<ZRoom*>(res);
// MemoryStream* memStream = new MemoryStream();
// BinaryWriter* writer = new BinaryWriter(memStream);
for (size_t i = 0; i < room->commands.size() * 8; i++)
writer->Write((uint8_t)0);
for (size_t i = 0; i < room->commands.size(); i++)
{
ZRoomCommand* cmd = room->commands[i];
writer->Seek(i * 8, SeekOffsetType::Start);
writer->Write((uint8_t)cmd->cmdID);
switch (cmd->cmdID)
{
case RoomCommand::SetWind:
{
SetWind* cmdSetWind = (SetWind*)cmd;
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
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((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(cmdTime->hour); // 0x04
writer->Write(cmdTime->min); // 0x05
writer->Write(cmdTime->unk); // 0x06
writer->Write((uint8_t)0); // 0x07
}
break;
case RoomCommand::SetSkyboxModifier:
{
SetSkyboxModifier* cmdSkybox = (SetSkyboxModifier*)cmd;
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(cmdSkybox->disableSky); // 0x04
writer->Write(cmdSkybox->disableSunMoon); // 0x05
writer->Write((uint8_t)0); // 0x06
writer->Write((uint8_t)0); // 0x07
}
break;
case RoomCommand::SetEchoSettings:
{
SetEchoSettings* cmdEcho = (SetEchoSettings*)cmd;
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write((uint8_t)0); // 0x04
writer->Write((uint8_t)0); // 0x05
writer->Write((uint8_t)0); // 0x06
writer->Write((uint8_t)cmdEcho->echo); // 0x07
}
break;
case RoomCommand::SetSoundSettings:
{
SetSoundSettings* cmdSound = (SetSoundSettings*)cmd;
writer->Write((uint8_t)cmdSound->reverb); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write((uint8_t)0); // 0x04
writer->Write((uint8_t)0); // 0x05
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)0); // 0x02
writer->Write((uint8_t)0); // 0x03
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;
writer->Write((uint8_t)cmdRoom->gameplayFlags); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(cmdRoom->gameplayFlags2); // 0x04
}
break;
case RoomCommand::SetCsCamera:
{
SetCsCamera* cmdCsCam = (SetCsCamera*)cmd;
writer->Write((uint8_t)cmdCsCam->cameras.size()); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(cmdCsCam->segmentOffset); // 0x04
}
break;
case RoomCommand::SetMesh:
{
SetMesh* cmdMesh = (SetMesh*)cmd;
int baseStreamEnd = writer->GetStream().get()->GetLength();
writer->Write((uint8_t)cmdMesh->data); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(baseStreamEnd); // 0x04
uint32_t oldOffset = writer->GetBaseAddress();
writer->Seek(baseStreamEnd, SeekOffsetType::Start);
// TODO: NOT DONE
writer->Write(cmdMesh->meshHeaderType);
if (cmdMesh->meshHeaderType == 0)
{
// writer->Write(cmdMesh->)
}
else if (cmdMesh->meshHeaderType == 1)
{
}
else if (cmdMesh->meshHeaderType == 2)
{
}
writer->Seek(oldOffset, SeekOffsetType::Start);
}
break;
case RoomCommand::SetCameraSettings:
{
SetCameraSettings* cmdCam = (SetCameraSettings*)cmd;
writer->Write((uint8_t)cmdCam->cameraMovement); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(cmdCam->mapHighlight); // 0x04
}
break;
case RoomCommand::SetLightingSettings:
{
SetLightingSettings* cmdLight = (SetLightingSettings*)cmd;
writer->Write((uint8_t)cmdLight->settings.size()); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(cmdLight->segmentOffset); // 0x04
uint32_t oldOffset = writer->GetBaseAddress();
writer->Seek(cmdLight->segmentOffset, SeekOffsetType::Start);
for (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);
}
writer->Seek(oldOffset, SeekOffsetType::Start);
}
break;
case RoomCommand::SetRoomList:
{
SetRoomList* cmdRoom = (SetRoomList*)cmd;
writer->Write((uint8_t)cmdRoom->romfile->rooms.size()); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
auto baseStreamEnd = writer->GetLength();
writer->Write(baseStreamEnd); // 0x04
uint32_t oldOffset = writer->GetBaseAddress();
writer->Seek(baseStreamEnd, SeekOffsetType::Start);
for (const auto& entry : cmdRoom->romfile->rooms)
{
writer->Write(entry.virtualAddressStart);
writer->Write(entry.virtualAddressEnd);
}
writer->Seek(oldOffset, SeekOffsetType::Start);
}
break;
case RoomCommand::SetCollisionHeader:
{
SetCollisionHeader* cmdCollHeader = (SetCollisionHeader*)cmd;
int streamEnd = writer->GetStream().get()->GetLength();
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(streamEnd); // 0x04
// TODO: NOT DONE
uint32_t oldOffset = writer->GetBaseAddress();
writer->Seek(streamEnd, SeekOffsetType::Start);
ExporterExample_Collision colExp = ExporterExample_Collision();
colExp.Save(cmdCollHeader->collisionHeader, outPath, writer);
writer->Seek(oldOffset, SeekOffsetType::Start);
}
break;
case RoomCommand::SetEntranceList:
{
SetEntranceList* cmdEntrance = (SetEntranceList*)cmd;
uint32_t baseStreamEnd = writer->GetStream().get()->GetLength();
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(baseStreamEnd); // 0x04
uint32_t oldOffset = writer->GetBaseAddress();
writer->Seek(baseStreamEnd, SeekOffsetType::Start);
for (EntranceEntry entry : cmdEntrance->entrances)
{
writer->Write((uint8_t)entry.startPositionIndex);
writer->Write((uint8_t)entry.roomToLoad);
}
writer->Seek(oldOffset, SeekOffsetType::Start);
}
break;
case RoomCommand::SetSpecialObjects:
{
SetSpecialObjects* cmdSpecObj = (SetSpecialObjects*)cmd;
writer->Write((uint8_t)cmdSpecObj->elfMessage); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write((uint8_t)0); // 0x04
writer->Write((uint8_t)0); // 0x05
writer->Write((uint16_t)cmdSpecObj->globalObject); // 0x06
}
break;
case RoomCommand::SetStartPositionList:
{
SetStartPositionList* cmdStartPos = (SetStartPositionList*)cmd;
uint32_t baseStreamEnd = writer->GetStream().get()->GetLength();
writer->Write((uint8_t)cmdStartPos->actors.size()); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write(baseStreamEnd); // 0x04
uint32_t oldOffset = writer->GetBaseAddress();
writer->Seek(baseStreamEnd, SeekOffsetType::Start);
for (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.initVar);
}
writer->Seek(oldOffset, SeekOffsetType::Start);
}
break;
case RoomCommand::EndMarker:
{
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write((uint8_t)0); // 0x04
writer->Write((uint8_t)0); // 0x05
writer->Write((uint8_t)0); // 0x06
writer->Write((uint8_t)0); // 0x07
}
break;
default:
printf("UNIMPLEMENTED COMMAND: %i\n", (int)cmd->cmdID);
writer->Write((uint8_t)0); // 0x01
writer->Write((uint8_t)0); // 0x02
writer->Write((uint8_t)0); // 0x03
writer->Write((uint8_t)0); // 0x04
writer->Write((uint8_t)0); // 0x05
writer->Write((uint8_t)0); // 0x06
writer->Write((uint8_t)0); // 0x07
break;
}
}
// writer->Close();
// File::WriteAllBytes(StringHelper::Sprintf("%s", res->GetName().c_str()),
// memStream->ToVector());
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "ZResource.h"
#include "ZRoom/ZRoom.h"
class ExporterExample_Room : public ZResourceExporter
{
public:
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
};

View File

@ -0,0 +1,14 @@
#include "TextureExporter.h"
#include "../ZAPD/ZFile.h"
void ExporterExample_Texture::Save(ZResource* res, [[maybe_unused]] fs::path outPath,
BinaryWriter* writer)
{
ZTexture* tex = (ZTexture*)res;
auto data = tex->parent->GetRawData();
for (offset_t i = tex->GetRawDataIndex(); i < tex->GetRawDataIndex() + tex->GetRawDataSize();
i++)
writer->Write(data[i]);
}

View File

@ -0,0 +1,11 @@
#pragma once
#include "Utils/BinaryWriter.h"
#include "ZResource.h"
#include "ZTexture.h"
class ExporterExample_Texture : public ZResourceExporter
{
public:
void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) override;
};

97
ZAPDTR/Jenkinsfile vendored Normal file
View File

@ -0,0 +1,97 @@
pipeline {
agent {
label 'ZAPD'
}
stages {
// Non-parallel ZAPD stage
stage('Build ZAPD') {
steps {
sh 'make -j WERROR=1'
}
}
// CHECKOUT THE REPOS
stage('Checkout Repos') {
parallel {
stage('Checkout oot') {
steps {
dir('oot') {
git url: 'https://github.com/zeldaret/oot.git'
}
}
}
stage('Checkout mm') {
steps{
dir('mm') {
git url: 'https://github.com/zeldaret/mm.git'
}
}
}
}
}
// SETUP THE REPOS
stage('Set up repos') {
parallel {
stage('Setup OOT') {
steps {
dir('oot') {
sh 'cp /usr/local/etc/roms/baserom_oot.z64 baserom_original.z64'
// Identical to `make setup` except for copying our newer ZAPD.out into oot
sh 'git submodule update --init --recursive'
sh 'make -C tools'
sh 'cp ../ZAPD.out tools/ZAPD/'
sh 'python3 fixbaserom.py'
sh 'python3 extract_baserom.py'
sh 'python3 extract_assets.py'
}
}
}
stage('Setup MM') {
steps {
dir('mm') {
sh 'cp /usr/local/etc/roms/mm.us.rev1.z64 baserom.mm.us.rev1.z64'
// Identical to `make setup` except for copying our newer ZAPD.out into mm
sh 'make -C tools'
sh 'cp ../ZAPD.out tools/ZAPD/'
sh 'python3 tools/fixbaserom.py'
sh 'python3 tools/extract_baserom.py'
sh 'python3 extract_assets.py -t$(nproc)'
}
}
}
}
}
// BUILD THE REPOS
stage('Build repos') {
parallel {
stage('Build oot') {
steps {
dir('oot') {
sh 'make -j'
}
}
}
stage('Build mm') {
steps {
dir('mm') {
sh 'make -j disasm'
sh 'make -j all'
}
}
}
}
}
}
post {
always {
cleanWs()
}
}
}

21
ZAPDTR/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Zelda Reverse Engineering Team
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.

134
ZAPDTR/Makefile Normal file
View File

@ -0,0 +1,134 @@
# use variables in submakes
export
OPTIMIZATION_ON ?= 1
ASAN ?= 0
DEPRECATION_ON ?= 1
DEBUG ?= 0
COPYCHECK_ARGS ?=
LLD ?= 0
WERROR ?= 0
# Use clang++ if available, else use g++
ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0)
CXX := clang++
else
CXX := g++
endif
INC := -I ZAPD -I lib/elfio -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils
CXXFLAGS := -fpic -std=c++17 -Wall -Wextra -fno-omit-frame-pointer
OPTFLAGS :=
ifneq ($(DEBUG),0)
OPTIMIZATION_ON = 0
CXXFLAGS += -g3 -DDEVELOPMENT -D_DEBUG
COPYCHECK_ARGS += --devel
DEPRECATION_ON = 0
endif
ifneq ($(WERROR),0)
CXXFLAGS += -Werror
endif
ifeq ($(OPTIMIZATION_ON),0)
OPTFLAGS := -O0
else
OPTFLAGS := -O2
endif
ifneq ($(ASAN),0)
CXXFLAGS += -fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined
endif
ifneq ($(DEPRECATION_ON),0)
CXXFLAGS += -DDEPRECATION_ON
endif
# CXXFLAGS += -DTEXTURE_DEBUG
LDFLAGS := -lm -ldl -lpng
# Use LLD if available. Set LLD=0 to not use it
ifeq ($(shell command -v ld.lld >/dev/null 2>&1; echo $$?),0)
LLD := 1
endif
ifneq ($(LLD),0)
LDFLAGS += -fuse-ld=lld
endif
UNAME := $(shell uname)
UNAMEM := $(shell uname -m)
ifneq ($(UNAME), Darwin)
LDFLAGS += -Wl,-export-dynamic -lstdc++fs
EXPORTERS := -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive
else
EXPORTERS := -Wl,-force_load ExporterTest/ExporterTest.a
ifeq ($(UNAMEM),arm64)
ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0)
LDFLAGS += -L $(shell brew --prefix)/lib
INC += -I $(shell brew --prefix)/include
else
$(error Please install libpng via Homebrew)
endif
endif
endif
ZAPD_SRC_DIRS := $(shell find ZAPD -type d)
SRC_DIRS = $(ZAPD_SRC_DIRS) lib/tinyxml2
ZAPD_CPP_FILES := $(foreach dir,$(ZAPD_SRC_DIRS),$(wildcard $(dir)/*.cpp))
ZAPD_H_FILES := $(foreach dir,$(ZAPD_SRC_DIRS),$(wildcard $(dir)/*.h))
CPP_FILES += $(ZAPD_CPP_FILES) lib/tinyxml2/tinyxml2.cpp
O_FILES := $(foreach f,$(CPP_FILES:.cpp=.o),build/$f)
O_FILES += build/ZAPD/BuildInfo.o
# create build directories
$(shell mkdir -p $(foreach dir,$(SRC_DIRS),build/$(dir)))
# Main targets
all: ZAPD.out copycheck
build/ZAPD/BuildInfo.o:
python3 ZAPD/genbuildinfo.py $(COPYCHECK_ARGS)
$(CXX) $(CXXFLAGS) $(OPTFLAGS) $(INC) -c $(OUTPUT_OPTION) build/ZAPD/BuildInfo.cpp
copycheck: ZAPD.out
python3 copycheck.py
clean:
rm -rf build ZAPD.out
$(MAKE) -C lib/libgfxd clean
$(MAKE) -C ZAPDUtils clean
$(MAKE) -C ExporterTest clean
rebuild: clean all
format:
clang-format-11 -i $(ZAPD_CPP_FILES) $(ZAPD_H_FILES)
$(MAKE) -C ZAPDUtils format
$(MAKE) -C ExporterTest format
.PHONY: all build/ZAPD/BuildInfo.o copycheck clean rebuild format
build/%.o: %.cpp
$(CXX) $(CXXFLAGS) $(OPTFLAGS) $(INC) -c $(OUTPUT_OPTION) $<
# Submakes
lib/libgfxd/libgfxd.a:
$(MAKE) -C lib/libgfxd
.PHONY: ExporterTest
ExporterTest:
$(MAKE) -C ExporterTest
.PHONY: ZAPDUtils
ZAPDUtils:
$(MAKE) -C ZAPDUtils
# Linking
ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils
$(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION)

168
ZAPDTR/README.md Normal file
View File

@ -0,0 +1,168 @@
# ZAPD: Zelda Asset Processor for Decomp
## Compiling
### Dependencies
ZAPD needs a compiler with C++17 support.
ZAPD has the following library dependencies:
- `libpng`
In a Debian/Ubuntu based environment, those could be installed with the following command:
```bash
sudo apt install libpng-dev
```
On a Mac, you will need to install libpng with Homebrew or MacPorts; we currently only support Homebrew. You can run
```bash
brew install libpng
```
to install it via Homebrew.
### Building
#### Linux / *nix
ZAPD uses the clasic `Makefile` approach. To build just run `make` (or even better `make -j` for faster compilations).
You can configure a bit your ZAPD build with the following options:
- `OPTIMIZATION_ON`: If set to `0` optimizations will be disabled (compile with `-O0`). Any other value compiles with `-O2`. Defaults to `1`.
- `ASAN`: If it is set to a non-zero then ZAPD will be compiled with Address Sanitizer enabled (`-fsanitize=address`). Defaults to `0`.
- `DEPRECATION_ON`: If it is set to a zero then deprecation warnings will be disabled. Defaults to `1`.
- `DEBUG`: If non-zero, ZAPD will be compiled in _development mode_. This implies the following:
- Debugging symbols enabled (`-g3`). They are disabled by default.
- `OPTIMIZATION_ON=0`: Disables optimizations (`-O0`).
- `DEPRECATION_ON=0`: Disables deprecation warnings.
- `LLD=1`: builds with the LLVM linker `ld.lld` instead of the system default.
As an example, if you want to build ZAPD with optimizations disabled and use the address sanitizer, you could use the following command:
```bash
make -j OPTIMIZATION_ON=0 ASAN=1
```
#### Windows
This repository contains `vcxproj` files for compiling under Visual Studio environments. See `ZAPD/ZAPD.vcxproj`.
## Invoking ZAPD
ZAPD needs a _File parsing mode_ to be passed as first parameter. The options are:
- `e`: "Extraction" mode.
- In this mode, ZAPD expects a XML file as input, a folder as ouput and a path to the baserom files.
- ZAPD will read the XML and use it as a guide to extract the contents of the specified asset file from the baserom folder.
- For more info of the format of those XMLs, see the [ZAPD extraction XML reference](docs/zapd_extraction_xml_reference.md).
- `bsf`: "Build source file" mode.
- This is an experimental mode.
- It was going to be used to let you have XMLs that aren't just for extraction. Might get used, might not. Still need to experiment on that.
- `btex`: "Build texture" mode.
- In this mode, ZAPD expects a PNG file as input, a filename as ouput and a texture type parameter (`-tt`).
- ZAPD will try to convert the given PNG into the contents of a `uint64_t` C array.
- `bren`: "Build (render) background" mode.
- In this mode, ZAPD expects a JPG file as input and a filename as ouput.
- ZAPD will try to convert the given JPG into the contents of a `uint64_t` C array.
- `blb`: "Build blob" mode.
- In this mode, ZAPD expects a BIN file as input and a filename as ouput.
- ZAPD will try to convert the given BIN into the contents of a `uint8_t` C array.
- `bovl`: "Build overlay" mode.
- In this mode, ZAPD expects an overlay C file as input, a filename as ouput and an overlay configuration path (`-cfg`).
- ZAPD will generate a reloc `.s` file.
ZAPD also accepts the following list of extra parameters:
- `-i PATH` / `--inputpath PATH`: Set input path.
- `-o PATH` / `--outputpath PATH`: Set output path.
- `-b PATH` / `--baserompath`: Set baserom path.
- Can be used only in `e` or `bsf` modes.
- `-osf PATH`: Set source output path. This is the path where the `.c` and `.h` files will be extracted to. If omitted, it will use the value passed to `--outputpath` parameter.
- `-gsf MODE`: Generate source file during extraction. If `MODE` is `1`, C source files will be generated.
- Can be used only in `e` mode.
- `-crc` / `--output-crc`: Outputs a CRC file for each extracted texture.
- Can be used only in `e` or `bsf` modes.
- `-ulzdl MODE`: Use "Legacy ZDisplayList" instead of `libgfxd`. Set `MODE` to `1` to enable it.
- Can be used only in `e` or `bsf` modes.
- `-profile MODE`: Enable profiling. Set `MODE` to `1` to enable it.
- `-uer MODE`: Split resources into their individual components (enabled by default). Set `MODE` to non-`1` to disable it.
- `-tt TYPE`: Set texture type.
- Can be used only in mode `btex`.
- Valid values:
- `rgba32`
- `rgb5a1`
- `i4`
- `i8`
- `ia4`
- `ia8`
- `ia16`
- `ci4`
- `ci8`
- `-cfg PATH`: Set cfg path (for overlays).
- Can be used only in `bovl` mode.
- `-rconf PATH` Read Config File.
- `-eh`: Enable error handler.
- Only available in non-Windows environments.
- `-v MODE`: Enable verbosity. Currently there are 3 possible values:
- `0`: Default. Completely silent (except for warnings and errors).
- `1`: Information.
- `2` (and higher): Debug.
- `-wu` / `--warn-unaccounted`: Enable warnings for each unaccounted block of data found.
- Can be used only in `e` or `bsf` modes.
- `-vu` / `--verbose-unaccounted`: Changes how unaccounteds are outputted. Max 4 bytes per line (a word) and add a comment with the offset of each of those lines.
- Could be useful for looking at raw data or testing.
- Can be used only in `e` or `bsf` modes.
- `-tm MODE`: Test Mode (enables certain experimental features). To enable it, set `MODE` to `1`.
- `-se` / `--set-exporter` : Sets which exporter to use.
- `--gcc-compat` : Enables GCC compatibly mode. Slower.
- `-us` / `--unaccounted-static` : Mark unaccounted data as `static`
- `-s` / `--static` : Mark every asset as `static`.
- This behaviour can be overridden per asset using `Static=` in the respective XML node.
- `-W...`: warning flags, see below
Additionally, you can pass the flag `--version` to see the current ZAPD version. If that flag is passed, ZAPD will ignore any other parameter passed.
### Warning flags
ZAPD contains a variety of warning types, with similar syntax to GCC or Clang's compiler warnings. Warnings can have three levels:
- Off (does not display anything)
- Warn (print a warning but continue processing)
- Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs)
Each warning type uses one of these by default, but can be modified with flags, similarly to GCC or Clang:
- `-Wfoo` enables warnings of type `foo`
- `-Wno-foo` disables warnings of type `foo`
- `-Werror=foo` escalates `foo` to behave like an error
- `-Weverything` enables all warnings (they may be turned off using `-Wno-` flags afterwards)
- `-Werror` escalates all enabled warnings to errors
All warning types currently implemented, with their default levels:
| Warning type | Default level | Description |
| --------------------------- | ------------- | ------------------------------------------------------------------------ |
| `-Wdeprecated` | Warn | Deprecated features |
| `-Whardcoded-pointer` | Warn | ZAPD lacks the info to make a symbol, so must output a hardcoded pointer |
| `-Wintersection` | Warn | Two assets intersect |
| `-Winvalid-attribute-value` | Err | Attribute declared in XML is wrong |
| `-Winvalid-extracted-data` | Err | Extracted data does not have correct form |
| `-Winvalid-jpeg` | Err | JPEG file does not conform to the game's format requirements |
| `-Winvalid-png` | Err | Issues arising when processing PNG data |
| `-Winvalid-xml` | Err | XML has syntax errors |
| `-Wmissing-attribute` | Warn | Required attribute missing in XML tag |
| `-Wmissing-offsets` | Warn | Offset attribute missing in XML tag |
| `-Wmissing-segment` | Warn | Segment not given in File tag in XML |
| `-Wnot-implemented` | Warn | ZAPD does not currently support this feature |
| `-Wunaccounted` | Off | Large blocks of unaccounted |
| `-Wunknown-attribute` | Warn | Unknown attribute in XML entry tag |
There are also errors that do not have a type, and cannot be disabled.
For example, here we have invoked ZAPD in the usual way to extract using a (rather badly-written) XML, but escalating `-Wintersection` to an error:
![ZAPD warnings example](docs/zapd_warning_example.png?raw=true)

23
ZAPDTR/ZAPD/CRC32.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
static uint32_t CRC32B(unsigned char* message, int32_t size)
{
int32_t byte, crc;
int32_t mask;
crc = 0xFFFFFFFF;
for (int32_t i = 0; i < size; i++)
{
byte = message[i];
crc = crc ^ byte;
for (int32_t j = 7; j >= 0; j--)
{
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~(uint32_t)(crc);
}

229
ZAPDTR/ZAPD/Declaration.cpp Normal file
View File

@ -0,0 +1,229 @@
#include "Declaration.h"
#include "Globals.h"
#include "Utils/StringHelper.h"
Declaration::Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nText)
{
address = nAddress;
alignment = nAlignment;
size = nSize;
text = nText;
}
Declaration::Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
const std::string& nText)
: Declaration(nAddress, nAlignment, nSize, nText)
{
varType = nVarType;
varName = nVarName;
isArray = nIsArray;
}
Declaration::Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
size_t nArrayItemCnt, const std::string& nText)
: Declaration(nAddress, nAlignment, nSize, nText)
{
varType = nVarType;
varName = nVarName;
isArray = nIsArray;
arrayItemCnt = nArrayItemCnt;
}
Declaration::Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
const std::string& nArrayItemCntStr, const std::string& nText)
: Declaration(nAddress, nAlignment, nSize, nText)
{
varType = nVarType;
varName = nVarName;
isArray = nIsArray;
arrayItemCntStr = nArrayItemCntStr;
}
Declaration::Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
size_t nArrayItemCnt, const std::string& nText, bool nIsExternal)
: Declaration(nAddress, nAlignment, nSize, nVarType, nVarName, nIsArray, nArrayItemCnt, nText)
{
isExternal = nIsExternal;
}
Declaration::Declaration(offset_t nAddress, const std::string& nIncludePath, size_t nSize,
const std::string& nVarType, const std::string& nVarName)
: Declaration(nAddress, DeclarationAlignment::Align4, nSize, "")
{
includePath = nIncludePath;
varType = nVarType;
varName = nVarName;
}
bool Declaration::IsStatic() const
{
switch (staticConf)
{
case StaticConfig::Off:
return false;
case StaticConfig::Global:
return Globals::Instance->forceStatic;
case StaticConfig::On:
return true;
}
return false;
}
std::string Declaration::GetNormalDeclarationStr() const
{
std::string output;
if (preText != "")
output += preText + "\n";
if (IsStatic())
{
output += "static ";
}
if (isArray)
{
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
{
output += StringHelper::Sprintf("%s %s[%s];\n", varType.c_str(), varName.c_str(),
arrayItemCntStr.c_str());
}
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
{
output += StringHelper::Sprintf("%s %s[%i] = {\n", varType.c_str(), varName.c_str(),
arrayItemCnt);
}
else
{
output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str());
}
output += text + "\n";
}
else
{
output += StringHelper::Sprintf("%s %s = { ", varType.c_str(), varName.c_str());
output += text;
}
if (output.back() == '\n')
output += "};";
else
output += " };";
if (rightText != "")
output += " " + rightText + "";
output += "\n";
if (postText != "")
output += postText + "\n";
output += "\n";
return output;
}
std::string Declaration::GetExternalDeclarationStr() const
{
std::string output;
if (preText != "")
output += preText + "\n";
if (IsStatic())
{
output += "static ";
}
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
output += StringHelper::Sprintf("%s %s[%s] = ", varType.c_str(), varName.c_str(),
arrayItemCntStr.c_str());
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
output +=
StringHelper::Sprintf("%s %s[%i] = ", varType.c_str(), varName.c_str(), arrayItemCnt);
else
output += StringHelper::Sprintf("%s %s[] = ", varType.c_str(), varName.c_str());
output += StringHelper::Sprintf("{\n#include \"%s\"\n};", includePath.c_str());
if (rightText != "")
output += " " + rightText + "";
output += "\n";
if (postText != "")
output += postText + "\n";
output += "\n";
return output;
}
std::string Declaration::GetExternStr() const
{
if (IsStatic() || varType == "")
{
return "";
}
if (Globals::Instance->otrMode) /* && (varType == "Gfx" || varType == "u64" || varType == "AnimationHeader" || varType == "LinkAnimationHeader" ||
varType == "StandardLimb" || varType == "JointIndex" || varType == "Vtx" || varType == "FlexSkeletonHeader" || varType == "SkeletonHeader") ||
varType == "CollisionHeader") */
return "";
if (isArray)
{
if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt))
{
return StringHelper::Sprintf("extern %s %s[%s];\n", varType.c_str(), varName.c_str(),
arrayItemCntStr.c_str());
}
else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt))
{
return StringHelper::Sprintf("extern %s %s[%i];\n", varType.c_str(), varName.c_str(),
arrayItemCnt);
}
else
return StringHelper::Sprintf("extern %s %s[];\n", varType.c_str(), varName.c_str());
}
return StringHelper::Sprintf("extern %s %s;\n", varType.c_str(), varName.c_str());
}
std::string Declaration::GetStaticForwardDeclarationStr() const
{
if (!IsStatic() || isUnaccounted)
return "";
if (isArray)
{
if (arrayItemCntStr == "" && arrayItemCnt == 0)
{
// Forward declaring static arrays without specifying the size is not allowed.
return "";
}
if (arrayItemCntStr != "")
{
return StringHelper::Sprintf("static %s %s[%s];\n", varType.c_str(), varName.c_str(),
arrayItemCntStr.c_str());
}
else
{
return StringHelper::Sprintf("static %s %s[%i];\n", varType.c_str(), varName.c_str(),
arrayItemCnt);
}
}
return StringHelper::Sprintf("static %s %s;\n", varType.c_str(), varName.c_str());
}

80
ZAPDTR/ZAPD/Declaration.h Normal file
View File

@ -0,0 +1,80 @@
#pragma once
#include <string>
#include <vector>
// TODO: should we drop the `_t` suffix because of UNIX compliance?
typedef uint32_t segptr_t;
typedef uint32_t offset_t;
#define SEGMENTED_NULL ((segptr_t)0)
enum class DeclarationAlignment
{
Align4,
Align8
};
enum class StaticConfig
{
Off,
Global,
On
};
class Declaration
{
public:
offset_t address;
DeclarationAlignment alignment;
size_t size;
std::string preText;
std::string text;
std::string rightText;
std::string postText;
std::string preComment;
std::string postComment;
std::string varType;
std::string varName;
std::string includePath;
bool isExternal = false;
bool isArray = false;
bool forceArrayCnt = false;
size_t arrayItemCnt = 0;
std::string arrayItemCntStr = "";
std::vector<segptr_t> references;
bool isUnaccounted = false;
bool isPlaceholder = false;
bool declaredInXml = false;
StaticConfig staticConf = StaticConfig::Global;
Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
const std::string& nText);
Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
size_t nArrayItemCnt, const std::string& nText);
Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
const std::string& nArrayItemCntStr, const std::string& nText);
Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nVarType, const std::string& nVarName, bool nIsArray,
size_t nArrayItemCnt, const std::string& nText, bool nIsExternal);
Declaration(offset_t nAddress, const std::string& nIncludePath, size_t nSize,
const std::string& nVarType, const std::string& nVarName);
bool IsStatic() const;
std::string GetNormalDeclarationStr() const;
std::string GetExternalDeclarationStr() const;
std::string GetExternStr() const;
std::string GetStaticForwardDeclarationStr() const;
protected:
Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize,
const std::string& nText);
};

184
ZAPDTR/ZAPD/GameConfig.cpp Normal file
View File

@ -0,0 +1,184 @@
#include "GameConfig.h"
#include <functional>
#include <string_view>
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "ZFile.h"
#include "tinyxml2.h"
using ConfigFunc = void (GameConfig::*)(const tinyxml2::XMLElement&);
GameConfig::~GameConfig()
{
for (auto& declPair : segmentRefFiles)
{
for (auto& file : declPair.second)
{
delete file;
}
}
}
void GameConfig::ReadTexturePool(const fs::path& texturePoolXmlPath)
{
tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.string().c_str());
if (eResult != tinyxml2::XML_SUCCESS)
{
fprintf(stderr, "Warning: Unable to read texture pool XML with error code %i\n", eResult);
return;
}
tinyxml2::XMLNode* root = doc.FirstChild();
if (root == nullptr)
return;
for (tinyxml2::XMLElement* child = root->FirstChildElement(); child != nullptr;
child = child->NextSiblingElement())
{
if (std::string_view(child->Name()) == "Texture")
{
std::string crcStr = child->Attribute("CRC");
fs::path texPath = child->Attribute("Path");
std::string texName;
uint32_t crc = strtoul(crcStr.c_str(), nullptr, 16);
texturePool[crc].path = texPath;
}
}
}
void GameConfig::GenSymbolMap(const fs::path& symbolMapPath)
{
auto symbolLines = File::ReadAllLines(symbolMapPath);
for (std::string& symbolLine : symbolLines)
{
auto split = StringHelper::Split(symbolLine, " ");
uint32_t addr = strtoul(split[0].c_str(), nullptr, 16);
std::string symbolName = split[1];
symbolMap[addr] = std::move(symbolName);
}
}
void GameConfig::ConfigFunc_SymbolMap(const tinyxml2::XMLElement& element)
{
std::string fileName = element.Attribute("File");
GenSymbolMap(Path::GetDirectoryName(configFilePath) / fileName);
}
void GameConfig::ConfigFunc_ActorList(const tinyxml2::XMLElement& element)
{
std::string fileName = element.Attribute("File");
std::vector<std::string> lines =
File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName);
for (auto& line : lines)
actorList.emplace_back(std::move(line));
}
void GameConfig::ConfigFunc_ObjectList(const tinyxml2::XMLElement& element)
{
std::string fileName = element.Attribute("File");
std::vector<std::string> lines =
File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName);
for (auto& line : lines)
objectList.emplace_back(std::move(line));
}
void GameConfig::ConfigFunc_TexturePool(const tinyxml2::XMLElement& element)
{
std::string fileName = element.Attribute("File");
ReadTexturePool(Path::GetDirectoryName(configFilePath) / fileName);
}
void GameConfig::ConfigFunc_BGConfig(const tinyxml2::XMLElement& element)
{
bgScreenWidth = element.IntAttribute("ScreenWidth", 320);
bgScreenHeight = element.IntAttribute("ScreenHeight", 240);
}
void GameConfig::ConfigFunc_ExternalXMLFolder(const tinyxml2::XMLElement& element)
{
const char* pathValue = element.Attribute("Path");
if (pathValue == nullptr)
{
throw std::runtime_error(
StringHelper::Sprintf("Parse: Fatal error in configuration file.\n"
"\t Missing 'Path' attribute in `ExternalXMLFolder` element.\n"));
}
if (externalXmlFolder != "")
{
throw std::runtime_error(StringHelper::Sprintf("Parse: Fatal error in configuration file.\n"
"\t `ExternalXMLFolder` is duplicated.\n"));
}
externalXmlFolder = pathValue;
}
void GameConfig::ConfigFunc_ExternalFile(const tinyxml2::XMLElement& element)
{
const char* xmlPathValue = element.Attribute("XmlPath");
if (xmlPathValue == nullptr)
{
throw std::runtime_error(
StringHelper::Sprintf("Parse: Fatal error in configuration file.\n"
"\t Missing 'XmlPath' attribute in `ExternalFile` element.\n"));
}
const char* outPathValue = element.Attribute("OutPath");
if (outPathValue == nullptr)
{
throw std::runtime_error(
StringHelper::Sprintf("Parse: Fatal error in configuration file.\n"
"\t Missing 'OutPath' attribute in `ExternalFile` element.\n"));
}
externalFiles.push_back(ExternalFile(fs::path(xmlPathValue), fs::path(outPathValue)));
}
void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath)
{
static const std::map<std::string, ConfigFunc> ConfigFuncDictionary = {
{"SymbolMap", &GameConfig::ConfigFunc_SymbolMap},
{"ActorList", &GameConfig::ConfigFunc_ActorList},
{"ObjectList", &GameConfig::ConfigFunc_ObjectList},
{"TexturePool", &GameConfig::ConfigFunc_TexturePool},
{"BGConfig", &GameConfig::ConfigFunc_BGConfig},
{"ExternalXMLFolder", &GameConfig::ConfigFunc_ExternalXMLFolder},
{"ExternalFile", &GameConfig::ConfigFunc_ExternalFile},
};
configFilePath = argConfigFilePath.string();
tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(configFilePath.c_str());
if (eResult != tinyxml2::XML_SUCCESS)
{
throw std::runtime_error("Error: Unable to read config file.");
}
tinyxml2::XMLNode* root = doc.FirstChild();
if (root == nullptr)
return;
for (tinyxml2::XMLElement* child = root->FirstChildElement(); child != nullptr;
child = child->NextSiblingElement())
{
auto it = ConfigFuncDictionary.find(child->Name());
if (it == ConfigFuncDictionary.end())
{
fprintf(stderr, "Unsupported configuration variable: %s\n", child->Name());
continue;
}
std::invoke(it->second, *this, *child);
}
}

58
ZAPDTR/ZAPD/GameConfig.h Normal file
View File

@ -0,0 +1,58 @@
#pragma once
#include <cstdint>
#include <map>
#include <string>
#include <vector>
#include "Utils/Directory.h"
#include "tinyxml2.h"
struct TexturePoolEntry
{
fs::path path = ""; // Path to Shared Texture
};
class ExternalFile
{
public:
fs::path xmlPath, outPath;
ExternalFile(fs::path nXmlPath, fs::path nOutPath);
};
class ZFile;
class GameConfig
{
public:
std::string configFilePath;
std::map<int32_t, std::vector<ZFile*>> segmentRefFiles;
std::map<uint32_t, std::string> symbolMap;
std::vector<std::string> actorList;
std::vector<std::string> objectList;
std::map<uint32_t, TexturePoolEntry> texturePool; // Key = CRC
// ZBackground
uint32_t bgScreenWidth = 320, bgScreenHeight = 240;
// ExternalFile
fs::path externalXmlFolder;
std::vector<ExternalFile> externalFiles;
GameConfig() = default;
~GameConfig();
void ReadTexturePool(const fs::path& texturePoolXmlPath);
void GenSymbolMap(const fs::path& symbolMapPath);
void ConfigFunc_SymbolMap(const tinyxml2::XMLElement& element);
void ConfigFunc_ActorList(const tinyxml2::XMLElement& element);
void ConfigFunc_ObjectList(const tinyxml2::XMLElement& element);
void ConfigFunc_TexturePool(const tinyxml2::XMLElement& element);
void ConfigFunc_BGConfig(const tinyxml2::XMLElement& element);
void ConfigFunc_ExternalXMLFolder(const tinyxml2::XMLElement& element);
void ConfigFunc_ExternalFile(const tinyxml2::XMLElement& element);
void ReadConfigFile(const fs::path& configFilePath);
};

225
ZAPDTR/ZAPD/Globals.cpp Normal file
View File

@ -0,0 +1,225 @@
#include "Globals.h"
#include <algorithm>
#include <string_view>
#include "Utils/File.h"
#include "Utils/Path.h"
#include "WarningHandler.h"
#include "tinyxml2.h"
Globals* Globals::Instance;
Globals::Globals()
{
Instance = this;
game = ZGame::OOT_RETAIL;
genSourceFile = true;
testMode = false;
profile = false;
useLegacyZDList = false;
useExternalResources = true;
verbosity = VerbosityLevel::VERBOSITY_SILENT;
outputPath = Directory::GetCurrentDirectory();
}
Globals::~Globals()
{
auto& exporters = GetExporterMap();
for (auto& it : exporters)
{
delete it.second;
}
}
void Globals::AddSegment(int32_t segment, ZFile* file)
{
if (std::find(segments.begin(), segments.end(), segment) == segments.end())
segments.push_back(segment);
if (cfg.segmentRefFiles.find(segment) == cfg.segmentRefFiles.end())
cfg.segmentRefFiles[segment] = std::vector<ZFile*>();
cfg.segmentRefFiles[segment].push_back(file);
}
bool Globals::HasSegment(int32_t segment)
{
return std::find(segments.begin(), segments.end(), segment) != segments.end();
}
ZFile* Globals::GetSegment(int32_t segment)
{
if (HasSegment(segment))
{
int idx = std::find(segments.begin(), segments.end(), segment) - segments.begin();
return files[idx];
}
else
return nullptr;
}
std::map<std::string, ExporterSet*>& Globals::GetExporterMap()
{
static std::map<std::string, ExporterSet*> exporters;
return exporters;
}
void Globals::AddExporter(std::string exporterName, ExporterSet* exporterSet)
{
auto& exporters = GetExporterMap();
exporters[exporterName] = exporterSet;
}
ZResourceExporter* Globals::GetExporter(ZResourceType resType)
{
auto& exporters = GetExporterMap();
if (currentExporter != "" && exporters[currentExporter]->exporters.find(resType) !=
exporters[currentExporter]->exporters.end())
return exporters[currentExporter]->exporters[resType];
else
return nullptr;
}
ExporterSet* Globals::GetExporterSet()
{
auto& exporters = GetExporterMap();
if (currentExporter != "")
return exporters[currentExporter];
else
return nullptr;
}
bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
const std::string& expectedType, std::string& declName)
{
if (segAddress == 0)
{
declName = "NULL";
return true;
}
uint8_t segment = GETSEGNUM(segAddress);
uint32_t offset = Seg2Filespace(segAddress, currentFile->baseAddress);
ZSymbol* sym;
sym = currentFile->GetSymbolResource(offset);
if (sym != nullptr)
{
if (expectedType == "" || expectedType == sym->GetSourceTypeName())
{
declName = sym->GetName();
return true;
}
}
sym = currentFile->GetSymbolResource(segAddress);
if (sym != nullptr)
{
if (expectedType == "" || expectedType == sym->GetSourceTypeName())
{
declName = sym->GetName();
return true;
}
}
if (currentFile->IsSegmentedInFilespaceRange(segAddress))
{
if (currentFile->GetDeclarationPtrName(segAddress, expectedType, declName))
return true;
}
else if (HasSegment(segment))
{
for (auto file : cfg.segmentRefFiles[segment])
{
offset = Seg2Filespace(segAddress, file->baseAddress);
sym = file->GetSymbolResource(offset);
if (sym != nullptr)
{
if (expectedType == "" || expectedType == sym->GetSourceTypeName())
{
declName = sym->GetName();
return true;
}
}
sym = file->GetSymbolResource(segAddress);
if (sym != nullptr)
{
if (expectedType == "" || expectedType == sym->GetSourceTypeName())
{
declName = sym->GetName();
return true;
}
}
if (file->IsSegmentedInFilespaceRange(segAddress))
{
if (file->GetDeclarationPtrName(segAddress, expectedType, declName))
return true;
}
}
}
const auto& symbolFromMap = Globals::Instance->cfg.symbolMap.find(segAddress);
if (symbolFromMap != Globals::Instance->cfg.symbolMap.end())
{
declName = "&" + symbolFromMap->second;
return true;
}
declName = StringHelper::Sprintf("0x%08X", segAddress);
return false;
}
bool Globals::GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize,
ZFile* currentFile, const std::string& expectedType,
std::string& declName)
{
if (segAddress == 0)
{
declName = "NULL";
return true;
}
uint8_t segment = GETSEGNUM(segAddress);
if (currentFile->IsSegmentedInFilespaceRange(segAddress))
{
bool addressFound = currentFile->GetDeclarationArrayIndexedName(segAddress, elementSize,
expectedType, declName);
if (addressFound)
return true;
}
else if (HasSegment(segment))
{
for (auto file : cfg.segmentRefFiles[segment])
{
if (file->IsSegmentedInFilespaceRange(segAddress))
{
bool addressFound = file->GetDeclarationArrayIndexedName(segAddress, elementSize,
expectedType, declName);
if (addressFound)
return true;
}
}
}
declName = StringHelper::Sprintf("0x%08X", segAddress);
return false;
}
ExternalFile::ExternalFile(fs::path nXmlPath, fs::path nOutPath)
: xmlPath{nXmlPath}, outPath{nOutPath}
{
}
ExporterSet::~ExporterSet()
{
for (auto& it : exporters)
{
delete it.second;
}
}

95
ZAPDTR/ZAPD/Globals.h Normal file
View File

@ -0,0 +1,95 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include "GameConfig.h"
#include "ZFile.h"
class ZRoom;
enum class VerbosityLevel
{
VERBOSITY_SILENT,
VERBOSITY_INFO,
VERBOSITY_DEBUG
};
typedef void (*ExporterSetFunc)(ZFile*);
typedef bool (*ExporterSetFuncBool)(ZFileMode fileMode);
typedef void (*ExporterSetFuncVoid)(int argc, char* argv[], int& i);
typedef void (*ExporterSetFuncVoid2)(const std::string& buildMode, ZFileMode& fileMode);
typedef void (*ExporterSetFuncVoid3)();
typedef void (*ExporterSetResSave)(ZResource* res, BinaryWriter& writer);
class ExporterSet
{
public:
~ExporterSet();
std::map<ZResourceType, ZResourceExporter*> exporters;
ExporterSetFuncVoid parseArgsFunc = nullptr;
ExporterSetFuncVoid2 parseFileModeFunc = nullptr;
ExporterSetFuncBool processFileModeFunc = nullptr;
ExporterSetFunc beginFileFunc = nullptr;
ExporterSetFunc endFileFunc = nullptr;
ExporterSetFuncVoid3 beginXMLFunc = nullptr;
ExporterSetFuncVoid3 endXMLFunc = nullptr;
ExporterSetResSave resSaveFunc = nullptr;
};
class Globals
{
public:
static Globals* Instance;
bool genSourceFile; // Used for extraction
bool useExternalResources;
bool testMode; // Enables certain experimental features
bool outputCrc = false;
bool profile; // Measure performance of certain operations
bool useLegacyZDList;
VerbosityLevel verbosity; // ZAPD outputs additional information
ZFileMode fileMode;
fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath;
TextureType texType;
ZGame game;
GameConfig cfg;
bool verboseUnaccounted = false;
bool gccCompat = false;
bool forceStatic = false;
bool forceUnaccountedStatic = false;
bool otrMode = true;
std::vector<ZFile*> files;
std::vector<ZFile*> externalFiles;
std::vector<int32_t> segments;
std::string currentExporter;
static std::map<std::string, ExporterSet*>& GetExporterMap();
static void AddExporter(std::string exporterName, ExporterSet* exporterSet);
Globals();
~Globals();
void AddSegment(int32_t segment, ZFile* file);
bool HasSegment(int32_t segment);
ZFile* GetSegment(int32_t segment);
ZResourceExporter* GetExporter(ZResourceType resType);
ExporterSet* GetExporterSet();
/**
* Search in every file (and the symbol map) for the `segAddress` passed as parameter.
* If the segment of `currentFile` is the same segment of `segAddress`, then that file will be
* used only, otherwise, the search will be performed in every other file.
* The name of that variable will be stored in the `declName` parameter.
* Returns `true` if the address is found. `false` otherwise,
* in which case `declName` will be set to the address formatted as a pointer.
*/
bool GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
const std::string& expectedType, std::string& declName);
bool GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize, ZFile* currentFile,
const std::string& expectedType, std::string& declName);
};

View File

@ -0,0 +1,506 @@
#include "ImageBackend.h"
#include <cassert>
#include <cstdlib>
#include <png.h>
#include <stdexcept>
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
/* ImageBackend */
ImageBackend::~ImageBackend()
{
FreeImageData();
}
void ImageBackend::ReadPng(const char* filename)
{
FreeImageData();
FILE* fp = fopen(filename, "rb");
if (fp == nullptr)
{
std::string errorHeader = StringHelper::Sprintf("could not open file '%s'", filename);
HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
}
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (png == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
}
png_infop info = png_create_info_struct(png);
if (info == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
}
if (setjmp(png_jmpbuf(png)))
{
// TODO: better warning explanation
HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
}
png_init_io(png, fp);
png_read_info(png, info);
width = png_get_image_width(png, info);
height = png_get_image_height(png, info);
colorType = png_get_color_type(png, info);
bitDepth = png_get_bit_depth(png, info);
#ifdef TEXTURE_DEBUG
printf("Width: %u\n", width);
printf("Height: %u\n", height);
printf("ColorType: ");
switch (colorType)
{
case PNG_COLOR_TYPE_RGBA:
printf("PNG_COLOR_TYPE_RGBA\n");
break;
case PNG_COLOR_TYPE_RGB:
printf("PNG_COLOR_TYPE_RGB\n");
break;
case PNG_COLOR_TYPE_PALETTE:
printf("PNG_COLOR_TYPE_PALETTE\n");
break;
default:
printf("%u\n", colorType);
break;
}
printf("BitDepth: %u\n", bitDepth);
printf("\n");
#endif
// Read any color_type into 8bit depth, RGBA format.
// See http://www.libpng.org/pub/png/libpng-manual.txt
if (bitDepth == 16)
png_set_strip_16(png);
if (colorType == PNG_COLOR_TYPE_PALETTE)
{
// png_set_palette_to_rgb(png);
isColorIndexed = true;
}
// PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
png_set_expand_gray_1_2_4_to_8(png);
/*if (png_get_valid(png, info, PNG_INFO_tRNS))
png_set_tRNS_to_alpha(png);*/
// These color_type don't have an alpha channel then fill it with 0xff.
/*if(*color_type == PNG_COLOR_TYPE_RGB ||
*color_type == PNG_COLOR_TYPE_GRAY ||
*color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);*/
if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
png_read_update_info(png, info);
size_t rowBytes = png_get_rowbytes(png, info);
pixelMatrix = (uint8_t**)malloc(sizeof(uint8_t*) * height);
for (size_t y = 0; y < height; y++)
{
pixelMatrix[y] = (uint8_t*)malloc(rowBytes);
}
png_read_image(png, pixelMatrix);
#ifdef TEXTURE_DEBUG
printf("rowBytes: %zu\n", rowBytes);
size_t bytePerPixel = GetBytesPerPixel();
printf("imgData\n");
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width; x++)
{
for (size_t z = 0; z < bytePerPixel; z++)
{
printf("%02X ", pixelMatrix[y][x * bytePerPixel + z]);
}
printf(" ");
}
printf("\n");
}
printf("\n");
#endif
fclose(fp);
png_destroy_read_struct(&png, &info, nullptr);
hasImageData = true;
}
void ImageBackend::ReadPng(const fs::path& filename)
{
ReadPng(filename.c_str());
}
void ImageBackend::WritePng(const char* filename)
{
assert(hasImageData);
FILE* fp = fopen(filename, "wb");
if (fp == nullptr)
{
std::string errorHeader =
StringHelper::Sprintf("could not open file '%s' in write mode", filename);
HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, "");
}
png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
if (png == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", "");
}
png_infop info = png_create_info_struct(png);
if (info == nullptr)
{
HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", "");
}
if (setjmp(png_jmpbuf(png)))
{
// TODO: better warning description
HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", "");
}
png_init_io(png, fp);
png_set_IHDR(png, info, width, height,
bitDepth, // 8,
colorType, // PNG_COLOR_TYPE_RGBA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
if (isColorIndexed)
{
png_set_PLTE(png, info, static_cast<png_color*>(colorPalette), paletteSize);
#ifdef TEXTURE_DEBUG
printf("palette\n");
png_color* aux = (png_color*)colorPalette;
for (size_t y = 0; y < paletteSize; y++)
{
printf("#%02X%02X%02X ", aux[y].red, aux[y].green, aux[y].blue);
if ((y + 1) % 8 == 0)
printf("\n");
}
printf("\n");
#endif
png_set_tRNS(png, info, alphaPalette, paletteSize, nullptr);
}
png_write_info(png, info);
// To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
// Use png_set_filler().
// png_set_filler(png, 0, PNG_FILLER_AFTER);
#ifdef TEXTURE_DEBUG
size_t bytePerPixel = GetBytesPerPixel();
printf("imgData\n");
for (size_t y = 0; y < height; y++)
{
for (size_t x = 0; x < width * bytePerPixel; x++)
{
printf("%02X ", pixelMatrix[y][x]);
}
printf("\n");
}
printf("\n");
#endif
png_write_image(png, pixelMatrix);
png_write_end(png, nullptr);
fclose(fp);
png_destroy_write_struct(&png, &info);
}
void ImageBackend::WritePng(const fs::path& filename)
{
// Note: The .string() is necessary for MSVC, due to the implementation of std::filesystem
// differing from GCC. Do not remove!
WritePng(filename.string().c_str());
}
void ImageBackend::SetTextureData(const std::vector<std::vector<RGBAPixel>>& texData,
uint32_t nWidth, uint32_t nHeight, uint8_t nColorType,
uint8_t nBitDepth)
{
FreeImageData();
width = nWidth;
height = nHeight;
colorType = nColorType;
bitDepth = nBitDepth;
size_t bytePerPixel = GetBytesPerPixel();
pixelMatrix = static_cast<uint8_t**>(malloc(sizeof(uint8_t*) * height));
for (size_t y = 0; y < height; y++)
{
pixelMatrix[y] = static_cast<uint8_t*>(malloc(sizeof(uint8_t*) * width * bytePerPixel));
for (size_t x = 0; x < width; x++)
{
pixelMatrix[y][x * bytePerPixel + 0] = texData.at(y).at(x).r;
pixelMatrix[y][x * bytePerPixel + 1] = texData.at(y).at(x).g;
pixelMatrix[y][x * bytePerPixel + 2] = texData.at(y).at(x).b;
if (colorType == PNG_COLOR_TYPE_RGBA)
pixelMatrix[y][x * bytePerPixel + 3] = texData.at(y).at(x).a;
}
}
hasImageData = true;
}
void ImageBackend::InitEmptyRGBImage(uint32_t nWidth, uint32_t nHeight, bool alpha)
{
FreeImageData();
width = nWidth;
height = nHeight;
colorType = PNG_COLOR_TYPE_RGB;
if (alpha)
colorType = PNG_COLOR_TYPE_RGBA;
bitDepth = 8; // nBitDepth;
size_t bytePerPixel = GetBytesPerPixel();
pixelMatrix = static_cast<uint8_t**>(malloc(sizeof(uint8_t*) * height));
for (size_t y = 0; y < height; y++)
{
pixelMatrix[y] = static_cast<uint8_t*>(calloc(width * bytePerPixel, sizeof(uint8_t*)));
}
hasImageData = true;
}
void ImageBackend::InitEmptyPaletteImage(uint32_t nWidth, uint32_t nHeight)
{
FreeImageData();
width = nWidth;
height = nHeight;
colorType = PNG_COLOR_TYPE_PALETTE;
bitDepth = 8;
size_t bytePerPixel = GetBytesPerPixel();
pixelMatrix = (uint8_t**)malloc(sizeof(uint8_t*) * height);
for (size_t y = 0; y < height; y++)
{
pixelMatrix[y] = static_cast<uint8_t*>(calloc(width * bytePerPixel, sizeof(uint8_t*)));
}
colorPalette = calloc(paletteSize, sizeof(png_color));
alphaPalette = static_cast<uint8_t*>(calloc(paletteSize, sizeof(uint8_t)));
hasImageData = true;
isColorIndexed = true;
}
RGBAPixel ImageBackend::GetPixel(size_t y, size_t x) const
{
assert(y < height);
assert(x < width);
assert(!isColorIndexed);
RGBAPixel pixel;
size_t bytePerPixel = GetBytesPerPixel();
pixel.r = pixelMatrix[y][x * bytePerPixel + 0];
pixel.g = pixelMatrix[y][x * bytePerPixel + 1];
pixel.b = pixelMatrix[y][x * bytePerPixel + 2];
if (colorType == PNG_COLOR_TYPE_RGBA)
pixel.a = pixelMatrix[y][x * bytePerPixel + 3];
return pixel;
}
uint8_t ImageBackend::GetIndexedPixel(size_t y, size_t x) const
{
assert(y < height);
assert(x < width);
assert(isColorIndexed);
return pixelMatrix[y][x];
}
void ImageBackend::SetRGBPixel(size_t y, size_t x, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
{
assert(hasImageData);
assert(y < height);
assert(x < width);
size_t bytePerPixel = GetBytesPerPixel();
pixelMatrix[y][x * bytePerPixel + 0] = nR;
pixelMatrix[y][x * bytePerPixel + 1] = nG;
pixelMatrix[y][x * bytePerPixel + 2] = nB;
if (colorType == PNG_COLOR_TYPE_RGBA)
pixelMatrix[y][x * bytePerPixel + 3] = nA;
}
void ImageBackend::SetGrayscalePixel(size_t y, size_t x, uint8_t grayscale, uint8_t alpha)
{
assert(hasImageData);
assert(y < height);
assert(x < width);
size_t bytePerPixel = GetBytesPerPixel();
pixelMatrix[y][x * bytePerPixel + 0] = grayscale;
pixelMatrix[y][x * bytePerPixel + 1] = grayscale;
pixelMatrix[y][x * bytePerPixel + 2] = grayscale;
if (colorType == PNG_COLOR_TYPE_RGBA)
pixelMatrix[y][x * bytePerPixel + 3] = alpha;
}
void ImageBackend::SetIndexedPixel(size_t y, size_t x, uint8_t index, uint8_t grayscale)
{
assert(hasImageData);
assert(y < height);
assert(x < width);
size_t bytePerPixel = GetBytesPerPixel();
pixelMatrix[y][x * bytePerPixel + 0] = index;
assert(index < paletteSize);
png_color* pal = static_cast<png_color*>(colorPalette);
pal[index].red = grayscale;
pal[index].green = grayscale;
pal[index].blue = grayscale;
alphaPalette[index] = 255;
}
void ImageBackend::SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
{
assert(isColorIndexed);
assert(index < paletteSize);
png_color* pal = static_cast<png_color*>(colorPalette);
pal[index].red = nR;
pal[index].green = nG;
pal[index].blue = nB;
alphaPalette[index] = nA;
}
void ImageBackend::SetPalette(const ImageBackend& pal)
{
assert(isColorIndexed);
size_t bytePerPixel = pal.GetBytesPerPixel();
for (size_t y = 0; y < pal.height; y++)
{
for (size_t x = 0; x < pal.width; x++)
{
size_t index = y * pal.width + x;
if (index >= paletteSize)
{
/*
* Some TLUTs are bigger than 256 colors.
* For those cases, we will only take the first 256
* to colorize this CI texture.
*/
return;
}
uint8_t r = pal.pixelMatrix[y][x * bytePerPixel + 0];
uint8_t g = pal.pixelMatrix[y][x * bytePerPixel + 1];
uint8_t b = pal.pixelMatrix[y][x * bytePerPixel + 2];
uint8_t a = pal.pixelMatrix[y][x * bytePerPixel + 3];
SetPaletteIndex(index, r, g, b, a);
}
}
}
uint32_t ImageBackend::GetWidth() const
{
return width;
}
uint32_t ImageBackend::GetHeight() const
{
return height;
}
uint8_t ImageBackend::GetColorType() const
{
return colorType;
}
uint8_t ImageBackend::GetBitDepth() const
{
return bitDepth;
}
double ImageBackend::GetBytesPerPixel() const
{
switch (colorType)
{
case PNG_COLOR_TYPE_RGBA:
return 4 * bitDepth / 8;
case PNG_COLOR_TYPE_RGB:
return 3 * bitDepth / 8;
case PNG_COLOR_TYPE_PALETTE:
return 1 * bitDepth / 8;
default:
HANDLE_ERROR(WarningType::InvalidPNG, "invalid color type", "");
}
}
void ImageBackend::FreeImageData()
{
if (hasImageData)
{
for (size_t y = 0; y < height; y++)
free(pixelMatrix[y]);
free(pixelMatrix);
pixelMatrix = nullptr;
}
if (isColorIndexed)
{
free(colorPalette);
free(alphaPalette);
colorPalette = nullptr;
alphaPalette = nullptr;
isColorIndexed = false;
}
hasImageData = false;
}
/* RGBAPixel */
void RGBAPixel::SetRGBA(uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
{
r = nR;
g = nG;
b = nB;
a = nA;
}
void RGBAPixel::SetGrayscale(uint8_t grayscale, uint8_t alpha)
{
r = grayscale;
g = grayscale;
b = grayscale;
a = alpha;
}

View File

@ -0,0 +1,71 @@
#pragma once
#include <cstdint>
#include <vector>
#include "Utils/Directory.h"
class RGBAPixel
{
public:
RGBAPixel() = default;
void SetRGBA(uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA);
void SetGrayscale(uint8_t grayscale, uint8_t alpha = 0);
uint8_t r = 0;
uint8_t g = 0;
uint8_t b = 0;
uint8_t a = 0;
};
class ImageBackend
{
public:
ImageBackend() = default;
~ImageBackend();
void ReadPng(const char* filename);
void ReadPng(const fs::path& filename);
void WritePng(const char* filename);
void WritePng(const fs::path& filename);
void SetTextureData(const std::vector<std::vector<RGBAPixel>>& texData, uint32_t nWidth,
uint32_t nHeight, uint8_t nColorType, uint8_t nBitDepth);
void InitEmptyRGBImage(uint32_t nWidth, uint32_t nHeight, bool alpha);
void InitEmptyPaletteImage(uint32_t nWidth, uint32_t nHeight);
RGBAPixel GetPixel(size_t y, size_t x) const;
uint8_t GetIndexedPixel(size_t y, size_t x) const;
void SetRGBPixel(size_t y, size_t x, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA = 0);
void SetGrayscalePixel(size_t y, size_t x, uint8_t grayscale, uint8_t alpha = 0);
void SetIndexedPixel(size_t y, size_t x, uint8_t index, uint8_t grayscale);
void SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA);
void SetPalette(const ImageBackend& pal);
uint32_t GetWidth() const;
uint32_t GetHeight() const;
uint8_t GetColorType() const;
uint8_t GetBitDepth() const;
protected:
uint8_t** pixelMatrix = nullptr; // height * [width * bytePerPixel]
void* colorPalette = nullptr;
uint8_t* alphaPalette = nullptr;
size_t paletteSize = 16 * 16;
uint32_t width = 0;
uint32_t height = 0;
uint8_t colorType = 0;
uint8_t bitDepth = 0;
bool hasImageData = false;
bool isColorIndexed = false;
double GetBytesPerPixel() const;
void FreeImageData();
};

471
ZAPDTR/ZAPD/Main.cpp Normal file
View File

@ -0,0 +1,471 @@
#include "Globals.h"
#include "Overlays/ZOverlay.h"
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "WarningHandler.h"
#include "ZAnimation.h"
#include "ZBackground.h"
#include "ZBlob.h"
#include "ZFile.h"
#include "ZTexture.h"
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#include <csignal>
#include <cstdlib>
#include <ctime>
#include <cxxabi.h> // for __cxa_demangle
#include <dlfcn.h> // for dladdr
#include <execinfo.h>
#include <unistd.h>
#endif
#include <string>
#include <string_view>
#include "tinyxml2.h"
//extern const char gBuildHash[];
const char gBuildHash[] = "";
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
ZFileMode fileMode);
void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const fs::path& outPath);
void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath);
void BuildAssetBlob(const fs::path& blobFilePath, const fs::path& outPath);
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#define ARRAY_COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
void ErrorHandler(int sig)
{
void* array[4096];
const size_t nMaxFrames = sizeof(array) / sizeof(array[0]);
size_t size = backtrace(array, nMaxFrames);
char** symbols = backtrace_symbols(array, nMaxFrames);
fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig);
// Feel free to add more crash messages.
const char* crashEasterEgg[] = {
"\tYou've met with a terrible fate, haven't you?",
"\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!",
"\tZAPD has fallen and cannot get up.",
};
srand(time(nullptr));
auto easterIndex = rand() % ARRAY_COUNT(crashEasterEgg);
fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]);
fprintf(stderr, "Traceback:\n");
for (size_t i = 1; i < size; i++)
{
Dl_info info;
uint32_t gotAddress = dladdr(array[i], &info);
std::string functionName(symbols[i]);
if (gotAddress != 0 && info.dli_sname != nullptr)
{
int32_t status;
char* demangled = abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, &status);
const char* nameFound = info.dli_sname;
if (status == 0)
{
nameFound = demangled;
}
functionName = StringHelper::Sprintf("%s (+0x%X)", nameFound,
(char*)array[i] - (char*)info.dli_saddr);
free(demangled);
}
fprintf(stderr, "%-3zd %s\n", i, functionName.c_str());
}
fprintf(stderr, "\n");
free(symbols);
exit(1);
}
#endif
int main(int argc, char* argv[])
{
// Syntax: ZAPD.out [mode (btex/bovl/e)] (Arbritrary Number of Arguments)
if (argc < 2)
{
printf("ZAPD.out (%s) [mode (btex/bovl/bsf/bblb/bmdlintr/bamnintr/e)] ...\n", gBuildHash);
return 1;
}
Globals* g = new Globals();
WarningHandler::Init(argc, argv);
for (int i = 1; i < argc; i++)
{
if (!strcmp(argv[i], "--version"))
{
printf("ZAPD.out %s\n", gBuildHash);
return 0;
}
else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h"))
{
printf("Congratulations!\n");
printf("You just found the (unimplemented and undocumented) ZAPD's help message.\n");
printf("Feel free to implement it if you want :D\n");
WarningHandler::PrintHelp();
return 0;
}
}
// Parse other "commands"
for (int32_t i = 2; i < argc; i++)
{
std::string arg = argv[i];
if (arg == "-o" || arg == "--outputpath") // Set output path
{
Globals::Instance->outputPath = argv[++i];
if (Globals::Instance->sourceOutputPath == "")
Globals::Instance->sourceOutputPath = Globals::Instance->outputPath;
}
else if (arg == "-i" || arg == "--inputpath") // Set input path
{
Globals::Instance->inputPath = argv[++i];
}
else if (arg == "-b" || arg == "--baserompath") // Set baserom path
{
Globals::Instance->baseRomPath = argv[++i];
}
else if (arg == "-osf") // Set source output path
{
Globals::Instance->sourceOutputPath = argv[++i];
}
else if (arg == "-gsf") // Generate source file during extraction
{
Globals::Instance->genSourceFile = std::string_view(argv[++i]) == "1";
}
else if (arg == "-tm") // Test Mode (enables certain experimental features)
{
Globals::Instance->testMode = std::string_view(argv[++i]) == "1";
}
else if (arg == "-crc" ||
arg == "--output-crc") // Outputs a CRC file for each extracted texture.
{
Globals::Instance->testMode = std::string_view(argv[++i]) == "1";
}
else if (arg == "-ulzdl") // Use Legacy ZDisplay List
{
Globals::Instance->useLegacyZDList = std::string_view(argv[++i]) == "1";
}
else if (arg == "-profile") // Enable profiling
{
Globals::Instance->profile = std::string_view(argv[++i]) == "1";
}
else if (arg ==
"-uer") // Split resources into their individual components (enabled by default)
// TODO: We may wish to make this a part of the config file...
{
Globals::Instance->useExternalResources = std::string_view(argv[++i]) == "1";
}
else if (arg == "-tt") // Set texture type
{
Globals::Instance->texType = ZTexture::GetTextureTypeFromString(argv[++i]);
}
else if (arg == "-cfg") // Set cfg path (for overlays)
// TODO: Change the name of this to something else so it doesn't
// get confused with XML config files.
{
Globals::Instance->cfgPath = argv[++i];
}
else if (arg == "-rconf") // Read Config File
{
Globals::Instance->cfg.ReadConfigFile(argv[++i]);
}
else if (arg == "-eh") // Enable Error Handler
{
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
signal(SIGSEGV, ErrorHandler);
signal(SIGABRT, ErrorHandler);
#else
HANDLE_WARNING(WarningType::Always,
"tried to set error handler, but this ZAPD build lacks support for one",
"");
#endif
}
else if (arg == "-v") // Verbose
{
Globals::Instance->verbosity = static_cast<VerbosityLevel>(strtol(argv[++i], NULL, 16));
}
else if (arg == "-vu" || arg == "--verbose-unaccounted") // Verbose unaccounted
{
Globals::Instance->verboseUnaccounted = true;
}
else if (arg == "-se" || arg == "--set-exporter") // Set Current Exporter
{
Globals::Instance->currentExporter = argv[++i];
}
else if (arg == "--gcc-compat") // GCC compatibility
{
Globals::Instance->gccCompat = true;
}
else if (arg == "-s" || arg == "--static")
{
Globals::Instance->forceStatic = true;
}
else if (arg == "-us" || arg == "--unaccounted-static")
{
Globals::Instance->forceUnaccountedStatic = true;
}
}
// Parse File Mode
ExporterSet* exporterSet = Globals::Instance->GetExporterSet();
std::string buildMode = argv[1];
ZFileMode fileMode = ZFileMode::Invalid;
if (buildMode == "btex")
fileMode = ZFileMode::BuildTexture;
else if (buildMode == "bren")
fileMode = ZFileMode::BuildBackground;
else if (buildMode == "bovl")
fileMode = ZFileMode::BuildOverlay;
else if (buildMode == "bsf")
fileMode = ZFileMode::BuildSourceFile;
else if (buildMode == "bblb")
fileMode = ZFileMode::BuildBlob;
else if (buildMode == "e")
fileMode = ZFileMode::Extract;
else if (exporterSet != nullptr && exporterSet->parseFileModeFunc != nullptr)
exporterSet->parseFileModeFunc(buildMode, fileMode);
if (fileMode == ZFileMode::Invalid)
{
printf("Error: Invalid file mode '%s'\n", buildMode.c_str());
return 1;
}
// We've parsed through our commands once. If an exporter exists, it's been set by now.
// Now we'll parse through them again but pass them on to our exporter if one is available.
if (exporterSet != nullptr && exporterSet->parseArgsFunc != nullptr)
{
for (int32_t i = 2; i < argc; i++)
exporterSet->parseArgsFunc(argc, argv, i);
}
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
WarningHandler::PrintWarningsDebugInfo();
}
// TODO: switch
if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile)
{
bool procFileModeSuccess = false;
if (exporterSet != nullptr && exporterSet->processFileModeFunc != nullptr)
procFileModeSuccess = exporterSet->processFileModeFunc(fileMode);
if (!procFileModeSuccess)
{
bool parseSuccessful;
for (auto& extFile : Globals::Instance->cfg.externalFiles)
{
fs::path externalXmlFilePath =
Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath;
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
{
printf("Parsing external file from config: '%s'\n",
externalXmlFilePath.c_str());
}
parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath,
extFile.outPath, ZFileMode::ExternalFile);
if (!parseSuccessful)
return 1;
}
parseSuccessful = Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath,
Globals::Instance->outputPath, fileMode);
if (!parseSuccessful)
return 1;
}
}
else if (fileMode == ZFileMode::BuildTexture)
{
TextureType texType = Globals::Instance->texType;
BuildAssetTexture(Globals::Instance->inputPath, texType, Globals::Instance->outputPath);
}
else if (fileMode == ZFileMode::BuildBackground)
{
BuildAssetBackground(Globals::Instance->inputPath, Globals::Instance->outputPath);
}
else if (fileMode == ZFileMode::BuildBlob)
{
BuildAssetBlob(Globals::Instance->inputPath, Globals::Instance->outputPath);
}
else if (fileMode == ZFileMode::BuildOverlay)
{
ZOverlay* overlay =
ZOverlay::FromBuild(Path::GetDirectoryName(Globals::Instance->inputPath),
Path::GetDirectoryName(Globals::Instance->cfgPath));
if (overlay != nullptr)
File::WriteAllText(Globals::Instance->outputPath.string(),
overlay->GetSourceOutputCode(""));
}
delete g;
return 0;
}
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
ZFileMode fileMode)
{
tinyxml2::XMLDocument doc;
tinyxml2::XMLError eResult = doc.LoadFile(xmlFilePath.string().c_str());
if (eResult != tinyxml2::XML_SUCCESS)
{
// TODO: use XMLDocument::ErrorIDToName to get more specific error messages here
HANDLE_ERROR(WarningType::InvalidXML,
StringHelper::Sprintf("invalid XML file: '%s'", xmlFilePath.c_str()), "");
return false;
}
tinyxml2::XMLNode* root = doc.FirstChild();
if (root == nullptr)
{
HANDLE_WARNING(
WarningType::InvalidXML,
StringHelper::Sprintf("missing Root tag in xml file: '%s'", xmlFilePath.c_str()), "");
return false;
}
for (tinyxml2::XMLElement* child = root->FirstChildElement(); child != NULL;
child = child->NextSiblingElement())
{
if (std::string_view(child->Name()) == "File")
{
ZFile* file = new ZFile(fileMode, child, basePath, outPath, "", xmlFilePath);
Globals::Instance->files.push_back(file);
if (fileMode == ZFileMode::ExternalFile)
{
Globals::Instance->externalFiles.push_back(file);
file->isExternalFile = true;
}
}
else if (std::string(child->Name()) == "ExternalFile")
{
const char* xmlPathValue = child->Attribute("XmlPath");
if (xmlPathValue == nullptr)
{
throw std::runtime_error(StringHelper::Sprintf(
"Parse: Fatal error in '%s'.\n"
"\t Missing 'XmlPath' attribute in `ExternalFile` element.\n",
xmlFilePath.c_str()));
}
const char* outPathValue = child->Attribute("OutPath");
if (outPathValue == nullptr)
{
throw std::runtime_error(StringHelper::Sprintf(
"Parse: Fatal error in '%s'.\n"
"\t Missing 'OutPath' attribute in `ExternalFile` element.\n",
xmlFilePath.c_str()));
}
fs::path externalXmlFilePath =
Globals::Instance->cfg.externalXmlFolder / fs::path(xmlPathValue);
fs::path externalOutFilePath = fs::path(outPathValue);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
{
printf("Parsing external file: '%s'\n", externalXmlFilePath.c_str());
}
// Recursion. What can go wrong?
Parse(externalXmlFilePath, basePath, externalOutFilePath, ZFileMode::ExternalFile);
}
else
{
std::string errorHeader =
StringHelper::Sprintf("when parsing file '%s'", xmlFilePath.c_str());
std::string errorBody = StringHelper::Sprintf(
"Found a resource outside a File element: '%s'", child->Name());
HANDLE_ERROR(WarningType::InvalidXML, errorHeader, errorBody);
}
}
if (fileMode != ZFileMode::ExternalFile)
{
ExporterSet* exporterSet = Globals::Instance->GetExporterSet();
if (exporterSet != nullptr && exporterSet->beginXMLFunc != nullptr)
exporterSet->beginXMLFunc();
for (ZFile* file : Globals::Instance->files)
{
if (fileMode == ZFileMode::BuildSourceFile)
file->BuildSourceFile();
else
file->ExtractResources();
}
if (exporterSet != nullptr && exporterSet->endXMLFunc != nullptr)
exporterSet->endXMLFunc();
}
return true;
}
void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const fs::path& outPath)
{
std::string name = outPath.stem().string();
ZTexture tex(nullptr);
if (name.find("u32") != std::string::npos)
tex.dWordAligned = false;
tex.FromPNG(pngFilePath.string(), texType);
std::string cfgPath = StringHelper::Split(pngFilePath.string(), ".")[0] + ".cfg";
if (File::Exists(cfgPath))
name = File::ReadAllText(cfgPath);
std::string src = tex.GetBodySourceCode();
File::WriteAllText(outPath.string(), src);
}
void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath)
{
ZBackground background(nullptr);
background.ParseBinaryFile(imageFilePath.string(), false);
File::WriteAllText(outPath.string(), background.GetBodySourceCode());
}
void BuildAssetBlob(const fs::path& blobFilePath, const fs::path& outPath)
{
ZBlob* blob = ZBlob::FromFile(blobFilePath.string());
std::string name = outPath.stem().string(); // filename without extension
std::string src = blob->GetBodySourceCode();
File::WriteAllText(outPath.string(), src);
delete blob;
}

View File

View File

@ -0,0 +1,343 @@
#include "SkinLimbStructs.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZDisplayList.h"
#include "ZFile.h"
/* Struct_800A57C0 */
Struct_800A57C0::Struct_800A57C0(ZFile* nParent) : ZResource(nParent)
{
}
void Struct_800A57C0::ParseRawData()
{
const auto& rawData = parent->GetRawData();
unk_0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x00);
unk_2 = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x02);
unk_4 = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x04);
unk_6 = BitConverter::ToInt8BE(rawData, rawDataIndex + 0x06);
unk_7 = BitConverter::ToInt8BE(rawData, rawDataIndex + 0x07);
unk_8 = BitConverter::ToInt8BE(rawData, rawDataIndex + 0x08);
unk_9 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x09);
}
std::string Struct_800A57C0::GetBodySourceCode() const
{
return StringHelper::Sprintf("0x%02X, %i, %i, %i, %i, %i, 0x%02X", unk_0, unk_2, unk_4, unk_6,
unk_7, unk_8, unk_9);
}
std::string Struct_800A57C0::GetSourceTypeName() const
{
return "Struct_800A57C0";
}
ZResourceType Struct_800A57C0::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
size_t Struct_800A57C0::GetRawDataSize() const
{
return 0x0A;
}
/* Struct_800A598C_2 */
Struct_800A598C_2::Struct_800A598C_2(ZFile* nParent) : ZResource(nParent)
{
}
void Struct_800A598C_2::ParseRawData()
{
const auto& rawData = parent->GetRawData();
unk_0 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x00);
x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x02);
y = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x04);
z = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x06);
unk_8 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08);
}
std::string Struct_800A598C_2::GetBodySourceCode() const
{
return StringHelper::Sprintf("0x%02X, %i, %i, %i, 0x%02X", unk_0, x, y, z, unk_8);
}
std::string Struct_800A598C_2::GetSourceTypeName() const
{
return "Struct_800A598C_2";
}
ZResourceType Struct_800A598C_2::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
size_t Struct_800A598C_2::GetRawDataSize() const
{
return 0x0A;
}
/* Struct_800A598C */
Struct_800A598C::Struct_800A598C(ZFile* nParent) : ZResource(nParent)
{
}
void Struct_800A598C::ParseRawData()
{
const auto& rawData = parent->GetRawData();
unk_0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x00);
unk_2 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x02);
unk_4 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x04);
unk_8 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x08);
unk_C = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0C);
if (unk_8 != 0 && GETSEGNUM(unk_8) == parent->segment)
{
uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress);
for (size_t i = 0; i < unk_0; i++)
{
Struct_800A57C0 unk8_data(parent);
unk8_data.ExtractFromFile(unk_8_Offset);
unk_8_arr.push_back(unk8_data);
unk_8_Offset += unk8_data.GetRawDataSize();
}
}
if (unk_C != 0 && GETSEGNUM(unk_8) == parent->segment)
{
uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress);
for (size_t i = 0; i < unk_2; i++)
{
Struct_800A598C_2 unkC_data(parent);
unkC_data.ExtractFromFile(unk_C_Offset);
unk_C_arr.push_back(unkC_data);
unk_C_Offset += unkC_data.GetRawDataSize();
}
}
}
void Struct_800A598C::DeclareReferences(const std::string& prefix)
{
std::string varPrefix = prefix;
if (name != "")
varPrefix = name;
if (unk_8 != 0 && GETSEGNUM(unk_8) == parent->segment)
{
const auto& res = unk_8_arr.at(0);
std::string unk_8_Str = res.GetDefaultName(varPrefix);
size_t arrayItemCnt = unk_8_arr.size();
std::string entryStr = "";
for (size_t i = 0; i < arrayItemCnt; i++)
{
auto& child = unk_8_arr[i];
child.DeclareReferences(varPrefix);
entryStr += StringHelper::Sprintf("\t{ %s },", child.GetBodySourceCode().c_str());
if (i < arrayItemCnt - 1)
entryStr += "\n";
}
uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress);
Declaration* decl = parent->GetDeclaration(unk_8_Offset);
if (decl == nullptr)
{
parent->AddDeclarationArray(unk_8_Offset, res.GetDeclarationAlignment(),
arrayItemCnt * res.GetRawDataSize(),
res.GetSourceTypeName(), unk_8_Str, arrayItemCnt, entryStr);
}
else
decl->text = entryStr;
}
if (unk_C != 0 && GETSEGNUM(unk_C) == parent->segment)
{
const auto& res = unk_C_arr.at(0);
std::string unk_C_Str = res.GetDefaultName(varPrefix);
size_t arrayItemCnt = unk_C_arr.size();
std::string entryStr = "";
for (size_t i = 0; i < arrayItemCnt; i++)
{
auto& child = unk_C_arr[i];
child.DeclareReferences(varPrefix);
entryStr += StringHelper::Sprintf("\t{ %s },", child.GetBodySourceCode().c_str());
if (i < arrayItemCnt - 1)
entryStr += "\n";
}
uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress);
Declaration* decl = parent->GetDeclaration(unk_C_Offset);
if (decl == nullptr)
{
parent->AddDeclarationArray(unk_C_Offset, res.GetDeclarationAlignment(),
arrayItemCnt * res.GetRawDataSize(),
res.GetSourceTypeName(), unk_C_Str, arrayItemCnt, entryStr);
}
else
decl->text = entryStr;
}
}
std::string Struct_800A598C::GetBodySourceCode() const
{
std::string unk_8_Str;
std::string unk_C_Str;
Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Struct_800A57C0", unk_8_Str);
Globals::Instance->GetSegmentedPtrName(unk_C, parent, "Struct_800A598C_2", unk_C_Str);
std::string entryStr = StringHelper::Sprintf("\n\t\tARRAY_COUNTU(%s), ARRAY_COUNTU(%s),\n",
unk_8_Str.c_str(), unk_C_Str.c_str());
entryStr +=
StringHelper::Sprintf("\t\t%i, %s, %s\n\t", unk_4, unk_8_Str.c_str(), unk_C_Str.c_str());
return entryStr;
}
std::string Struct_800A598C::GetSourceTypeName() const
{
return "Struct_800A598C";
}
ZResourceType Struct_800A598C::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
size_t Struct_800A598C::GetRawDataSize() const
{
return 0x10;
}
/* Struct_800A5E28 */
Struct_800A5E28::Struct_800A5E28(ZFile* nParent) : ZResource(nParent)
{
}
void Struct_800A5E28::ParseRawData()
{
const auto& rawData = parent->GetRawData();
unk_0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x00);
unk_2 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x02);
unk_4 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x04);
unk_8 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x08);
if (unk_4 != 0 && GETSEGNUM(unk_4) == parent->segment)
{
uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress);
for (size_t i = 0; i < unk_2; i++)
{
Struct_800A598C unk_4_data(parent);
unk_4_data.ExtractFromFile(unk_4_Offset);
unk_4_arr.push_back(unk_4_data);
unk_4_Offset += unk_4_data.GetRawDataSize();
}
}
}
void Struct_800A5E28::DeclareReferences(const std::string& prefix)
{
std::string varPrefix = prefix;
if (name != "")
varPrefix = name;
ZResource::DeclareReferences(varPrefix);
if (unk_4 != SEGMENTED_NULL && GETSEGNUM(unk_4) == parent->segment)
{
const auto& res = unk_4_arr.at(0);
std::string unk_4_Str = res.GetDefaultName(varPrefix);
size_t arrayItemCnt = unk_4_arr.size();
std::string entryStr = "";
for (size_t i = 0; i < arrayItemCnt; i++)
{
auto& child = unk_4_arr[i];
child.DeclareReferences(varPrefix);
entryStr += StringHelper::Sprintf("\t{ %s },", child.GetBodySourceCode().c_str());
if (i < arrayItemCnt - 1)
entryStr += "\n";
}
uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress);
Declaration* decl = parent->GetDeclaration(unk_4_Offset);
if (decl == nullptr)
{
parent->AddDeclarationArray(unk_4_Offset, res.GetDeclarationAlignment(),
arrayItemCnt * res.GetRawDataSize(),
res.GetSourceTypeName(), unk_4_Str, arrayItemCnt, entryStr);
}
else
decl->text = entryStr;
}
if (unk_8 != SEGMENTED_NULL && GETSEGNUM(unk_8) == parent->segment)
{
uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress);
int32_t dlistLength = ZDisplayList::GetDListLength(
parent->GetRawData(), unk_8_Offset,
Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX);
unk_8_dlist = new ZDisplayList(parent);
unk_8_dlist->ExtractFromBinary(unk_8_Offset, dlistLength);
std::string dListStr =
StringHelper::Sprintf("%sSkinLimbDL_%06X", varPrefix.c_str(), unk_8_Offset);
unk_8_dlist->SetName(dListStr);
unk_8_dlist->DeclareVar(varPrefix, "");
unk_8_dlist->DeclareReferences(varPrefix);
parent->AddResource(unk_8_dlist);
}
}
std::string Struct_800A5E28::GetBodySourceCode() const
{
std::string unk_4_Str;
std::string unk_8_Str;
Globals::Instance->GetSegmentedPtrName(unk_4, parent, "Struct_800A598C", unk_4_Str);
Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Gfx", unk_8_Str);
std::string entryStr = "\n";
entryStr += StringHelper::Sprintf("\t%i, ARRAY_COUNTU(%s),\n", unk_0, unk_4_Str.c_str());
entryStr += StringHelper::Sprintf("\t%s, %s\n", unk_4_Str.c_str(), unk_8_Str.c_str());
return entryStr;
}
std::string Struct_800A5E28::GetSourceTypeName() const
{
return "Struct_800A5E28";
}
ZResourceType Struct_800A5E28::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
size_t Struct_800A5E28::GetRawDataSize() const
{
return 0x0C;
}

View File

@ -0,0 +1,114 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "ZResource.h"
#include "ZDisplayList.h"
// TODO: check if more types exists
enum class ZLimbSkinType
{
SkinType_0, // Segment = 0
SkinType_4 = 4, // Segment = segmented address // Struct_800A5E28
SkinType_5 = 5, // Segment = 0
SkinType_DList = 11, // Segment = DList address
};
class Struct_800A57C0 : public ZResource
{
public:
Struct_800A57C0(ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
public:
uint16_t unk_0;
int16_t unk_2;
int16_t unk_4;
int8_t unk_6;
int8_t unk_7;
int8_t unk_8;
uint8_t unk_9;
};
class Struct_800A598C_2 : public ZResource
{
public:
Struct_800A598C_2(ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
public:
uint8_t unk_0;
int16_t x;
int16_t y;
int16_t z;
uint8_t unk_8;
};
class Struct_800A598C : public ZResource
{
public:
Struct_800A598C(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
public:
uint16_t unk_0; // Length of unk_8
uint16_t unk_2; // Length of unk_C
uint16_t unk_4; // 0 or 1 // Used as an index for unk_C
segptr_t unk_8; // Struct_800A57C0*
segptr_t unk_C; // Struct_800A598C_2*
std::vector<Struct_800A57C0> unk_8_arr;
std::vector<Struct_800A598C_2> unk_C_arr;
};
class Struct_800A5E28 : public ZResource
{
public:
Struct_800A5E28(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
public:
uint16_t unk_0; // Vtx count
uint16_t unk_2; // Length of unk_4
segptr_t unk_4; // Struct_800A598C*
segptr_t unk_8; // Gfx*
std::vector<Struct_800A598C> unk_4_arr;
ZDisplayList* unk_8_dlist = nullptr;
};

View File

@ -0,0 +1,119 @@
#include "OutputFormatter.h"
#include <Globals.h>
void OutputFormatter::Flush()
{
//if (!Globals::Instance->otrMode)
{
if (col > lineLimit && !Globals::Instance->otrMode)
{
str.append(1, '\n');
str.append(currentIndent, ' ');
uint32_t newCol = currentIndent + (wordP - word);
for (uint32_t i = 0; i < wordNests; i++)
nestIndent[nest - i] -= col - newCol;
col = newCol;
}
else
{
str.append(space, spaceP - space);
}
spaceP = space;
str.append(word, wordP - word);
wordP = word;
wordNests = 0;
}
}
int OutputFormatter::Write(const char* buf, int count)
{
for (int i = 0; i < count; i++)
{
char c = buf[i];
if (c == ' ' || c == '\t' || c == '\n')
{
if (wordP - word != 0)
{
Flush();
}
if (c == '\n')
{
col = 0;
*spaceP++ = c;
}
else if (c == '\t')
{
int n = tabSize - (col % tabSize);
col += n;
for (int j = 0; j < n; j++)
*spaceP++ = ' ';
}
else
{
col++;
*spaceP++ = c;
}
currentIndent = nestIndent[nest];
}
else
{
col++;
if (c == '(')
{
nest++;
nestIndent[nest] = col;
wordNests++;
}
else if (c == ')')
{
if (nest > 0)
nest--;
if (wordNests > 0)
wordNests--;
}
*wordP++ = c;
}
}
return count;
}
int OutputFormatter::Write(const std::string& buf)
{
return Write(buf.data(), buf.size());
}
OutputFormatter* OutputFormatter::Instance;
int OutputFormatter::WriteStatic(const char* buf, int count)
{
return Instance->Write(buf, count);
}
int (*OutputFormatter::StaticWriter())(const char* buf, int count)
{
Instance = this;
return &WriteStatic;
}
OutputFormatter::OutputFormatter(uint32_t tabSize, uint32_t indentation, uint32_t lineLimit)
: tabSize{tabSize}, lineLimit{lineLimit}, col{0}, nest{0}, nestIndent{indentation},
currentIndent{indentation}, wordNests(0), wordP{word}, spaceP{space}
{
}
std::string OutputFormatter::GetOutput()
{
Flush();
return std::move(str);
}

View File

@ -0,0 +1,40 @@
#pragma once
#include <map>
#include <string>
#include <vector>
class OutputFormatter
{
private:
const uint32_t tabSize;
const uint32_t lineLimit;
uint32_t col;
uint32_t nest;
uint32_t nestIndent[8];
uint32_t currentIndent;
uint32_t wordNests;
char word[128];
char space[128];
char* wordP;
char* spaceP;
std::string str;
void Flush();
static OutputFormatter* Instance;
static int WriteStatic(const char* buf, int count);
public:
OutputFormatter(uint32_t tabSize = 4, uint32_t indentation = 4, uint32_t lineLimit = 120);
int (*StaticWriter())(const char* buf, int count); // Must be `int` due to libgfxd
int Write(const char* buf, int count);
int Write(const std::string& buf);
std::string GetOutput();
};

View File

@ -0,0 +1,352 @@
#include "ZOverlay.h"
#include <cassert>
#include <unordered_set>
#include "Globals.h"
#include "Utils/Directory.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
using namespace ELFIO;
const char* RelocationEntry::GetSectionName() const
{
switch (sectionType)
{
case SectionType::Text:
return ".text";
case SectionType::Data:
return ".data";
case SectionType::RoData:
return ".rodata";
case SectionType::Bss:
return ".bss";
case SectionType::ERROR:
return ".ERROR";
}
assert(!"Oh no :c");
}
const char* RelocationEntry::GetRelocTypeName() const
{
switch (relocationType)
{
case RelocationType::R_MIPS_32:
return "R_MIPS_32";
case RelocationType::R_MIPS_26:
return "R_MIPS_26";
case RelocationType::R_MIPS_HI16:
return "R_MIPS_HI16";
case RelocationType::R_MIPS_LO16:
return "R_MIPS_LO16";
}
assert(!"Oh no :c");
}
ZOverlay::ZOverlay()
{
name = "";
entries = std::vector<RelocationEntry*>();
}
ZOverlay::ZOverlay(const std::string& nName) : ZOverlay()
{
name = nName;
}
ZOverlay::~ZOverlay()
{
for (auto entry : entries)
if (entry)
delete entry;
entries.clear();
}
static const std::unordered_set<std::string> sRelSections = {
".rel.text",
".rel.data",
".rel.rodata",
};
static const std::unordered_set<std::string> sSections = {
".text", ".data", ".symtab", ".rodata", ".rodata.str1.4", ".rodata.cst4", ".rodata.cst8",
};
ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath)
{
std::string cfgText = File::ReadAllText(cfgFolderPath / "overlay.cfg");
std::vector<std::string> cfgLines = StringHelper::Split(cfgText, "\n");
ZOverlay* ovl = new ZOverlay(StringHelper::Strip(cfgLines[0], "\r"));
ovl->cfgLines = cfgLines;
int32_t sectionOffs[5] = {0};
std::vector<RelocationEntry*> textRelocs;
std::vector<RelocationEntry*> dataRelocs;
std::vector<RelocationEntry*> rodataRelocs;
// get the elf files
std::vector<elfio*> readers;
for (size_t i = 1; i < cfgLines.size(); i++)
{
std::string elfPath =
(buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string();
elfio* reader = new elfio();
if (!reader->load(elfPath))
{
// not all files were compiled
for (auto r : readers)
delete r;
readers.clear();
delete ovl;
return nullptr;
}
readers.push_back(reader);
}
for (size_t curReaderId = 0; curReaderId < readers.size(); curReaderId++)
{
auto& curReader = readers[curReaderId];
Elf_Half sec_num = curReader->sections.size();
for (int32_t i = 0; i < sec_num; i++)
{
section* pSec = curReader->sections[i];
if (pSec->get_type() != SHT_REL ||
sRelSections.find(pSec->get_name()) == sRelSections.end())
{
continue;
}
symbol_section_accessor currentSymbols(*curReader,
curReader->sections[(Elf_Half)pSec->get_link()]);
SectionType sectionType = GetSectionTypeFromStr(pSec->get_name());
if (sectionType == SectionType::ERROR)
{
HANDLE_WARNING(WarningType::Always, "one of the section types returned ERROR", "");
}
relocation_section_accessor relocs(*curReader, pSec);
for (Elf_Xword j = 0; j < relocs.get_entries_num(); j++)
{
Elf64_Addr offset = 0;
Elf_Word symbol = 0;
Elf_Word type = 0;
{
Elf_Sxword addend = 0;
relocs.get_entry(j, offset, symbol, type, addend);
}
std::string curSymName;
Elf_Half curSymShndx = SHN_UNDEF;
{
Elf64_Addr value;
Elf_Xword size;
unsigned char bind;
unsigned char type;
unsigned char other;
currentSymbols.get_symbol(symbol, curSymName, value, size, bind, type,
curSymShndx, other);
}
// check symbols outside the elf but within the overlay
if (curSymShndx == SHN_UNDEF)
{
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf("Symbol '%s' doesn't exist in current .o file (%s). Searching...\n",
curSymName.c_str(), cfgLines[curReaderId + 1].c_str());
}
for (size_t readerId = 0; readerId < readers.size(); readerId++)
{
auto& reader = readers[readerId];
if (curSymShndx != SHN_UNDEF)
break;
if (reader == curReader)
continue;
auto sectionData = reader->sections[(Elf_Half)pSec->get_link()];
curSymShndx =
ovl->FindSymbolInSection(curSymName, sectionData, *reader, readerId);
if (curSymShndx != SHN_UNDEF)
break;
if (Globals::Instance->gccCompat)
{
// Symbol wasn't found, try checking every section
Elf_Half sec_num = reader->sections.size();
for (int32_t otherSectionIdx = 0; otherSectionIdx < sec_num;
otherSectionIdx++)
{
if (curSymShndx != SHN_UNDEF)
{
break;
}
auto sectionDataIter = reader->sections[otherSectionIdx];
curSymShndx = ovl->FindSymbolInSection(curSymName, sectionDataIter,
*reader, readerId);
}
}
}
}
if (curSymShndx != SHN_UNDEF)
{
RelocationType typeConverted = (RelocationType)type;
offset += sectionOffs[static_cast<size_t>(sectionType)];
RelocationEntry* reloc =
new RelocationEntry(sectionType, typeConverted, offset);
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf(".word 0x%08X # %s %s 0x%04X\n", reloc->CalcRelocationWord(),
reloc->GetSectionName(), reloc->GetRelocTypeName(), reloc->offset);
}
// this is to keep the correct reloc entry order
if (sectionType == SectionType::Text)
textRelocs.push_back(reloc);
if (sectionType == SectionType::Data)
dataRelocs.push_back(reloc);
if (sectionType == SectionType::RoData)
rodataRelocs.push_back(reloc);
}
}
}
// increase section offsets
for (int32_t i = 0; i < sec_num; i++)
{
section* pSec = curReader->sections[i];
if (pSec->get_type() == SHT_PROGBITS &&
sSections.find(pSec->get_name()) != sSections.end())
{
SectionType sectionType = GetSectionTypeFromStr(pSec->get_name());
sectionOffs[static_cast<size_t>(sectionType)] += pSec->get_size();
}
}
}
ovl->entries.reserve(textRelocs.size() + dataRelocs.size() + rodataRelocs.size());
ovl->entries.insert(ovl->entries.end(), textRelocs.begin(), textRelocs.end());
ovl->entries.insert(ovl->entries.end(), dataRelocs.begin(), dataRelocs.end());
ovl->entries.insert(ovl->entries.end(), rodataRelocs.begin(), rodataRelocs.end());
for (auto r : readers)
delete r;
readers.clear();
return ovl;
}
std::string ZOverlay::GetSourceOutputCode([[maybe_unused]] const std::string& prefix)
{
std::string output;
output += ".section .ovl\n";
output += StringHelper::Sprintf("# %sOverlayInfo\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentTextSize\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentDataSize\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentRoDataSize\n", name.c_str());
output += StringHelper::Sprintf(".word _%sSegmentBssSize\n", name.c_str());
output += "\n";
output += StringHelper::Sprintf(".word %i # reloc_count\n", entries.size());
for (size_t i = 0; i < entries.size(); i++)
{
RelocationEntry* reloc = entries[i];
output += StringHelper::Sprintf(".word 0x%08X # %s %s 0x%04X\n",
reloc->CalcRelocationWord(), reloc->GetSectionName(),
reloc->GetRelocTypeName(), reloc->offset);
}
size_t offset = (entries.size() * 4) + 20;
while (offset % 16 != 12)
{
output += ".word 0\n";
offset += 4;
}
output += "\n";
output +=
StringHelper::Sprintf(".word 0x%08X # %sOverlayInfoOffset\n", offset + 4, name.c_str());
return output;
}
SectionType ZOverlay::GetSectionTypeFromStr(const std::string& sectionName)
{
if (sectionName == ".rel.text" || sectionName == ".text")
return SectionType::Text;
else if (sectionName == ".rel.data" || sectionName == ".data")
return SectionType::Data;
else if (sectionName == ".rel.rodata" || sectionName == ".rodata" ||
sectionName == ".rodata.str1.4" || sectionName == ".rodata.cst4")
return SectionType::RoData;
else if (sectionName == ".rel.bss" || sectionName == ".bss")
return SectionType::Bss;
return SectionType::ERROR;
}
ELFIO::Elf_Half ZOverlay::FindSymbolInSection(const std::string& curSymName,
ELFIO::section* sectionData, ELFIO::elfio& reader,
size_t readerId)
{
if (sectionData == nullptr)
return SHN_UNDEF;
auto sectionDataName = sectionData->get_name();
if (sSections.find(sectionDataName) == sSections.end())
return SHN_UNDEF;
#ifdef DEVELOPMENT
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf("\t File '%s' section: %s \n", cfgLines[readerId + 1].c_str(),
sectionDataName.c_str());
}
#endif
symbol_section_accessor symbols(reader, sectionData);
Elf_Xword symbolNum = symbols.get_symbols_num();
for (Elf_Xword symIdx = 0; symIdx < symbolNum; symIdx++)
{
Elf_Half shndx = SHN_UNDEF;
Elf64_Addr value;
std::string name;
Elf_Xword size;
unsigned char bind;
unsigned char type;
unsigned char other;
symbols.get_symbol(symIdx, name, value, size, bind, type, shndx, other);
if (name == curSymName)
{
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
{
printf("\t Symbol '%s' found in '%s' '%s' \n", curSymName.c_str(),
cfgLines[readerId + 1].c_str(), sectionDataName.c_str());
}
return shndx;
}
}
return SHN_UNDEF;
}

View File

@ -0,0 +1,75 @@
#pragma once
#include "Utils/Directory.h"
#include "ZResource.h"
#include "elfio/elfio.hpp"
#include "tinyxml2.h"
enum class SectionType
{
Text = 1,
Data = 2,
RoData = 3,
Bss = 4,
ERROR = 255
};
enum class RelocationType
{
R_MIPS_32 = 2,
R_MIPS_26 = 4,
R_MIPS_HI16 = 5,
R_MIPS_LO16 = 6,
};
class RelocationEntry
{
public:
SectionType sectionType;
RelocationType relocationType;
int32_t offset;
RelocationEntry(SectionType nSecType, RelocationType nRelType, int32_t nOffset)
{
sectionType = nSecType;
relocationType = nRelType;
offset = nOffset;
}
uint32_t CalcRelocationWord()
{
uint32_t relocationWord = 0;
relocationWord |= static_cast<uint32_t>(sectionType) << 30;
relocationWord |= static_cast<uint32_t>(relocationType) << 24;
relocationWord |= offset;
return relocationWord;
}
const char* GetSectionName() const;
const char* GetRelocTypeName() const;
};
class ZOverlay
{
public:
std::string name;
ZOverlay(const std::string& nName);
~ZOverlay();
static ZOverlay* FromBuild(fs::path buildPath, fs::path cfgFolderPath);
std::string GetSourceOutputCode(const std::string& prefix);
private:
std::vector<RelocationEntry*> entries;
std::vector<std::string> cfgLines;
ZOverlay();
static SectionType GetSectionTypeFromStr(const std::string& sectionName);
// static std::string GetOverlayNameFromElf(ELFIO::elfio& reader);
ELFIO::Elf_Half FindSymbolInSection(const std::string& curSymName, ELFIO::section* sectionData,
ELFIO::elfio& reader, size_t readerId);
};

View File

@ -0,0 +1,443 @@
/**
* ZAPD Warning- and Error-handling system
* =======================================
*
* This provides a common standard way to write ZAPD warnings/errors, which should be used for all
* such. It will pretty-print them in a uniform way, with styles defined in the header.
*
* Warnings/errors should be constructed using the macros given in the header; there are now plenty
* of examples in the codebase of how to do this. Their purposes are noted above each category in
* the header. Each warning has a type, one of the ones in warningStringToInitMap, or
* WarningType::Always, which is used for warnings that cannot be disabled and do not display a
* type.
*
* Currently there are three levels of alert a warning can have:
* - Off (does not display anything)
* - Warn (print a warning but continue processing)
* - Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs)
*
* Flag use:
* - -Wfoo enables warnings of type foo
* - -Wno-foo disables warnings of type foo
* - -Werror=foo escalates foo to behave like an error
* - -Weverything enables all warnings
* - -Werror escalates all enabled warnings to errors
*
* Errors do not have types, and will always throw an exception; they cannot be disabled.
*
* Format
* ===
* Each printed warning/error contains the same three sections:
* - Preamble: automatically generated; the content varies depending on category. It will print the
* file and function that the warning is from, and information about the files being processed
* or extracted.
* - Header: begins with 'warning: ' or 'error:', should contain essential information about the
* warning/error, ends with the warning type if applicable. Printed with emphasis to make it
* stand out. Does not start with a capital letter or end with a '.'
* - Body (optional): indented, should contain further diagnostic information useful for identifying
* and fixing the warning/error. Can be a sentence with captialisation and '.' on the end.
*
* Please think of what the end user will find most useful when writing the header and body, and try
* to keep it brief without sacrificing important information! Also remember that if the user is
* only looking at stderr, they will normally have no other context.
*
* Warning vs error
* ===
* The principle that we have operated on so far is
* - issue a warning if ZAPD will still be able to produce a valid, compilable C file that will
* match
* - if this cannot happen, use an error.
* but at the end of the day, it is up to the programmer's discretion what it should be possible to
* disable.
*
* Documentation
* ===
* Remember that all warnings also need to be documented in the README.md. The help is generated
* automatically.
*/
#include "WarningHandler.h"
#include <cassert>
#include "Globals.h"
#include "Utils/StringHelper.h"
typedef struct
{
WarningType type;
WarningLevel defaultLevel;
std::string description;
} WarningInfoInit;
typedef struct
{
WarningLevel level;
std::string name;
std::string description;
} WarningInfo;
/**
* Master list of all default warning types and features
*
* To add a warning type, fill in a new row of this map. Think carefully about what its default
* level should be, and try and make the description both brief and informative: it is used in the
* help message, so again, think about what the end user needs to know.
*/
// clang-format off
static const std::unordered_map<std::string, WarningInfoInit> warningStringToInitMap = {
{"deprecated", {WarningType::Deprecated,
#ifdef DEPRECATION_ON
WarningLevel::Warn,
#else
WarningLevel::Off,
#endif
"Deprecated features"}},
{"unaccounted", {WarningType::Unaccounted, WarningLevel::Off, "Large blocks of unaccounted"}},
{"missing-offsets", {WarningType::MissingOffsets, WarningLevel::Warn, "Offset attribute missing in XML tag"}},
{"intersection", {WarningType::Intersection, WarningLevel::Warn, "Two assets intersect"}},
{"missing-attribute", {WarningType::MissingAttribute, WarningLevel::Warn, "Required attribute missing in XML tag"}},
{"invalid-attribute-value", {WarningType::InvalidAttributeValue, WarningLevel::Err, "Attribute declared in XML is wrong"}},
{"unknown-attribute", {WarningType::UnknownAttribute, WarningLevel::Warn, "Unknown attribute in XML entry tag"}},
{"invalid-xml", {WarningType::InvalidXML, WarningLevel::Err, "XML has syntax errors"}},
{"invalid-jpeg", {WarningType::InvalidJPEG, WarningLevel::Err, "JPEG file does not conform to the game's format requirements"}},
{"invalid-png", {WarningType::InvalidPNG, WarningLevel::Err, "Issues arising when processing PNG data"}},
{"invalid-extracted-data", {WarningType::InvalidExtractedData, WarningLevel::Err, "Extracted data does not have correct form"}},
{"missing-segment", {WarningType::MissingSegment, WarningLevel::Warn, "Segment not given in File tag in XML"}},
{"hardcoded-pointer", {WarningType::HardcodedPointer, WarningLevel::Warn, "ZAPD lacks the info to make a symbol, so must output a hardcoded pointer"}},
{"not-implemented", {WarningType::NotImplemented, WarningLevel::Warn, "ZAPD does not currently support this feature"}},
};
/**
* Map constructed at runtime to contain the warning features as set by the user using -W flags.
*/
static std::unordered_map<WarningType, WarningInfo> warningTypeToInfoMap;
void WarningHandler::ConstructTypeToInfoMap() {
for (auto& entry : warningStringToInitMap) {
warningTypeToInfoMap[entry.second.type] = {entry.second.defaultLevel, entry.first, entry.second.description};
}
warningTypeToInfoMap[WarningType::Always] = {WarningLevel::Warn, "always", "you shouldn't be reading this"};
assert(warningTypeToInfoMap.size() == static_cast<size_t>(WarningType::Max));
}
/**
* Initialises the main warning type map and reads flags passed to set each warning type's level.
*/
void WarningHandler::Init(int argc, char* argv[]) {
ConstructTypeToInfoMap();
bool werror = false;
for (int i = 1; i < argc; i++) {
// If it doesn't start with "-W" skip it.
if (argv[i][0] != '-' || argv[i][1] != 'W' || argv[i][2] == '\0') {
continue;
}
WarningLevel warningTypeOn = WarningLevel::Warn;
size_t startingIndex = 2;
// "-Wno-"
if (argv[i][2] == 'n' && argv[i][3] == 'o' && argv[i][4] == '-' && argv[i][5] != '\0') {
warningTypeOn = WarningLevel::Off;
startingIndex = 5;
}
// Read starting after the "-W" or "-Wno-"
std::string_view currentArgv = &argv[i][startingIndex];
if (currentArgv == "error") {
werror = warningTypeOn != WarningLevel::Off;
} else if (currentArgv == "everything") {
for (auto& it: warningTypeToInfoMap) {
if (it.second.level <= WarningLevel::Warn) {
it.second.level = warningTypeOn;
}
}
} else {
// "-Werror=" / "-Wno-error=" parser
if (currentArgv.rfind("error=", 0) == 0) {
// Read starting after the "error=" part
currentArgv = &argv[i][startingIndex + 6];
warningTypeOn = warningTypeOn != WarningLevel::Off ? WarningLevel::Err : WarningLevel::Warn;
}
auto it = warningStringToInitMap.find(std::string(currentArgv));
if (it != warningStringToInitMap.end()) {
warningTypeToInfoMap[it->second.type].level = warningTypeOn;
}
else {
HANDLE_WARNING(WarningType::Always, StringHelper::Sprintf("unknown warning flag '%s'", argv[i]), "");
}
}
}
if (werror) {
for (auto& it: warningTypeToInfoMap) {
if (it.second.level >= WarningLevel::Warn) {
it.second.level = WarningLevel::Err;
}
}
}
}
bool WarningHandler::IsWarningEnabled(WarningType warnType) {
assert(static_cast<size_t>(warnType) >= 0 && warnType < WarningType::Max);
return warningTypeToInfoMap.at(warnType).level != WarningLevel::Off;
}
bool WarningHandler::WasElevatedToError(WarningType warnType) {
assert(static_cast<size_t>(warnType) >= 0 && warnType < WarningType::Max);
if (!IsWarningEnabled(warnType)) {
return false;
}
return warningTypeToInfoMap.at(warnType).level >= WarningLevel::Err;
}
/**
* Print file/line/function info for debugging
*/
void WarningHandler::FunctionPreamble(const char* filename, int32_t line, const char* function) {
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) {
fprintf(stderr, "%s:%i: in function %s:\n", filename, line, function);
}
}
/**
* Print the information about the file(s) being processed (XML for extraction, png etc. for building)
*/
void WarningHandler::ProcessedFilePreamble() {
if (Globals::Instance->inputPath != "") {
fprintf(stderr, "When processing file %s: ", Globals::Instance->inputPath.c_str());
}
}
/**
* Print information about the binary file being extracted
*/
void WarningHandler::ExtractedFilePreamble(const ZFile *parent, const ZResource* res, const uint32_t offset) {
fprintf(stderr, "in input binary file %s, ", parent->GetName().c_str());
if (res != nullptr) {
fprintf(stderr, "resource '%s' at ", res->GetName().c_str());
}
fprintf(stderr, "offset 0x%06X: \n\t", offset);
}
/**
* Construct the rest of the message, after warning:/error. The message is filled in one character at a time, with indents added after newlines
*/
std::string WarningHandler::ConstructMessage(std::string message, const std::string& header, const std::string& body) {
message.reserve(message.size() + header.size() + body.size() + 10 * (sizeof(HANG_INDT) - 1));
message += StringHelper::Sprintf(HILITE("%s"), header.c_str());
message += "\n";
if (body == "") {
return message;
}
message += HANG_INDT;
for (const char* ptr = body.c_str(); *ptr != '\0'; ptr++) {
message += *ptr;
if (*ptr == '\n') {
message += HANG_INDT;
}
}
message += "\n";
return message;
}
/* Error module functions */
void WarningHandler::PrintErrorAndThrow(const std::string& header, const std::string& body) {
std::string errorMsg = ERR_FMT("error: ");
throw std::runtime_error(ConstructMessage(errorMsg, header, body));
}
/* Error types, to be used via the macros */
void WarningHandler::ErrorType(WarningType warnType, const std::string& header, const std::string& body) {
std::string headerMsg = header;
for (const auto& iter: warningStringToInitMap) {
if (iter.second.type == warnType) {
headerMsg += StringHelper::Sprintf(" [%s]", iter.first.c_str());
}
}
PrintErrorAndThrow(headerMsg, body);
}
void WarningHandler::Error_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
FunctionPreamble(filename, line, function);
ErrorType(warnType, header, body);
}
void WarningHandler::Error_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
ErrorType(warnType, header, body);
}
void WarningHandler::Error_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) {
assert(parent != nullptr);
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
ExtractedFilePreamble(parent, res, offset);
ErrorType(warnType, header, body);
}
/* Warning module functions */
void WarningHandler::PrintWarningBody(const std::string& header, const std::string& body) {
std::string errorMsg = WARN_FMT("warning: ");
fprintf(stderr, "%s", ConstructMessage(errorMsg, header, body).c_str());
}
void WarningHandler::WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header, const std::string& body) {
std::string headerMsg = header;
for (const auto& iter: warningStringToInitMap) {
if (iter.second.type == warnType) {
headerMsg += StringHelper::Sprintf(" [-W%s]", iter.first.c_str());
}
}
if (WasElevatedToError(warnType)) {
PrintErrorAndThrow(headerMsg, body);
} else {
PrintWarningBody(headerMsg, body);
}
}
/* Warning types, to be used via the macros */
void WarningHandler::Warning_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
if (!IsWarningEnabled(warnType)) {
return;
}
FunctionPreamble(filename, line, function);
WarningTypeAndChooseEscalate(warnType, header, body);
}
void WarningHandler::Warning_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) {
if (!IsWarningEnabled(warnType)) {
return;
}
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
WarningTypeAndChooseEscalate(warnType, header, body);
}
void WarningHandler::Warning_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) {
assert(parent != nullptr);
if (!IsWarningEnabled(warnType)) {
return;
}
FunctionPreamble(filename, line, function);
ProcessedFilePreamble();
ExtractedFilePreamble(parent, res, offset);
WarningTypeAndChooseEscalate(warnType, header, body);
}
/* Help-related functions */
#include <set>
/**
* Print each warning name, default status, and description using the init map
*/
void WarningHandler::PrintHelp() {
std::set<std::string> sortedKeys;
WarningInfoInit warningInfo;
uint32_t columnWidth = 25;
std::string dt;
// Sort keys through the magic of `set`, to print in alphabetical order
for (auto& it : warningStringToInitMap) {
sortedKeys.insert(it.first);
}
printf("\nWarning types ( * means enabled by default)\n");
for (auto& key : sortedKeys) {
warningInfo = warningStringToInitMap.at(key);
if (warningInfo.defaultLevel <= WarningLevel::Warn) {
dt = "-W";
dt += key;
if (warningInfo.defaultLevel == WarningLevel::Warn) {
dt += " *";
}
printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str());
if (dt.length() + 2 > columnWidth) {
printf("\n" HELP_DT_INDT "%-*s", columnWidth, "");
}
printf("%s\n", warningInfo.description.c_str());
}
}
printf("\nDefault errors\n");
for (auto& key : sortedKeys) {
if (warningInfo.defaultLevel > WarningLevel::Warn) {
dt = "-W";
dt += key;
printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str());
if (dt.length() + 2 > columnWidth) {
printf("\n" HELP_DT_INDT "%*s", columnWidth, "");
}
printf("%s\n", warningInfo.description.c_str());
}
}
printf("\n");
printf("Other\n" HELP_DT_INDT "-Weverything will enable all existing warnings.\n" HELP_DT_INDT "-Werror will promote all warnings to errors.\n");
printf("\n");
printf("Warnings can be disabled using -Wno-... instead of -W...; -Weverything will override any -Wno-... flags passed before it.\n");
}
/**
* Print which warnings are currently enabled
*/
void WarningHandler::PrintWarningsDebugInfo()
{
std::string dt;
printf("Warnings status:\n");
for (auto& it: warningTypeToInfoMap) {
dt = it.second.name;
dt += ": ";
printf(HELP_DT_INDT "%-25s", dt.c_str());
switch (it.second.level)
{
case WarningLevel::Off:
printf(VT_FGCOL(LIGHTGRAY) "Off" VT_RST);
break;
case WarningLevel::Warn:
printf(VT_FGCOL(YELLOW) "Warn" VT_RST);
break;
case WarningLevel::Err:
printf(VT_FGCOL(RED) "Err" VT_RST);
break;
}
printf("\n");
}
printf("\n");
}

View File

@ -0,0 +1,145 @@
#pragma once
#include <array>
#include <string>
#include <string_view>
#include <unordered_map>
#include "Utils/vt.h"
#include "ZFile.h"
#ifdef _MSC_VER
#define __PRETTY_FUNCTION__ __FUNCSIG__
#elif not defined(__GNUC__)
#define __PRETTY_FUNCTION__ __func__
#endif
// =======================================
/* Formatting macros */
// TODO: move this somewhere else so it can be used by other help
#define HELP_DT_INDT " "
/* Macros for formatting warnings/errors */
#define VT_HILITE VT_BOLD_FGCOL(WHITE)
#define VT_WARN VT_BOLD_FGCOL(PURPLE)
#define VT_ERR VT_BOLD_FGCOL(RED)
#define HILITE(string) (VT_HILITE string VT_RST)
#define WARN_FMT(string) (VT_WARN string VT_RST)
#define ERR_FMT(string) (VT_ERR string VT_RST)
// Maybe make WARN_LF instead
// Currently 8 spaces
#define WARN_INDT " "
// Currently 16 spaces
#define HANG_INDT " "
// =======================================
/* Warning and error macros */
// TODO: better names
// General-purpose, plain style (only prints function,file,line in the preamble)
#define HANDLE_ERROR(warningType, header, body) \
WarningHandler::Error_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, body)
#define HANDLE_WARNING(warningType, header, body) \
WarningHandler::Warning_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
body)
// For processing XMLs or textures/blobs (preamble contains function,file,line; processed file)
#define HANDLE_ERROR_PROCESS(warningType, header, body) \
WarningHandler::Error_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
body)
#define HANDLE_WARNING_PROCESS(warningType, header, body) \
WarningHandler::Warning_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \
body)
// For ZResource-related stuff (preamble contains function,file,line; processed file; extracted file
// and offset)
#define HANDLE_ERROR_RESOURCE(warningType, parent, resource, offset, header, body) \
WarningHandler::Error_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \
resource, offset, header, body)
#define HANDLE_WARNING_RESOURCE(warningType, parent, resource, offset, header, body) \
WarningHandler::Warning_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \
resource, offset, header, body)
// =======================================
enum class WarningType
{
Always, // Warnings of this type are always printed, cannot be disabled.
Deprecated,
Unaccounted,
MissingOffsets,
Intersection,
MissingAttribute,
InvalidAttributeValue,
UnknownAttribute,
InvalidXML,
InvalidJPEG,
InvalidPNG,
InvalidExtractedData,
MissingSegment,
HardcodedPointer,
NotImplemented,
Max,
};
enum class WarningLevel
{
Off,
Warn,
Err,
};
class WarningHandler
{
public:
static void ConstructTypeToInfoMap();
static void Init(int argc, char* argv[]);
static bool IsWarningEnabled(WarningType warnType);
static bool WasElevatedToError(WarningType warnType);
static void FunctionPreamble(const char* filename, int32_t line, const char* function);
static void ProcessedFilePreamble();
static void ExtractedFilePreamble(const ZFile* parent, const ZResource* res,
const uint32_t offset);
static std::string ConstructMessage(std::string message, const std::string& header,
const std::string& body);
[[noreturn]] static void PrintErrorAndThrow(const std::string& header, const std::string& body);
static void PrintWarningBody(const std::string& header, const std::string& body);
[[noreturn]] static void ErrorType(WarningType warnType, const std::string& header,
const std::string& body);
[[noreturn]] static void Error_Plain(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
[[noreturn]] static void Error_Process(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
[[noreturn]] static void Error_Resource(const char* filename, int32_t line,
const char* function, WarningType warnType,
const ZFile* parent, const ZResource* res,
const uint32_t offset, const std::string& header,
const std::string& body);
static void WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header,
const std::string& body);
static void Warning_Plain(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
static void Warning_Process(const char* filename, int32_t line, const char* function,
WarningType warnType, const std::string& header,
const std::string& body);
static void Warning_Resource(const char* filename, int32_t line, const char* function,
WarningType warnType, const ZFile* parent, const ZResource* res,
const uint32_t offset, const std::string& header,
const std::string& body);
static void PrintHelp();
static void PrintWarningsDebugInfo();
};

356
ZAPDTR/ZAPD/ZAPD.vcxproj Normal file
View File

@ -0,0 +1,356 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props" Condition="Exists('..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props')" />
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>15.0</VCProjectVersion>
<ProjectGuid>{B53F9E5B-0A58-4BAE-9AFE-856C8CBB8D36}</ProjectGuid>
<RootNamespace>ZAPD</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>ZAPD</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LibraryPath>$(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\..\OTRExporter\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(ProjectDir)..\..\libultraship\libultraship\;$(LibraryPath)</LibraryPath>
<IncludePath>$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
<LibraryPath>$(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\..\OTRExporter\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(ProjectDir)..\..\libultraship\libultraship\;$(LibraryPath)</LibraryPath>
<PreBuildEventUseInBuild>false</PreBuildEventUseInBuild>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>$(SolutionDir)ZAPD\lib\tinyxml2;$(SolutionDir)ZAPD\lib\libgfxd;$(SolutionDir)ZAPD\lib\elfio;$(SolutionDir)ZAPD\lib\stb;$(ProjectDir);$(IncludePath)</IncludePath>
<LibraryPath>$(SolutionDir)ZAPD\lib\libgfxd;$(SolutionDir)x64\Debug;$(SolutionDir)packages\libpng.1.6.28.1\build\native\lib\x64\v140\dynamic\Debug;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<LanguageStandard_C>stdc11</LanguageStandard_C>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<Profile>true</Profile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<LanguageStandard_C>stdc11</LanguageStandard_C>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<Profile>true</Profile>
<AdditionalDependencies>ZAPDUtils.lib;/WHOLEARCHIVE:OTRExporter.lib;libultraship.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
</Link>
<PreBuildEvent>
<Command>
</Command>
</PreBuildEvent>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<LanguageStandard_C>stdc11</LanguageStandard_C>
</ClCompile>
<Link>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>ZAPDUtils.lib;/WHOLEARCHIVE:OTRExporter.lib;libultraship.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
</Link>
<PreBuildEvent>
<Command>
</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\lib\libgfxd\gfxd.c" />
<ClCompile Include="..\lib\libgfxd\uc.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3d.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3db.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dex.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dex2.c" />
<ClCompile Include="..\lib\libgfxd\uc_f3dexb.c" />
<ClCompile Include="Declaration.cpp" />
<ClCompile Include="GameConfig.cpp" />
<ClCompile Include="Globals.cpp" />
<ClCompile Include="ImageBackend.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="OtherStructs\SkinLimbStructs.cpp" />
<ClCompile Include="OutputFormatter.cpp" />
<ClCompile Include="Overlays\ZOverlay.cpp" />
<ClCompile Include="WarningHandler.cpp" />
<ClCompile Include="ZArray.cpp" />
<ClCompile Include="ZBackground.cpp" />
<ClCompile Include="ZCutsceneMM.cpp" />
<ClCompile Include="ZLimb.cpp" />
<ClCompile Include="ZMtx.cpp" />
<ClCompile Include="ZPath.cpp" />
<ClCompile Include="ZPlayerAnimationData.cpp" />
<ClCompile Include="ZRoom\Commands\SetActorCutsceneList.cpp" />
<ClCompile Include="ZRoom\Commands\SetAnimatedMaterialList.cpp" />
<ClCompile Include="ZRoom\Commands\SetCsCamera.cpp" />
<ClCompile Include="ZRoom\Commands\SetMinimapChests.cpp" />
<ClCompile Include="ZRoom\Commands\SetMinimapList.cpp" />
<ClCompile Include="ZRoom\Commands\SetWorldMapVisited.cpp" />
<ClCompile Include="ZRoom\Commands\Unused1D.cpp" />
<ClCompile Include="ZScalar.cpp" />
<ClCompile Include="ZAnimation.cpp" />
<ClCompile Include="ZBlob.cpp" />
<ClCompile Include="ZCollision.cpp" />
<ClCompile Include="ZCutscene.cpp" />
<ClCompile Include="ZDisplayList.cpp" />
<ClCompile Include="ZFile.cpp" />
<ClCompile Include="ZSkeleton.cpp" />
<ClCompile Include="ZResource.cpp" />
<ClCompile Include="ZRoom\Commands\EndMarker.cpp" />
<ClCompile Include="ZRoom\Commands\SetActorList.cpp" />
<ClCompile Include="ZRoom\Commands\SetAlternateHeaders.cpp" />
<ClCompile Include="ZRoom\Commands\SetCameraSettings.cpp" />
<ClCompile Include="ZRoom\Commands\SetCollisionHeader.cpp" />
<ClCompile Include="ZRoom\Commands\SetCutscenes.cpp" />
<ClCompile Include="ZRoom\Commands\SetEchoSettings.cpp" />
<ClCompile Include="ZRoom\Commands\SetEntranceList.cpp" />
<ClCompile Include="ZRoom\Commands\SetExitList.cpp" />
<ClCompile Include="ZRoom\Commands\SetLightingSettings.cpp" />
<ClCompile Include="ZRoom\Commands\SetLightList.cpp" />
<ClCompile Include="ZRoom\Commands\SetMesh.cpp" />
<ClCompile Include="ZRoom\Commands\SetObjectList.cpp" />
<ClCompile Include="ZRoom\Commands\SetPathways.cpp" />
<ClCompile Include="ZRoom\Commands\SetRoomBehavior.cpp" />
<ClCompile Include="ZRoom\Commands\SetRoomList.cpp" />
<ClCompile Include="ZRoom\Commands\SetSkyboxModifier.cpp" />
<ClCompile Include="ZRoom\Commands\SetSkyboxSettings.cpp" />
<ClCompile Include="ZRoom\Commands\SetSoundSettings.cpp" />
<ClCompile Include="ZRoom\Commands\SetSpecialObjects.cpp" />
<ClCompile Include="ZRoom\Commands\SetStartPositionList.cpp" />
<ClCompile Include="ZRoom\Commands\SetTimeSettings.cpp" />
<ClCompile Include="ZRoom\Commands\SetTransitionActorList.cpp" />
<ClCompile Include="ZRoom\Commands\SetWind.cpp" />
<ClCompile Include="ZRoom\Commands\Unused09.cpp" />
<ClCompile Include="ZRoom\Commands\ZRoomCommandUnk.cpp" />
<ClCompile Include="ZRoom\ZRoom.cpp" />
<ClCompile Include="ZRoom\ZRoomCommand.cpp" />
<ClCompile Include="ZString.cpp" />
<ClCompile Include="ZSymbol.cpp" />
<ClCompile Include="ZText.cpp" />
<ClCompile Include="ZTexture.cpp" />
<ClCompile Include="ZTextureAnimation.cpp" />
<ClCompile Include="ZVector.cpp" />
<ClCompile Include="ZVtx.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\lib\elfio\elfio\elfio.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_dump.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_dynamic.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_header.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_note.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_relocation.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_section.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_segment.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_strings.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_symbols.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elfio_utils.hpp" />
<ClInclude Include="..\lib\elfio\elfio\elf_types.hpp" />
<ClInclude Include="..\lib\libgfxd\gbi.h" />
<ClInclude Include="..\lib\libgfxd\gfxd.h" />
<ClInclude Include="..\lib\libgfxd\priv.h" />
<ClInclude Include="..\lib\stb\stb_image.h" />
<ClInclude Include="..\lib\stb\stb_image_write.h" />
<ClInclude Include="..\lib\stb\tinyxml2.h" />
<ClInclude Include="CRC32.h" />
<ClInclude Include="Declaration.h" />
<ClInclude Include="GameConfig.h" />
<ClInclude Include="Globals.h" />
<ClInclude Include="ImageBackend.h" />
<ClInclude Include="OtherStructs\SkinLimbStructs.h" />
<ClInclude Include="OutputFormatter.h" />
<ClInclude Include="Overlays\ZOverlay.h" />
<ClInclude Include="WarningHandler.h" />
<ClInclude Include="ZAnimation.h" />
<ClInclude Include="ZArray.h" />
<ClInclude Include="ZBackground.h" />
<ClInclude Include="ZBlob.h" />
<ClInclude Include="ZCollision.h" />
<ClInclude Include="ZCutscene.h" />
<ClInclude Include="ZCutsceneMM.h" />
<ClInclude Include="ZDisplayList.h" />
<ClInclude Include="ZFile.h" />
<ClInclude Include="ZLimb.h" />
<ClInclude Include="ZMtx.h" />
<ClInclude Include="ZPath.h" />
<ClInclude Include="ZPlayerAnimationData.h" />
<ClInclude Include="ZRoom\Commands\SetActorCutsceneList.h" />
<ClInclude Include="ZRoom\Commands\SetAnimatedMaterialList.h" />
<ClInclude Include="ZRoom\Commands\SetCsCamera.h" />
<ClInclude Include="ZRoom\Commands\SetMinimapChests.h" />
<ClInclude Include="ZRoom\Commands\SetMinimapList.h" />
<ClInclude Include="ZRoom\Commands\SetWorldMapVisited.h" />
<ClInclude Include="ZRoom\Commands\Unused1D.h" />
<ClInclude Include="ZScalar.h" />
<ClInclude Include="ZSkeleton.h" />
<ClInclude Include="ZResource.h" />
<ClInclude Include="ZRoom\Commands\EndMarker.h" />
<ClInclude Include="ZRoom\Commands\SetActorList.h" />
<ClInclude Include="ZRoom\Commands\SetAlternateHeaders.h" />
<ClInclude Include="ZRoom\Commands\SetCameraSettings.h" />
<ClInclude Include="ZRoom\Commands\SetCollisionHeader.h" />
<ClInclude Include="ZRoom\Commands\SetCutscenes.h" />
<ClInclude Include="ZRoom\Commands\SetEchoSettings.h" />
<ClInclude Include="ZRoom\Commands\SetEntranceList.h" />
<ClInclude Include="ZRoom\Commands\SetExitList.h" />
<ClInclude Include="ZRoom\Commands\SetLightingSettings.h" />
<ClInclude Include="ZRoom\Commands\SetLightList.h" />
<ClInclude Include="ZRoom\Commands\SetMesh.h" />
<ClInclude Include="ZRoom\Commands\SetObjectList.h" />
<ClInclude Include="ZRoom\Commands\SetPathways.h" />
<ClInclude Include="ZRoom\Commands\SetRoomBehavior.h" />
<ClInclude Include="ZRoom\Commands\SetRoomList.h" />
<ClInclude Include="ZRoom\Commands\SetSkyboxModifier.h" />
<ClInclude Include="ZRoom\Commands\SetSkyboxSettings.h" />
<ClInclude Include="ZRoom\Commands\SetSoundSettings.h" />
<ClInclude Include="ZRoom\Commands\SetSpecialObjects.h" />
<ClInclude Include="ZRoom\Commands\SetStartPositionList.h" />
<ClInclude Include="ZRoom\Commands\SetTimeSettings.h" />
<ClInclude Include="ZRoom\Commands\SetTransitionActorList.h" />
<ClInclude Include="ZRoom\Commands\SetWind.h" />
<ClInclude Include="ZRoom\Commands\Unused09.h" />
<ClInclude Include="ZRoom\Commands\ZRoomCommandUnk.h" />
<ClInclude Include="ZRoom\ZRoom.h" />
<ClInclude Include="ZRoom\ZRoomCommand.h" />
<ClInclude Include="ZString.h" />
<ClInclude Include="ZSymbol.h" />
<ClInclude Include="ZText.h" />
<ClInclude Include="ZTexture.h" />
<ClInclude Include="ZTextureAnimation.h" />
<ClInclude Include="ZVector.h" />
<ClInclude Include="ZVtx.h" />
</ItemGroup>
<ItemGroup>
<Text Include="..\SymbolMap_OoTMqDbg.txt">
<DeploymentContent>true</DeploymentContent>
</Text>
<Text Include="any\any\zlib.static.txt" />
<Text Include="NuGet\libpng.static.txt" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="..\..\OTRExporter\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\..\OTRExporter\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
<Import Project="..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets" Condition="Exists('..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets')" />
<Import Project="..\..\OTRExporter\packages\zlib.static.1.2.5\build\native\zlib.static.targets" Condition="Exists('..\..\OTRExporter\packages\zlib.static.1.2.5\build\native\zlib.static.targets')" />
<Import Project="..\..\OTRExporter\packages\libpng.static.1.6.37\build\native\libpng.static.targets" Condition="Exists('..\..\OTRExporter\packages\libpng.static.1.6.37\build\native\libpng.static.targets')" />
</ImportGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\OTRExporter\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('..\..\OTRExporter\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\OTRExporter\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets'))" />
<Error Condition="!Exists('..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props'))" />
<Error Condition="!Exists('..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\OTRExporter\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets'))" />
<Error Condition="!Exists('..\..\OTRExporter\packages\zlib.static.1.2.5\build\native\zlib.static.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\OTRExporter\packages\zlib.static.1.2.5\build\native\zlib.static.targets'))" />
<Error Condition="!Exists('..\..\OTRExporter\packages\libpng.static.1.6.37\build\native\libpng.static.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\OTRExporter\packages\libpng.static.1.6.37\build\native\libpng.static.targets'))" />
</Target>
</Project>

View File

@ -0,0 +1,557 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Source Files\Libraries">
<UniqueIdentifier>{02148456-5068-4613-8478-f10addc58e70}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Libraries">
<UniqueIdentifier>{bcab3136-95ba-4839-833c-43d78ad6e335}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Libraries\elfio">
<UniqueIdentifier>{dc06ed84-f6fe-4277-80f3-d62bd5cdbb98}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Z64">
<UniqueIdentifier>{6049c045-bc38-4221-b29e-ca6d4d8af4aa}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Z64\ZRoom">
<UniqueIdentifier>{490e3a08-047b-48d3-ab53-3a860a3b92aa}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Z64\ZRoom\Commands">
<UniqueIdentifier>{26c06845-8e8e-4b79-ad18-07c4f9c0f801}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Z64">
<UniqueIdentifier>{d45c420d-2378-47ac-92c5-80db9475c195}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Z64\ZRoom">
<UniqueIdentifier>{03cc56a2-e0e8-4167-80a0-98fb900a959a}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Z64\ZRoom\Commands">
<UniqueIdentifier>{73db0879-6df8-4f6a-8cc2-a1f836e9e796}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Libraries\fbx">
<UniqueIdentifier>{be9a5be0-ec6a-4200-8e39-bb58c7da7aa8}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\Libraries\libgfxd">
<UniqueIdentifier>{7ee79d97-c6a8-4e82-93ef-37981f4d7838}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\Libraries\libgfxd">
<UniqueIdentifier>{85600275-99fe-491d-8189-bcc3dc1a8903}</UniqueIdentifier>
</Filter>
<Filter Include="any">
<UniqueIdentifier>{ba9990b0-1082-48bb-874c-6108534b5455}</UniqueIdentifier>
</Filter>
<Filter Include="any\any">
<UniqueIdentifier>{ce9d91b0-ba20-4296-bc2d-8630965bb392}</UniqueIdentifier>
</Filter>
<Filter Include="NuGet">
<UniqueIdentifier>{730beb67-6d59-4849-9d9b-702c4a565fc0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZRoom\ZRoom.cpp">
<Filter>Source Files\Z64\ZRoom</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetEchoSettings.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\ZRoomCommand.cpp">
<Filter>Source Files\Z64\ZRoom</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetSoundSettings.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetWind.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetTimeSettings.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetSpecialObjects.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetRoomBehavior.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetSkyboxSettings.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetCameraSettings.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetSkyboxModifier.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetActorList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetEntranceList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetStartPositionList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="Globals.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetAlternateHeaders.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetExitList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\EndMarker.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetCollisionHeader.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetRoomList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetObjectList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetMesh.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\Unused09.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetLightingSettings.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetTransitionActorList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetPathways.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetCutscenes.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZAnimation.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZBlob.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZCutscene.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZDisplayList.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZFile.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZResource.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZTexture.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="Overlays\ZOverlay.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZSkeleton.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetLightList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\ZRoomCommandUnk.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZCollision.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZScalar.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZVector.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZArray.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZVtx.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZLimb.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="OutputFormatter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZSymbol.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="..\lib\libgfxd\gfxd.c">
<Filter>Source Files\Libraries\libgfxd</Filter>
</ClCompile>
<ClCompile Include="..\lib\libgfxd\uc.c">
<Filter>Source Files\Libraries\libgfxd</Filter>
</ClCompile>
<ClCompile Include="..\lib\libgfxd\uc_f3d.c">
<Filter>Source Files\Libraries\libgfxd</Filter>
</ClCompile>
<ClCompile Include="..\lib\libgfxd\uc_f3db.c">
<Filter>Source Files\Libraries\libgfxd</Filter>
</ClCompile>
<ClCompile Include="..\lib\libgfxd\uc_f3dex.c">
<Filter>Source Files\Libraries\libgfxd</Filter>
</ClCompile>
<ClCompile Include="..\lib\libgfxd\uc_f3dex2.c">
<Filter>Source Files\Libraries\libgfxd</Filter>
</ClCompile>
<ClCompile Include="..\lib\libgfxd\uc_f3dexb.c">
<Filter>Source Files\Libraries\libgfxd</Filter>
</ClCompile>
<ClCompile Include="ZMtx.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetWorldMapVisited.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\Unused1D.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetActorCutsceneList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetCsCamera.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetMinimapChests.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetMinimapList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZCutsceneMM.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZBackground.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZRoom\Commands\SetAnimatedMaterialList.cpp">
<Filter>Source Files\Z64\ZRoom\Commands</Filter>
</ClCompile>
<ClCompile Include="ZPath.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="Declaration.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ImageBackend.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZString.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="GameConfig.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZTextureAnimation.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="OtherStructs\SkinLimbStructs.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="ZPlayerAnimationData.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
<ClCompile Include="WarningHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ZText.cpp">
<Filter>Source Files\Z64</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ZRoom\ZRoom.h">
<Filter>Header Files\Z64\ZRoom</Filter>
</ClInclude>
<ClInclude Include="ZRoom\ZRoomCommand.h">
<Filter>Header Files\Z64\ZRoom</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetEchoSettings.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetSoundSettings.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetWind.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetTimeSettings.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetSpecialObjects.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetRoomBehavior.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetSkyboxSettings.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetCameraSettings.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetSkyboxModifier.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetActorList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetEntranceList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetStartPositionList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elf_types.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_dump.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_dynamic.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_header.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_note.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_relocation.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_section.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_segment.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_strings.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_symbols.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="..\lib\elfio\elfio\elfio_utils.hpp">
<Filter>Header Files\Libraries\elfio</Filter>
</ClInclude>
<ClInclude Include="Globals.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetAlternateHeaders.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetExitList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\EndMarker.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetCollisionHeader.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetRoomList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetObjectList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetMesh.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\Unused09.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetLightingSettings.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetTransitionActorList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetPathways.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetCutscenes.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="..\lib\stb\stb_image.h">
<Filter>Header Files\Libraries</Filter>
</ClInclude>
<ClInclude Include="..\lib\stb\stb_image_write.h">
<Filter>Header Files\Libraries</Filter>
</ClInclude>
<ClInclude Include="Overlays\ZOverlay.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZTexture.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZAnimation.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZBlob.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZCutscene.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZDisplayList.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZFile.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZResource.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZSkeleton.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetLightList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\ZRoomCommandUnk.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZCollision.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZScalar.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZVector.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="..\lib\stb\tinyxml2.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZArray.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZVtx.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="CRC32.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZLimb.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="OutputFormatter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZSymbol.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="..\lib\libgfxd\gbi.h">
<Filter>Header Files\Libraries\libgfxd</Filter>
</ClInclude>
<ClInclude Include="..\lib\libgfxd\gfxd.h">
<Filter>Header Files\Libraries\libgfxd</Filter>
</ClInclude>
<ClInclude Include="..\lib\libgfxd\priv.h">
<Filter>Header Files\Libraries\libgfxd</Filter>
</ClInclude>
<ClInclude Include="ZMtx.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetWorldMapVisited.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetActorCutsceneList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\Unused1D.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetCsCamera.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetMinimapChests.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetMinimapList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ZCutsceneMM.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZBackground.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZRoom\Commands\SetAnimatedMaterialList.h">
<Filter>Header Files\Z64\ZRoom\Commands</Filter>
</ClInclude>
<ClInclude Include="ImageBackend.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZPath.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="Declaration.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZString.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="GameConfig.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZTextureAnimation.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="OtherStructs\SkinLimbStructs.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="ZPlayerAnimationData.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
<ClInclude Include="WarningHandler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ZText.h">
<Filter>Header Files\Z64</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Text Include="..\SymbolMap_OoTMqDbg.txt">
<Filter>Resource Files</Filter>
</Text>
<Text Include="any\any\zlib.static.txt">
<Filter>any\any</Filter>
</Text>
<Text Include="NuGet\libpng.static.txt">
<Filter>NuGet</Filter>
</Text>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

569
ZAPDTR/ZAPD/ZAnimation.cpp Normal file
View File

@ -0,0 +1,569 @@
#include "ZAnimation.h"
#include <utility>
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/File.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Animation, ZNormalAnimation);
REGISTER_ZFILENODE(PlayerAnimation, ZLinkAnimation);
REGISTER_ZFILENODE(CurveAnimation, ZCurveAnimation);
REGISTER_ZFILENODE(LegacyAnimation, ZLegacyAnimation);
ZAnimation::ZAnimation(ZFile* nParent) : ZResource(nParent)
{
frameCount = 0;
genOTRDef = true;
}
void ZAnimation::ParseRawData()
{
ZResource::ParseRawData();
frameCount = BitConverter::ToInt16BE(parent->GetRawData(), rawDataIndex + 0);
}
/*
std::string ZAnimation::GetSourceOutputHeader(const std::string& prefix)
{
if (Globals::Instance->otrMode)
{
std::string str = "";
str += StringHelper::Sprintf("#define %s \"__OTR__%s/%s\"", name.c_str(), parent->GetOutName().c_str(), name.c_str());
return str;
}
else
return ZResource::GetSourceOutputHeader(prefix);
}
*/
ZResourceType ZAnimation::GetResourceType() const
{
return ZResourceType::Animation;
}
/* ZNormalAnimation */
ZNormalAnimation::ZNormalAnimation(ZFile* nParent) : ZAnimation(nParent)
{
}
size_t ZNormalAnimation::GetRawDataSize() const
{
return 16;
}
std::string ZNormalAnimation::GetSourceTypeName() const
{
return "AnimationHeader";
}
void ZNormalAnimation::ParseRawData()
{
ZAnimation::ParseRawData();
const uint8_t* data = parent->GetRawData().data();
rotationValuesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 4);
rotationIndicesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 8);
limit = BitConverter::ToInt16BE(data, rawDataIndex + 12);
rotationValuesOffset = Seg2Filespace(rotationValuesSeg, parent->baseAddress);
rotationIndicesOffset = Seg2Filespace(rotationIndicesSeg, parent->baseAddress);
uint32_t currentPtr = rotationValuesOffset;
// Read the Rotation Values
for (uint32_t i = 0; i < ((rotationIndicesOffset - rotationValuesOffset) / 2); i++)
{
rotationValues.push_back(BitConverter::ToInt16BE(data, currentPtr));
currentPtr += 2;
}
currentPtr = rotationIndicesOffset;
// Read the Rotation Indices
for (uint32_t i = 0; i < ((rawDataIndex - rotationIndicesOffset) / 6); i++)
{
rotationIndices.push_back(RotationIndex(BitConverter::ToInt16BE(data, currentPtr),
BitConverter::ToInt16BE(data, currentPtr + 2),
BitConverter::ToInt16BE(data, currentPtr + 4)));
currentPtr += 6;
}
}
void ZNormalAnimation::DeclareReferences(const std::string& prefix)
{
std::string defaultPrefix = prefix.c_str();
if (name != "")
defaultPrefix = name;
// replace g prefix with s for local variables
if (defaultPrefix.at(0) == 'g')
defaultPrefix.replace(0, 1, "s");
std::string indicesStr = "";
std::string valuesStr = " ";
const uint8_t lineLength = 14;
const uint8_t offset = 0;
for (size_t i = 0; i < rotationValues.size(); i++)
{
valuesStr += StringHelper::Sprintf("0x%04X, ", rotationValues[i]);
if ((i - offset + 1) % lineLength == 0)
valuesStr += "\n ";
}
parent->AddDeclarationArray(rotationValuesOffset, DeclarationAlignment::Align4,
rotationValues.size() * 2, "s16",
StringHelper::Sprintf("%sFrameData", defaultPrefix.c_str()),
rotationValues.size(), valuesStr);
for (size_t i = 0; i < rotationIndices.size(); i++)
{
indicesStr += StringHelper::Sprintf(" { 0x%04X, 0x%04X, 0x%04X },", rotationIndices[i].x,
rotationIndices[i].y, rotationIndices[i].z);
if (i != (rotationIndices.size() - 1))
indicesStr += "\n";
}
parent->AddDeclarationArray(rotationIndicesOffset, DeclarationAlignment::Align4,
rotationIndices.size() * 6, "JointIndex",
StringHelper::Sprintf("%sJointIndices", defaultPrefix.c_str()),
rotationIndices.size(), indicesStr);
}
std::string ZNormalAnimation::GetBodySourceCode() const
{
std::string frameDataName;
Globals::Instance->GetSegmentedPtrName(rotationValuesSeg, parent, "s16", frameDataName);
std::string jointIndicesName;
Globals::Instance->GetSegmentedPtrName(rotationIndicesSeg, parent, "JointIndex",
jointIndicesName);
std::string headerStr =
StringHelper::Sprintf("\n\t{ %i }, %s,\n", frameCount, frameDataName.c_str());
headerStr += StringHelper::Sprintf("\t%s, %i\n", jointIndicesName.c_str(), limit);
return headerStr;
}
/* ZLinkAnimation */
ZLinkAnimation::ZLinkAnimation(ZFile* nParent) : ZAnimation(nParent)
{
segmentAddress = 0;
}
size_t ZLinkAnimation::GetRawDataSize() const
{
return 8;
}
std::string ZLinkAnimation::GetSourceTypeName() const
{
return "LinkAnimationHeader";
}
void ZLinkAnimation::ParseRawData()
{
ZAnimation::ParseRawData();
const auto& rawData = parent->GetRawData();
segmentAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 4);
}
std::string ZLinkAnimation::GetBodySourceCode() const
{
std::string segSymbol;
Globals::Instance->GetSegmentedPtrName(segmentAddress, parent, "", segSymbol);
return StringHelper::Sprintf("\n\t{ %i }, %s\n", frameCount, segSymbol.c_str());
}
/* ZCurveAnimation */
TransformData::TransformData(ZFile* parent, const std::vector<uint8_t>& rawData,
uint32_t fileOffset)
: parent(parent)
{
unk_00 = BitConverter::ToUInt16BE(rawData, fileOffset + 0);
unk_02 = BitConverter::ToUInt16BE(rawData, fileOffset + 2);
unk_04 = BitConverter::ToInt16BE(rawData, fileOffset + 4);
unk_06 = BitConverter::ToInt16BE(rawData, fileOffset + 6);
unk_08 = BitConverter::ToFloatBE(rawData, fileOffset + 8);
}
TransformData::TransformData(ZFile* parent, const std::vector<uint8_t>& rawData,
uint32_t fileOffset, size_t index)
: TransformData(parent, rawData, fileOffset + index * GetRawDataSize())
{
}
std::string TransformData::GetBody([[maybe_unused]] const std::string& prefix) const
{
return StringHelper::Sprintf("0x%04X, 0x%04X, %i, %i, %ff", unk_00, unk_02, unk_04, unk_06,
unk_08);
}
size_t TransformData::GetRawDataSize() const
{
return 0x0C;
}
std::string TransformData::GetSourceTypeName()
{
return "TransformData";
}
ZCurveAnimation::ZCurveAnimation(ZFile* nParent) : ZAnimation(nParent)
{
RegisterOptionalAttribute("SkelOffset");
}
void ZCurveAnimation::ParseXML(tinyxml2::XMLElement* reader)
{
ZAnimation::ParseXML(reader);
std::string skelOffsetXml = registeredAttributes.at("SkelOffset").value;
if (skelOffsetXml == "")
{
HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
"missing 'SkelOffset' attribute in <ZCurveAnimation>",
"You need to provide the offset of the curve skeleton.");
}
skelOffset = StringHelper::StrToL(skelOffsetXml, 0);
}
void ZCurveAnimation::ParseRawData()
{
ZAnimation::ParseRawData();
const auto& rawData = parent->GetRawData();
refIndex = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0);
transformData = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
copyValues = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
unk_0C = BitConverter::ToInt16BE(rawData, rawDataIndex + 12);
unk_10 = BitConverter::ToInt16BE(rawData, rawDataIndex + 14);
uint32_t limbCountAddress = Seg2Filespace(skelOffset, parent->baseAddress) + 4;
limbCount = BitConverter::ToUInt8BE(rawData, limbCountAddress);
size_t transformDataSize = 0;
size_t copyValuesSize = 0;
if (refIndex != 0)
{
uint32_t refIndexOffset = Seg2Filespace(refIndex, parent->baseAddress);
for (size_t i = 0; i < 3 * 3 * limbCount; i++)
{
uint8_t ref = BitConverter::ToUInt8BE(rawData, refIndexOffset + i);
if (ref == 0)
copyValuesSize++;
else
transformDataSize += ref;
refIndexArr.emplace_back(ref);
}
}
if (transformData != 0)
{
uint32_t transformDataOffset = Seg2Filespace(transformData, parent->baseAddress);
for (size_t i = 0; i < transformDataSize; i++)
transformDataArr.emplace_back(parent, rawData, transformDataOffset, i);
}
if (copyValues != 0)
{
uint32_t copyValuesOffset = Seg2Filespace(copyValues, parent->baseAddress);
for (size_t i = 0; i < copyValuesSize; i++)
copyValuesArr.emplace_back(BitConverter::ToInt16BE(rawData, copyValuesOffset + i * 2));
}
}
void ZCurveAnimation::DeclareReferences(const std::string& prefix)
{
if (refIndex != 0)
{
uint32_t refIndexOffset = Seg2Filespace(refIndex, parent->baseAddress);
std::string refIndexStr =
StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Ref", refIndexOffset);
std::string entryStr = " ";
uint16_t arrayItemCnt = refIndexArr.size();
size_t i = 0;
for (auto& child : refIndexArr)
{
entryStr += StringHelper::Sprintf("0x%02X, %s", child, (i++ % 8 == 7) ? "\n " : "");
}
Declaration* decl = parent->GetDeclaration(refIndexOffset);
if (decl == nullptr)
{
parent->AddDeclarationArray(refIndexOffset, DeclarationAlignment::Align4,
arrayItemCnt * 1, "u8", refIndexStr, arrayItemCnt,
entryStr);
}
else
{
decl->text = entryStr;
}
}
if (transformData != 0)
{
uint32_t transformDataOffset = Seg2Filespace(transformData, parent->baseAddress);
std::string transformDataStr = StringHelper::Sprintf(
"%sCurveAnime_%s_%06X", prefix.c_str(),
transformDataArr.at(0).GetSourceTypeName().c_str(), transformDataOffset);
std::string entryStr;
uint16_t arrayItemCnt = transformDataArr.size();
size_t i = 0;
for (auto& child : transformDataArr)
{
entryStr += StringHelper::Sprintf(" { %s },%s", child.GetBody(prefix).c_str(),
(++i < arrayItemCnt) ? "\n" : "");
}
Declaration* decl = parent->GetDeclaration(transformDataOffset);
if (decl == nullptr)
{
parent->AddDeclarationArray(transformDataOffset, DeclarationAlignment::Align4,
arrayItemCnt * transformDataArr.at(0).GetRawDataSize(),
transformDataArr.at(0).GetSourceTypeName(),
transformDataStr, arrayItemCnt, entryStr);
}
else
{
decl->text = entryStr;
}
}
if (copyValues != 0)
{
uint32_t copyValuesOffset = Seg2Filespace(copyValues, parent->baseAddress);
std::string copyValuesStr =
StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Copy", copyValuesOffset);
std::string entryStr = " ";
uint16_t arrayItemCnt = copyValuesArr.size();
size_t i = 0;
for (auto& child : copyValuesArr)
{
entryStr += StringHelper::Sprintf("% 6i, %s", child, (i++ % 8 == 7) ? "\n " : "");
}
Declaration* decl = parent->GetDeclaration(copyValuesOffset);
if (decl == nullptr)
{
parent->AddDeclarationArray(copyValuesOffset, DeclarationAlignment::Align4,
arrayItemCnt * 2, "s16", copyValuesStr, arrayItemCnt,
entryStr);
}
else
{
decl->text = entryStr;
}
}
}
std::string ZCurveAnimation::GetBodySourceCode() const
{
std::string refIndexStr;
Globals::Instance->GetSegmentedPtrName(refIndex, parent, "u8", refIndexStr);
std::string transformDataStr;
Globals::Instance->GetSegmentedPtrName(transformData, parent, "TransformData",
transformDataStr);
std::string copyValuesStr;
Globals::Instance->GetSegmentedPtrName(copyValues, parent, "s16", copyValuesStr);
return StringHelper::Sprintf("\n\t%s,\n\t%s,\n\t%s,\n\t%i, %i\n", refIndexStr.c_str(),
transformDataStr.c_str(), copyValuesStr.c_str(), unk_0C, unk_10);
}
size_t ZCurveAnimation::GetRawDataSize() const
{
return 0x10;
}
DeclarationAlignment ZCurveAnimation::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align4;
}
std::string ZCurveAnimation::GetSourceTypeName() const
{
return "TransformUpdateIndex";
}
/* ZLegacyAnimation */
ZLegacyAnimation::ZLegacyAnimation(ZFile* nParent) : ZAnimation(nParent)
{
}
void ZLegacyAnimation::ParseRawData()
{
ZAnimation::ParseRawData();
const auto& rawData = parent->GetRawData();
limbCount = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x02);
frameData = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x04);
jointKey = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x08);
if (GETSEGNUM(frameData) == parent->segment && GETSEGNUM(jointKey) == parent->segment)
{
uint32_t frameDataOffset = Seg2Filespace(frameData, parent->baseAddress);
uint32_t jointKeyOffset = Seg2Filespace(jointKey, parent->baseAddress);
uint32_t ptr = frameDataOffset;
for (size_t i = 0; i < (jointKeyOffset - frameDataOffset) / 2; i++)
{
frameDataArray.push_back(BitConverter::ToUInt16BE(rawData, ptr));
ptr += 2;
}
ptr = jointKeyOffset;
for (int32_t i = 0; i < limbCount + 1; i++)
{
JointKey key(parent);
key.ExtractFromFile(ptr);
jointKeyArray.push_back(key);
ptr += key.GetRawDataSize();
}
}
}
void ZLegacyAnimation::DeclareReferences(const std::string& prefix)
{
std::string varPrefix = prefix;
if (name != "")
varPrefix = name;
ZAnimation::DeclareReferences(varPrefix);
if (!frameDataArray.empty())
{
uint32_t frameDataOffset = Seg2Filespace(frameData, parent->baseAddress);
if (GETSEGNUM(frameData) == parent->segment && !parent->HasDeclaration(frameDataOffset))
{
std::string frameDataBody = "\t";
for (size_t i = 0; i < frameDataArray.size(); i++)
{
frameDataBody += StringHelper::Sprintf("0x%04X, ", frameDataArray[i]);
if (i % 8 == 7 && i + 1 < frameDataArray.size())
frameDataBody += "\n\t";
}
std::string frameDataName = StringHelper::Sprintf("%sFrameData", varPrefix.c_str());
parent->AddDeclarationArray(frameDataOffset, DeclarationAlignment::Align4,
frameDataArray.size() * 2, "s16", frameDataName,
frameDataArray.size(), frameDataBody);
}
}
if (!jointKeyArray.empty())
{
uint32_t jointKeyOffset = Seg2Filespace(jointKey, parent->baseAddress);
if (GETSEGNUM(jointKey) == parent->segment && !parent->HasDeclaration(jointKeyOffset))
{
const auto res = jointKeyArray.at(0);
std::string jointKeyBody;
for (size_t i = 0; i < jointKeyArray.size(); i++)
{
jointKeyBody += StringHelper::Sprintf("\t{ %s },",
jointKeyArray[i].GetBodySourceCode().c_str());
if (i + 1 < jointKeyArray.size())
jointKeyBody += "\n";
}
std::string jointKeyName = StringHelper::Sprintf("%sJointKey", varPrefix.c_str());
parent->AddDeclarationArray(jointKeyOffset, DeclarationAlignment::Align4,
jointKeyArray.size() * res.GetRawDataSize(),
res.GetSourceTypeName(), jointKeyName, jointKeyArray.size(),
jointKeyBody);
}
}
}
std::string ZLegacyAnimation::GetBodySourceCode() const
{
std::string body = "\n";
std::string frameDataName;
std::string jointKeyName;
Globals::Instance->GetSegmentedPtrName(frameData, parent, "s16", frameDataName);
Globals::Instance->GetSegmentedPtrName(jointKey, parent, "JointKey", jointKeyName);
body += StringHelper::Sprintf("\t%i, %i,\n", frameCount, limbCount);
body += StringHelper::Sprintf("\t%s,\n", frameDataName.c_str());
body += StringHelper::Sprintf("\t%s\n", jointKeyName.c_str());
return body;
}
std::string ZLegacyAnimation::GetSourceTypeName() const
{
return "LegacyAnimationHeader";
}
size_t ZLegacyAnimation::GetRawDataSize() const
{
return 0x0C;
}
JointKey::JointKey(ZFile* nParent) : ZResource(nParent)
{
}
void JointKey::ParseRawData()
{
ZResource::ParseRawData();
const auto& rawData = parent->GetRawData();
xMax = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x00);
x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x02);
yMax = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x04);
y = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x06);
zMax = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x08);
z = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x0A);
}
std::string JointKey::GetBodySourceCode() const
{
return StringHelper::Sprintf("%6i, %6i, %6i, %6i, %6i, %6i", xMax, x, yMax, y, zMax, z);
}
std::string JointKey::GetSourceTypeName() const
{
return "JointKey";
}
ZResourceType JointKey::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
size_t JointKey::GetRawDataSize() const
{
return 0x0C;
}

180
ZAPDTR/ZAPD/ZAnimation.h Normal file
View File

@ -0,0 +1,180 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "Vec3s.h"
#include "ZResource.h"
#include "ZSkeleton.h"
#include "tinyxml2.h"
struct RotationIndex
{
// uint16_t transX, transY, transZ;
uint16_t x, y, z;
RotationIndex(uint16_t nX, uint16_t nY, uint16_t nZ) : x(nX), y(nY), z(nZ) {}
};
class ZAnimation : public ZResource
{
public:
int16_t frameCount;
ZAnimation(ZFile* nParent);
//std::string GetSourceOutputHeader(const std::string& prefix) override;
ZResourceType GetResourceType() const override;
protected:
void ParseRawData() override;
};
class ZNormalAnimation : public ZAnimation
{
public:
std::vector<uint16_t> rotationValues;
std::vector<RotationIndex> rotationIndices;
segptr_t rotationValuesSeg = 0;
segptr_t rotationIndicesSeg = 0;
offset_t rotationValuesOffset = 0;
offset_t rotationIndicesOffset = 0;
int16_t limit = 0;
ZNormalAnimation(ZFile* nParent);
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
size_t GetRawDataSize() const override;
std::string GetSourceTypeName() const override;
void ParseRawData() override;
};
class ZLinkAnimation : public ZAnimation
{
public:
segptr_t segmentAddress;
ZLinkAnimation(ZFile* nParent);
std::string GetBodySourceCode() const override;
size_t GetRawDataSize() const override;
std::string GetSourceTypeName() const override;
void ParseRawData() override;
};
class TransformData
{
public:
ZFile* parent;
///* 0x0000 */ u16 unk_00; // appears to be flags
uint16_t unk_00;
///* 0x0002 */ s16 unk_02;
int16_t unk_02;
///* 0x0004 */ s16 unk_04;
int16_t unk_04;
///* 0x0006 */ s16 unk_06;
int16_t unk_06;
///* 0x0008 */ f32 unk_08;
float unk_08;
public:
TransformData() = default;
TransformData(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset);
TransformData(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset,
size_t index);
[[nodiscard]] std::string GetBody(const std::string& prefix) const;
size_t GetRawDataSize() const;
std::string GetSourceTypeName();
};
class ZCurveAnimation : public ZAnimation
{
public:
segptr_t skelOffset = 0;
///* 0x0000 */ u8* refIndex;
segptr_t refIndex = 0;
///* 0x0004 */ TransformData* transformData;
segptr_t transformData = 0;
///* 0x0008 */ s16* copyValues;
segptr_t copyValues = 0;
///* 0x000C */ s16 unk_0C;
int16_t unk_0C;
///* 0x000E */ s16 unk_10;
int16_t unk_10;
uint8_t limbCount = 0;
std::vector<uint8_t> refIndexArr;
std::vector<TransformData> transformDataArr;
std::vector<int16_t> copyValuesArr;
public:
ZCurveAnimation(ZFile* nParent);
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
size_t GetRawDataSize() const override;
DeclarationAlignment GetDeclarationAlignment() const override;
std::string GetSourceTypeName() const override;
};
// TransformUpdateIndex
/* ZLegacyAnimation */
class JointKey : public ZResource
{
public:
JointKey(ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
protected:
int16_t xMax, x;
int16_t yMax, y;
int16_t zMax, z;
};
class ZLegacyAnimation : public ZAnimation
{
public:
ZLegacyAnimation(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
size_t GetRawDataSize() const override;
protected:
int16_t limbCount;
segptr_t frameData; // s16*
segptr_t jointKey; // JointKey*
std::vector<uint16_t> frameDataArray;
std::vector<JointKey> jointKeyArray;
};

143
ZAPDTR/ZAPD/ZArray.cpp Normal file
View File

@ -0,0 +1,143 @@
#include "ZArray.h"
#include <cassert>
#include "Globals.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Array, ZArray);
ZArray::ZArray(ZFile* nParent) : ZResource(nParent)
{
canHaveInner = true;
genOTRDef = true;
RegisterRequiredAttribute("Count");
}
ZArray::~ZArray()
{
for (auto res : resList)
delete res;
}
void ZArray::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
arrayCnt = reader->IntAttribute("Count", 0);
if (arrayCnt <= 0)
{
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'Count' attribute", "");
}
tinyxml2::XMLElement* child = reader->FirstChildElement();
if (child == nullptr)
{
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex,
"<Array> needs one sub-element", "");
}
childName = child->Name();
auto nodeMap = ZFile::GetNodeMap();
size_t childIndex = rawDataIndex;
for (size_t i = 0; i < arrayCnt; i++)
{
ZResource* res = nodeMap->at(childName)(parent);
if (!res->DoesSupportArray())
{
std::string errorHeader = StringHelper::Sprintf(
"resource <%s> does not support being wrapped in an <Array>", childName.c_str());
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, errorHeader,
"");
}
res->parent = parent;
res->SetInnerNode(true);
res->ExtractFromXML(child, childIndex);
childIndex += res->GetRawDataSize();
resList.push_back(res);
}
}
Declaration* ZArray::DeclareVar(const std::string& prefix, const std::string& bodyStr)
{
std::string auxName = name;
if (name == "")
auxName = GetDefaultName(prefix);
ZResource* res = resList.at(0);
Declaration* decl;
if (res->IsExternalResource())
{
auto filepath = Globals::Instance->outputPath / name;
std::string includePath = StringHelper::Sprintf("%s.%s.inc", filepath.c_str(),
res->GetExternalExtension().c_str());
decl = parent->AddDeclarationIncludeArray(rawDataIndex, includePath, GetRawDataSize(),
GetSourceTypeName(), name, arrayCnt);
decl->text = bodyStr;
decl->isExternal = true;
}
else
{
decl =
parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(),
GetSourceTypeName(), name, arrayCnt, bodyStr);
}
decl->staticConf = staticConf;
return decl;
}
std::string ZArray::GetBodySourceCode() const
{
std::string output = "";
for (size_t i = 0; i < arrayCnt; i++)
{
const auto& res = resList[i];
output += "\t";
if (res->GetResourceType() == ZResourceType::Scalar ||
res->GetResourceType() == ZResourceType::Vertex)
output += resList.at(i)->GetBodySourceCode();
else
output += StringHelper::Sprintf("{ %s }", resList.at(i)->GetBodySourceCode().c_str());
if (i < arrayCnt - 1 || res->IsExternalResource())
output += ",\n";
}
return output;
}
size_t ZArray::GetRawDataSize() const
{
size_t size = 0;
for (auto res : resList)
size += res->GetRawDataSize();
return size;
}
std::string ZArray::GetSourceTypeName() const
{
return resList.at(0)->GetSourceTypeName();
}
ZResourceType ZArray::GetResourceType() const
{
return ZResourceType::Array;
}
DeclarationAlignment ZArray::GetDeclarationAlignment() const
{
if (resList.size() == 0)
{
return DeclarationAlignment::Align4;
}
return resList.at(0)->GetDeclarationAlignment();
}

31
ZAPDTR/ZAPD/ZArray.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "ZResource.h"
#include "tinyxml2.h"
class ZArray : public ZResource
{
public:
ZArray(ZFile* nParent);
~ZArray();
void ParseXML(tinyxml2::XMLElement* reader) override;
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetBodySourceCode() const override;
size_t GetRawDataSize() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
DeclarationAlignment GetDeclarationAlignment() const override;
size_t arrayCnt;
std::vector<ZResource*> resList;
protected:
std::string childName;
};

192
ZAPDTR/ZAPD/ZBackground.cpp Normal file
View File

@ -0,0 +1,192 @@
#include "ZBackground.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Background, ZBackground);
#define JPEG_MARKER 0xFFD8FFE0
#define MARKER_DQT 0xFFDB
#define MARKER_EOI 0xFFD9
ZBackground::ZBackground(ZFile* nParent) : ZResource(nParent)
{
}
void ZBackground::ParseRawData()
{
ZResource::ParseRawData();
const auto& rawData = parent->GetRawData();
size_t i = 0;
while (true)
{
uint8_t val = rawData.at(rawDataIndex + i);
data.push_back(val);
if (BitConverter::ToUInt16BE(rawData, rawDataIndex + i) == MARKER_EOI)
{
data.push_back(rawData.at(rawDataIndex + i + 1));
break;
}
i++;
}
}
void ZBackground::ParseBinaryFile(const std::string& inFolder, bool appendOutName)
{
fs::path filepath(inFolder);
if (appendOutName)
filepath = filepath / (outName + "." + GetExternalExtension());
data = File::ReadAllBytes(filepath.string());
// Add padding.
data.insert(data.end(), GetRawDataSize() - data.size(), 0x00);
CheckValidJpeg(filepath.generic_string());
}
void ZBackground::CheckValidJpeg(const std::string& filepath)
{
std::string filename = outName;
if (filepath != "")
{
filename = filepath;
}
uint32_t jpegMarker = BitConverter::ToUInt32BE(data, 0);
if (jpegMarker != JPEG_MARKER)
{
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG,
StringHelper::Sprintf("missing jpeg marker at beginning of file: '%s'",
filename.c_str()),
"The game will skip this jpeg.");
}
if (data.at(6) != 'J' || data.at(7) != 'F' || data.at(8) != 'I' || data.at(9) != 'F' ||
data.at(10) != '\0')
{
std::string jfifIdentifier(data.begin() + 6, data.begin() + 6 + 5);
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG, "missing 'JFIF' identifier",
StringHelper::Sprintf(
"This image may be corrupted, or not a jpeg. The identifier found was: '%s'",
jfifIdentifier.c_str()));
}
uint8_t majorVersion = data.at(11);
uint8_t minorVersion = data.at(12);
if (majorVersion != 0x01 || minorVersion != 0x01)
{
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG,
StringHelper::Sprintf("wrong JFIF version '%i.%02i'", majorVersion, minorVersion),
"The expected version is '1.01'. The game may be unable to decode this image "
"correctly.");
}
if (BitConverter::ToUInt16BE(data, 20) != MARKER_DQT)
{
// This may happen when creating a custom image with Exif, XMP, thumbnail, progressive, etc.
// enabled.
HANDLE_WARNING_PROCESS(WarningType::InvalidJPEG,
"there seems to be extra data before the image data in this file",
"The game may not be able to decode this image correctly.");
}
if (data.size() > GetRawDataSize())
{
HANDLE_WARNING_PROCESS(
WarningType::InvalidJPEG, "the image is bigger than the screen buffer",
StringHelper::Sprintf("Image size: %zu bytes\nScreen buffer size: %zu bytes",
data.size(), GetRawDataSize()));
}
}
size_t ZBackground::GetRawDataSize() const
{
// Jpgs use the whole sceen buffer, which is a u16 matrix.
return Globals::Instance->cfg.bgScreenHeight * Globals::Instance->cfg.bgScreenWidth * 2;
}
Declaration* ZBackground::DeclareVar(const std::string& prefix,
[[maybe_unused]] const std::string& bodyStr)
{
std::string auxName = name;
std::string auxOutName = outName;
if (auxName == "")
auxName = GetDefaultName(prefix);
if (auxOutName == "")
auxOutName = GetDefaultName(prefix);
auto filepath = Globals::Instance->outputPath / fs::path(auxOutName).stem();
std::string incStr =
StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str());
Declaration* decl = parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(),
GetSourceTypeName(), auxName, 0);
decl->arrayItemCntStr = "SCREEN_WIDTH * SCREEN_HEIGHT / 4";
decl->forceArrayCnt = true;
decl->staticConf = staticConf;
return decl;
}
bool ZBackground::IsExternalResource() const
{
return true;
}
std::string ZBackground::GetExternalExtension() const
{
return "jpg";
}
void ZBackground::Save(const fs::path& outFolder)
{
fs::path filepath = outFolder / (outName + "." + GetExternalExtension());
File::WriteAllBytes(filepath.string(), data);
}
std::string ZBackground::GetBodySourceCode() const
{
std::string bodyStr = " ";
for (size_t i = 0; i < data.size() / 8; ++i)
{
bodyStr += StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(data, i * 8));
if (i % 8 == 7)
bodyStr += "\n ";
}
bodyStr += "\n";
return bodyStr;
}
std::string ZBackground::GetDefaultName(const std::string& prefix) const
{
return StringHelper::Sprintf("%sBackground_%06X", prefix.c_str(), rawDataIndex);
}
std::string ZBackground::GetSourceTypeName() const
{
return "u64";
}
ZResourceType ZBackground::GetResourceType() const
{
return ZResourceType::Background;
}
DeclarationAlignment ZBackground::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align8;
}

34
ZAPDTR/ZAPD/ZBackground.h Normal file
View File

@ -0,0 +1,34 @@
#pragma once
#include <cstdint>
#include <vector>
#include "ZResource.h"
class ZBackground : public ZResource
{
protected:
std::vector<uint8_t> data;
public:
ZBackground(ZFile* nParent);
void ParseBinaryFile(const std::string& inFolder, bool appendOutName);
void ParseRawData() override;
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetBodySourceCode() const override;
std::string GetDefaultName(const std::string& prefix) const override;
void Save(const fs::path& outFolder) override;
bool IsExternalResource() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
std::string GetExternalExtension() const override;
size_t GetRawDataSize() const override;
DeclarationAlignment GetDeclarationAlignment() const override;
void CheckValidJpeg(const std::string& filepath);
};

116
ZAPDTR/ZAPD/ZBlob.cpp Normal file
View File

@ -0,0 +1,116 @@
#include "ZBlob.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/File.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Blob, ZBlob);
ZBlob::ZBlob(ZFile* nParent) : ZResource(nParent)
{
genOTRDef = true;
RegisterRequiredAttribute("Size");
}
ZBlob* ZBlob::FromFile(const std::string& filePath)
{
ZBlob* blob = new ZBlob(nullptr);
blob->name = StringHelper::Split(Path::GetFileNameWithoutExtension(filePath), ".")[0];
blob->blobData = File::ReadAllBytes(filePath);
return blob;
}
void ZBlob::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
blobSize = StringHelper::StrToL(registeredAttributes.at("Size").value, 16);
}
void ZBlob::ParseRawData()
{
blobData.assign(parent->GetRawData().begin() + rawDataIndex,
parent->GetRawData().begin() + rawDataIndex + blobSize);
}
Declaration* ZBlob::DeclareVar(const std::string& prefix,
[[maybe_unused]] const std::string& bodyStr)
{
std::string auxName = name;
std::string auxOutName = outName;
if (auxName == "")
auxName = GetDefaultName(prefix);
if (auxOutName == "")
auxOutName = GetDefaultName(prefix);
std::string path = Path::GetFileNameWithoutExtension(auxOutName);
std::string assetOutDir =
(Globals::Instance->outputPath / Path::GetFileNameWithoutExtension(GetOutName())).string();
std::string incStr =
StringHelper::Sprintf("%s.%s.inc.c", assetOutDir.c_str(), GetExternalExtension().c_str());
return parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(),
GetSourceTypeName(), auxName, blobData.size());
}
std::string ZBlob::GetBodySourceCode() const
{
std::string sourceOutput;
for (size_t i = 0; i < blobData.size(); i += 1)
{
if (i % 16 == 0)
sourceOutput += "\t";
sourceOutput += StringHelper::Sprintf("0x%02X, ", blobData[i]);
if (i % 16 == 15)
sourceOutput += "\n";
}
// Ensure there's always a trailing line feed to prevent dumb warnings.
// Please don't remove this line, unless you somehow made a way to prevent
// that warning when building the OoT repo.
sourceOutput += "\n";
return sourceOutput;
}
void ZBlob::Save(const fs::path& outFolder)
{
if (!Globals::Instance->otrMode)
File::WriteAllBytes((outFolder / (name + ".bin")).string(), blobData);
}
bool ZBlob::IsExternalResource() const
{
return true;
}
std::string ZBlob::GetExternalExtension() const
{
return "bin";
}
std::string ZBlob::GetSourceTypeName() const
{
return "u8";
}
ZResourceType ZBlob::GetResourceType() const
{
return ZResourceType::Blob;
}
size_t ZBlob::GetRawDataSize() const
{
return blobSize;
}

31
ZAPDTR/ZAPD/ZBlob.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include "ZResource.h"
#include "tinyxml2.h"
class ZBlob : public ZResource
{
public:
ZBlob(ZFile* nParent);
static ZBlob* FromFile(const std::string& filePath);
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetBodySourceCode() const override;
void Save(const fs::path& outFolder) override;
bool IsExternalResource() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
std::string GetExternalExtension() const override;
size_t GetRawDataSize() const override;
protected:
std::vector<uint8_t> blobData;
size_t blobSize = 0;
};

364
ZAPDTR/ZAPD/ZCollision.cpp Normal file
View File

@ -0,0 +1,364 @@
#include "ZCollision.h"
#include <cstdint>
#include <string>
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
REGISTER_ZFILENODE(Collision, ZCollisionHeader);
ZCollisionHeader::ZCollisionHeader(ZFile* nParent) : ZResource(nParent)
{
genOTRDef = true;
}
ZCollisionHeader::~ZCollisionHeader()
{
delete camData;
}
void ZCollisionHeader::ParseRawData()
{
const auto& rawData = parent->GetRawData();
absMinX = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
absMinY = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
absMinZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
absMaxX = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
absMaxY = BitConverter::ToInt16BE(rawData, rawDataIndex + 8);
absMaxZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 10);
numVerts = BitConverter::ToUInt16BE(rawData, rawDataIndex + 12);
vtxAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 16);
numPolygons = BitConverter::ToUInt16BE(rawData, rawDataIndex + 20);
polyAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 24);
polyTypeDefAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 28);
camDataAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 32);
numWaterBoxes = BitConverter::ToUInt16BE(rawData, rawDataIndex + 36);
waterBoxAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 40);
vtxSegmentOffset = Seg2Filespace(vtxAddress, parent->baseAddress);
polySegmentOffset = Seg2Filespace(polyAddress, parent->baseAddress);
polyTypeDefSegmentOffset = Seg2Filespace(polyTypeDefAddress, parent->baseAddress);
camDataSegmentOffset = Seg2Filespace(camDataAddress, parent->baseAddress);
waterBoxSegmentOffset = Seg2Filespace(waterBoxAddress, parent->baseAddress);
vertices.reserve(numVerts);
polygons.reserve(numPolygons);
uint32_t currentPtr = vtxSegmentOffset;
for (uint16_t i = 0; i < numVerts; i++)
{
ZVector vec(parent);
vec.ExtractFromBinary(currentPtr, ZScalarType::ZSCALAR_S16, 3);
currentPtr += vec.GetRawDataSize();
vertices.push_back(vec);
}
for (uint16_t i = 0; i < numPolygons; i++)
polygons.push_back(PolygonEntry(rawData, polySegmentOffset + (i * 16)));
uint16_t highestPolyType = 0;
for (PolygonEntry poly : polygons)
{
if (poly.type > highestPolyType)
highestPolyType = poly.type;
}
for (uint16_t i = 0; i < highestPolyType + 1; i++)
polygonTypes.push_back(
BitConverter::ToUInt64BE(rawData, polyTypeDefSegmentOffset + (i * 8)));
if (camDataAddress != 0)
camData = new CameraDataList(parent, name, rawData, camDataSegmentOffset,
polyTypeDefSegmentOffset, polygonTypes.size());
for (uint16_t i = 0; i < numWaterBoxes; i++)
waterBoxes.push_back(WaterBoxHeader(
rawData,
waterBoxSegmentOffset + (i * (Globals::Instance->game == ZGame::OOT_SW97 ? 12 : 16))));
}
void ZCollisionHeader::DeclareReferences(const std::string& prefix)
{
std::string declaration = "";
std::string auxName = name;
if (name == "")
auxName = GetDefaultName(prefix);
if (waterBoxes.size() > 0)
{
for (size_t i = 0; i < waterBoxes.size(); i++)
{
declaration +=
StringHelper::Sprintf("\t{ %s },", waterBoxes[i].GetBodySourceCode().c_str());
if (i + 1 < waterBoxes.size())
declaration += "\n";
}
parent->AddDeclarationArray(
waterBoxSegmentOffset, DeclarationAlignment::Align4, 16 * waterBoxes.size(), "WaterBox",
StringHelper::Sprintf("%s_waterBoxes_%06X", auxName.c_str(), waterBoxSegmentOffset),
waterBoxes.size(), declaration);
}
if (polygons.size() > 0)
{
declaration.clear();
for (size_t i = 0; i < polygons.size(); i++)
{
declaration += StringHelper::Sprintf(
"\t{ 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X },",
polygons[i].type, polygons[i].vtxA, polygons[i].vtxB, polygons[i].vtxC,
polygons[i].a, polygons[i].b, polygons[i].c, polygons[i].d);
if (i + 1 < polygons.size())
declaration += "\n";
}
parent->AddDeclarationArray(
polySegmentOffset, DeclarationAlignment::Align4, polygons.size() * 16, "CollisionPoly",
StringHelper::Sprintf("%s_polygons_%08X", auxName.c_str(), polySegmentOffset),
polygons.size(), declaration);
}
declaration.clear();
for (size_t i = 0; i < polygonTypes.size(); i++)
{
declaration += StringHelper::Sprintf("\t{ 0x%08lX, 0x%08lX },", polygonTypes[i] >> 32,
polygonTypes[i] & 0xFFFFFFFF);
if (i < polygonTypes.size() - 1)
declaration += "\n";
}
if (polyTypeDefAddress != 0)
parent->AddDeclarationArray(
polyTypeDefSegmentOffset, DeclarationAlignment::Align4, polygonTypes.size() * 8,
"SurfaceType",
StringHelper::Sprintf("%s_surfaceType_%08X", auxName.c_str(), polyTypeDefSegmentOffset),
polygonTypes.size(), declaration);
declaration.clear();
if (vertices.size() > 0)
{
declaration.clear();
for (size_t i = 0; i < vertices.size(); i++)
{
declaration +=
StringHelper::Sprintf("\t{ %s },", vertices[i].GetBodySourceCode().c_str());
if (i < vertices.size() - 1)
declaration += "\n";
}
const auto& first = vertices.front();
if (vtxAddress != 0)
parent->AddDeclarationArray(
vtxSegmentOffset, first.GetDeclarationAlignment(),
vertices.size() * first.GetRawDataSize(), first.GetSourceTypeName(),
StringHelper::Sprintf("%s_vtx_%08X", auxName.c_str(), vtxSegmentOffset),
vertices.size(), declaration);
}
}
std::string ZCollisionHeader::GetBodySourceCode() const
{
std::string declaration = "";
declaration += "\n";
declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMinX, absMinY, absMinZ);
declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMaxX, absMaxY, absMaxZ);
std::string vtxName;
Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName);
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str());
std::string polyName;
Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName);
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str());
std::string surfaceName;
Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName);
declaration += StringHelper::Sprintf("\t%s,\n", surfaceName.c_str());
std::string camName;
Globals::Instance->GetSegmentedPtrName(camDataAddress, parent, "CamData", camName);
declaration += StringHelper::Sprintf("\t%s,\n", camName.c_str());
std::string waterBoxName;
Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName);
declaration += StringHelper::Sprintf("\t%i,\n\t%s\n", numWaterBoxes, waterBoxName.c_str());
return declaration;
}
std::string ZCollisionHeader::GetDefaultName(const std::string& prefix) const
{
return StringHelper::Sprintf("%sCol_%06X", prefix.c_str(), rawDataIndex);
}
std::string ZCollisionHeader::GetSourceTypeName() const
{
return "CollisionHeader";
}
ZResourceType ZCollisionHeader::GetResourceType() const
{
return ZResourceType::CollisionHeader;
}
size_t ZCollisionHeader::GetRawDataSize() const
{
return 44;
}
PolygonEntry::PolygonEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
{
const uint8_t* data = rawData.data();
type = BitConverter::ToUInt16BE(data, rawDataIndex + 0);
vtxA = BitConverter::ToUInt16BE(data, rawDataIndex + 2);
vtxB = BitConverter::ToUInt16BE(data, rawDataIndex + 4);
vtxC = BitConverter::ToUInt16BE(data, rawDataIndex + 6);
a = BitConverter::ToUInt16BE(data, rawDataIndex + 8);
b = BitConverter::ToUInt16BE(data, rawDataIndex + 10);
c = BitConverter::ToUInt16BE(data, rawDataIndex + 12);
d = BitConverter::ToUInt16BE(data, rawDataIndex + 14);
}
WaterBoxHeader::WaterBoxHeader(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
{
const uint8_t* data = rawData.data();
xMin = BitConverter::ToInt16BE(data, rawDataIndex + 0);
ySurface = BitConverter::ToInt16BE(data, rawDataIndex + 2);
zMin = BitConverter::ToInt16BE(data, rawDataIndex + 4);
xLength = BitConverter::ToInt16BE(data, rawDataIndex + 6);
zLength = BitConverter::ToInt16BE(data, rawDataIndex + 8);
if (Globals::Instance->game == ZGame::OOT_SW97)
properties = BitConverter::ToInt16BE(data, rawDataIndex + 10);
else
properties = BitConverter::ToInt32BE(data, rawDataIndex + 12);
}
std::string WaterBoxHeader::GetBodySourceCode() const
{
return StringHelper::Sprintf("%i, %i, %i, %i, %i, 0x%08X", xMin, ySurface, zMin, xLength,
zLength, properties);
}
CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix,
const std::vector<uint8_t>& rawData, uint32_t rawDataIndex,
uint32_t polyTypeDefSegmentOffset,
[[maybe_unused]] uint32_t polygonTypesCnt)
{
std::string declaration;
// Parse CameraDataEntries
int32_t numElements = (polyTypeDefSegmentOffset - rawDataIndex) / 8;
uint32_t cameraPosDataSeg = rawDataIndex;
for (int32_t i = 0; i < numElements; i++)
{
CameraDataEntry* entry = new CameraDataEntry();
entry->cameraSType =
BitConverter::ToInt16BE(rawData, rawDataIndex + (entries.size() * 8) + 0);
entry->numData = BitConverter::ToInt16BE(rawData, rawDataIndex + (entries.size() * 8) + 2);
entry->cameraPosDataSeg =
BitConverter::ToInt32BE(rawData, rawDataIndex + (entries.size() * 8) + 4);
if (entry->cameraPosDataSeg != 0 && GETSEGNUM(entry->cameraPosDataSeg) != SEGMENT_SCENE)
{
cameraPosDataSeg = rawDataIndex + (entries.size() * 8);
break;
}
if (entry->cameraPosDataSeg != 0 && cameraPosDataSeg > (entry->cameraPosDataSeg & 0xFFFFFF))
cameraPosDataSeg = (entry->cameraPosDataSeg & 0xFFFFFF);
entries.push_back(entry);
}
// Setting cameraPosDataAddr to rawDataIndex give a pos list length of 0
uint32_t cameraPosDataOffset = cameraPosDataSeg & 0xFFFFFF;
for (size_t i = 0; i < entries.size(); i++)
{
char camSegLine[2048];
if (entries[i]->cameraPosDataSeg != 0)
{
int32_t index =
((entries[i]->cameraPosDataSeg & 0x00FFFFFF) - cameraPosDataOffset) / 0x6;
sprintf(camSegLine, "&%s_camPosData_%08X[%i]", prefix.c_str(), cameraPosDataOffset,
index);
}
else
sprintf(camSegLine, "NULL");
declaration +=
StringHelper::Sprintf(" { 0x%04X, %i, %s },", entries[i]->cameraSType,
entries[i]->numData, camSegLine, rawDataIndex + (i * 8));
if (i < entries.size() - 1)
declaration += "\n";
}
parent->AddDeclarationArray(
rawDataIndex, DeclarationAlignment::Align4, entries.size() * 8, "CamData",
StringHelper::Sprintf("%s_camDataList_%08X", prefix.c_str(), rawDataIndex), entries.size(),
declaration);
uint32_t numDataTotal = (rawDataIndex - cameraPosDataOffset) / 0x6;
if (numDataTotal > 0)
{
declaration.clear();
for (uint32_t i = 0; i < numDataTotal; i++)
{
CameraPositionData* data =
new CameraPositionData(rawData, cameraPosDataOffset + (i * 6));
cameraPositionData.push_back(data);
declaration += StringHelper::Sprintf("\t{ %6i, %6i, %6i },", data->x, data->y, data->z);
if (i + 1 < numDataTotal)
declaration += "\n";
}
int32_t cameraPosDataIndex = GETSEGOFFSET(cameraPosDataSeg);
uint32_t entrySize = numDataTotal * 0x6;
parent->AddDeclarationArray(
cameraPosDataIndex, DeclarationAlignment::Align4, entrySize, "Vec3s",
StringHelper::Sprintf("%s_camPosData_%08X", prefix.c_str(), cameraPosDataIndex),
numDataTotal, declaration);
}
}
CameraDataList::~CameraDataList()
{
for (auto entry : entries)
delete entry;
for (auto camPosData : cameraPositionData)
delete camPosData;
}
CameraPositionData::CameraPositionData(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
{
x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
y = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
z = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
}

99
ZAPDTR/ZAPD/ZCollision.h Normal file
View File

@ -0,0 +1,99 @@
#pragma once
#include "ZFile.h"
#include "ZResource.h"
#include "ZRoom/ZRoom.h"
#include "ZVector.h"
class PolygonEntry
{
public:
uint16_t type;
uint16_t vtxA, vtxB, vtxC;
uint16_t a, b, c, d;
PolygonEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class WaterBoxHeader
{
public:
int16_t xMin;
int16_t ySurface;
int16_t zMin;
int16_t xLength;
int16_t zLength;
int16_t pad;
int32_t properties;
WaterBoxHeader(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
};
class CameraPositionData
{
public:
int16_t x, y, z;
CameraPositionData(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CameraDataEntry
{
public:
uint16_t cameraSType;
int16_t numData;
int32_t cameraPosDataSeg;
};
class CameraDataList
{
public:
std::vector<CameraDataEntry*> entries;
std::vector<CameraPositionData*> cameraPositionData;
CameraDataList(ZFile* parent, const std::string& prefix, const std::vector<uint8_t>& rawData,
uint32_t rawDataIndex, uint32_t polyTypeDefSegmentOffset,
uint32_t polygonTypesCnt);
~CameraDataList();
};
class ZCollisionHeader : public ZResource
{
public:
int16_t absMinX, absMinY, absMinZ;
int16_t absMaxX, absMaxY, absMaxZ;
uint16_t numVerts;
segptr_t vtxAddress;
uint16_t numPolygons;
segptr_t polyAddress;
segptr_t polyTypeDefAddress;
segptr_t camDataAddress;
int32_t numWaterBoxes;
segptr_t waterBoxAddress;
uint32_t vtxSegmentOffset, polySegmentOffset, polyTypeDefSegmentOffset, camDataSegmentOffset,
waterBoxSegmentOffset;
std::vector<ZVector> vertices;
std::vector<PolygonEntry> polygons;
std::vector<uint64_t> polygonTypes;
std::vector<WaterBoxHeader> waterBoxes;
CameraDataList* camData = nullptr;
ZCollisionHeader(ZFile* nParent);
~ZCollisionHeader();
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetDefaultName(const std::string& prefix) const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
};

1260
ZAPDTR/ZAPD/ZCutscene.cpp Normal file

File diff suppressed because it is too large Load Diff

440
ZAPDTR/ZAPD/ZCutscene.h Normal file
View File

@ -0,0 +1,440 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "ZFile.h"
#include "ZResource.h"
#include "tinyxml2.h"
enum class CutsceneCommands
{
Cmd00 = 0x0000,
SetCameraPos = 0x0001,
SetCameraFocus = 0x0002,
SpecialAction = 0x0003,
SetLighting = 0x0004,
SetCameraPosLink = 0x0005,
SetCameraFocusLink = 0x0006,
Cmd07 = 0x0007,
Cmd08 = 0x0008,
Cmd09 = 0x0009,
Unknown = 0x001A,
Textbox = 0x0013,
SetActorAction0 = 0x000A,
SetActorAction1 = 0x000F,
SetActorAction2 = 0x000E,
SetActorAction3 = 0x0019,
SetActorAction4 = 0x001D,
SetActorAction5 = 0x001E,
SetActorAction6 = 0x002C,
SetActorAction7 = 0x001F,
SetActorAction8 = 0x0031,
SetActorAction9 = 0x003E,
SetActorAction10 = 0x008F,
SetSceneTransFX = 0x002D,
Nop = 0x000B,
PlayBGM = 0x0056,
StopBGM = 0x0057,
FadeBGM = 0x007C,
SetTime = 0x008C,
Terminator = 0x03E8,
End = 0xFFFF,
Error = 0xFEAF,
};
class CutsceneCameraPoint
{
public:
int8_t continueFlag;
int8_t cameraRoll;
int16_t nextPointFrame;
float viewAngle;
int16_t posX, posY, posZ;
int16_t unused;
CutsceneCameraPoint(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommand
{
public:
uint32_t commandID;
uint32_t commandIndex;
virtual ~CutsceneCommand();
CutsceneCommand(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
virtual std::string GetCName();
virtual std::string GenerateSourceCode(uint32_t baseAddress);
virtual size_t GetCommandSize();
};
class CutsceneCommandSetCameraPos : public CutsceneCommand
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
uint16_t unused;
std::vector<CutsceneCameraPoint*> entries;
~CutsceneCommandSetCameraPos();
CutsceneCommandSetCameraPos(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class SpecialActionEntry
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
uint16_t unused0;
uint32_t unused1;
uint32_t unused2;
uint32_t unused3;
uint32_t unused4;
uint32_t unused5;
uint32_t unused6;
uint32_t unused7;
uint32_t unused8;
uint32_t unused9;
uint32_t unused10;
SpecialActionEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandSpecialAction : public CutsceneCommand
{
public:
std::vector<SpecialActionEntry*> entries;
CutsceneCommandSpecialAction(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandSpecialAction();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class MusicFadeEntry
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
uint16_t unknown0;
uint32_t unknown1;
uint32_t unknown2;
uint32_t unknown3;
uint32_t unknown4;
uint32_t unknown5;
uint32_t unknown6;
uint32_t unknown7;
uint32_t unknown8;
uint32_t unknown9;
uint32_t unknown10;
MusicFadeEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandFadeBGM : public CutsceneCommand
{
public:
std::vector<MusicFadeEntry*> entries;
CutsceneCommandFadeBGM(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandFadeBGM();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class MusicChangeEntry
{
public:
uint16_t sequence;
uint16_t startFrame;
uint16_t endFrame;
uint16_t unknown0;
uint32_t unknown1;
uint32_t unknown2;
uint32_t unknown3;
uint32_t unknown4;
uint32_t unknown5;
uint32_t unknown6;
uint32_t unknown7;
MusicChangeEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandPlayBGM : public CutsceneCommand
{
public:
std::vector<MusicChangeEntry*> entries;
CutsceneCommandPlayBGM(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandPlayBGM();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class CutsceneCommandStopBGM : public CutsceneCommand
{
public:
std::vector<MusicChangeEntry*> entries;
CutsceneCommandStopBGM(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandStopBGM();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class EnvLightingEntry
{
public:
uint16_t setting;
uint16_t startFrame;
uint16_t endFrame;
uint16_t unused0;
uint32_t unused1;
uint32_t unused2;
uint32_t unused3;
uint32_t unused4;
uint32_t unused5;
uint32_t unused6;
uint32_t unused7;
EnvLightingEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandEnvLighting : public CutsceneCommand
{
public:
std::vector<EnvLightingEntry*> entries;
CutsceneCommandEnvLighting(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandEnvLighting();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class CutsceneCommandSceneTransFX : public CutsceneCommand
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
~CutsceneCommandSceneTransFX();
CutsceneCommandSceneTransFX(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class Unknown9Entry
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
uint16_t unk2;
uint16_t unk3;
uint16_t unk4;
uint8_t unused0;
uint8_t unused1;
Unknown9Entry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandUnknown9 : public CutsceneCommand
{
public:
std::vector<Unknown9Entry*> entries;
CutsceneCommandUnknown9(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandUnknown9();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class UnkEntry
{
public:
uint32_t unused0;
uint32_t unused1;
uint32_t unused2;
uint32_t unused3;
uint32_t unused4;
uint32_t unused5;
uint32_t unused6;
uint32_t unused7;
uint32_t unused8;
uint32_t unused9;
uint32_t unused10;
uint32_t unused11;
UnkEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandUnknown : public CutsceneCommand
{
public:
std::vector<UnkEntry*> entries;
CutsceneCommandUnknown(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandUnknown();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class DayTimeEntry
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
uint8_t hour;
uint8_t minute;
uint8_t unused;
DayTimeEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandDayTime : public CutsceneCommand
{
public:
std::vector<DayTimeEntry*> entries;
CutsceneCommandDayTime(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandDayTime();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class TextboxEntry
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
uint16_t type;
uint16_t textID1;
uint16_t textID2;
TextboxEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandTextbox : public CutsceneCommand
{
public:
std::vector<TextboxEntry*> entries;
CutsceneCommandTextbox(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandTextbox();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class ActorAction
{
public:
uint16_t action;
uint16_t startFrame;
uint16_t endFrame;
int16_t rotX, rotY, rotZ;
int32_t startPosX, startPosY, startPosZ;
int32_t endPosX, endPosY, endPosZ;
float normalX, normalY, normalZ;
ActorAction(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
};
class CutsceneCommandActorAction : public CutsceneCommand
{
public:
std::vector<ActorAction*> entries;
CutsceneCommandActorAction(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
~CutsceneCommandActorAction();
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class CutsceneCommandTerminator : public CutsceneCommand
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
uint16_t unknown;
CutsceneCommandTerminator(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class CutsceneCommandEnd : public CutsceneCommand
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
CutsceneCommandEnd(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetCName();
std::string GenerateSourceCode(uint32_t baseAddress);
size_t GetCommandSize();
};
class CutsceneCommandNop : public CutsceneCommand
{
public:
uint16_t base;
uint16_t startFrame;
uint16_t endFrame;
CutsceneCommandNop(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetCName();
size_t GetCommandSize();
};
class ZCutsceneBase : public ZResource
{
public:
ZCutsceneBase(ZFile* nParent);
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetSourceTypeName() const override;
};
class ZCutscene : public ZCutsceneBase
{
public:
ZCutscene(ZFile* nParent);
~ZCutscene();
void ParseRawData() override;
std::string GetBodySourceCode() const override;
size_t GetRawDataSize() const override;
ZResourceType GetResourceType() const override;
CutsceneCommands GetCommandFromID(int32_t id);
int32_t numCommands;
int32_t endFrame;
std::vector<CutsceneCommand*> commands;
};

View File

@ -0,0 +1,61 @@
#include "ZCutsceneMM.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
ZCutsceneMM::ZCutsceneMM(ZFile* nParent) : ZCutsceneBase(nParent)
{
}
ZCutsceneMM::~ZCutsceneMM()
{
for (CutsceneCommand* cmd : commands)
delete cmd;
}
std::string ZCutsceneMM::GetBodySourceCode() const
{
std::string output;
output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),", numCommands, endFrame);
for (size_t i = 0; i < data.size(); i++)
{
if ((i % 4) == 0)
output += "\n ";
output += StringHelper::Sprintf("0x%08X, ", data[i]);
}
return output;
}
size_t ZCutsceneMM::GetRawDataSize() const
{
return 8 + data.size() * 4;
}
void ZCutsceneMM::ParseRawData()
{
const auto& rawData = parent->GetRawData();
numCommands = BitConverter::ToInt32BE(rawData, rawDataIndex + 0);
commands = std::vector<CutsceneCommand*>();
endFrame = BitConverter::ToInt32BE(rawData, rawDataIndex + 4);
uint32_t currentPtr = rawDataIndex + 8;
uint32_t lastData = 0;
// TODO currently cutscenes aren't being parsed, so just consume words until we see an end
// marker.
do
{
lastData = BitConverter::ToInt32BE(rawData, currentPtr);
data.push_back(lastData);
currentPtr += 4;
} while (lastData != 0xFFFFFFFF);
}
ZResourceType ZCutsceneMM::GetResourceType() const
{
return ZResourceType::Cutscene;
}

29
ZAPDTR/ZAPD/ZCutsceneMM.h Normal file
View File

@ -0,0 +1,29 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "ZCutscene.h"
#include "ZFile.h"
#include "tinyxml2.h"
class ZCutsceneMM : public ZCutsceneBase
{
public:
ZCutsceneMM(ZFile* nParent);
virtual ~ZCutsceneMM();
std::string GetBodySourceCode() const override;
size_t GetRawDataSize() const override;
void ParseRawData() override;
ZResourceType GetResourceType() const override;
protected:
int32_t numCommands;
int32_t endFrame;
std::vector<CutsceneCommand*> commands;
std::vector<uint32_t> data;
};

2121
ZAPDTR/ZAPD/ZDisplayList.cpp Normal file

File diff suppressed because it is too large Load Diff

378
ZAPDTR/ZAPD/ZDisplayList.h Normal file
View File

@ -0,0 +1,378 @@
#pragma once
#include "ZMtx.h"
#include "ZResource.h"
#include "ZRoom/ZRoom.h"
#include "ZTexture.h"
#include "ZVtx.h"
#include "tinyxml2.h"
#include <map>
#include <string>
#include <vector>
enum class F3DEXOpcode
{
G_SPNOOP = 0x00,
G_MTX = 0x01,
G_MOVEMEM = 0x03,
G_VTX = 0x04,
G_DL = 0x06,
G_LOAD_UCODE = 0xAF,
G_BRANCH_Z = 0xB0,
G_TRI2 = 0xB1,
G_MODIFYVTX = 0xB2,
G_RDPHALF_2 = 0xB3,
G_RDPHALF_1 = 0xB4,
G_QUAD = 0xB5,
G_CLEARGEOMETRYMODE = 0xB6,
G_SETGEOMETRYMODE = 0xB7,
G_ENDDL = 0xB8,
G_SETOTHERMODE_L = 0xB9,
G_SETOTHERMODE_H = 0xBA,
G_TEXTURE = 0xBB,
G_MOVEWORD = 0xBC,
G_POPMTX = 0xBD,
G_CULLDL = 0xBE,
G_TRI1 = 0xBF,
G_NOOP = 0xC0,
G_TEXRECT = 0xE4,
G_TEXRECTFLIP = 0xE5,
G_RDPLOADSYNC = 0xE6,
G_RDPPIPESYNC = 0xE7,
G_RDPTILESYNC = 0xE8,
G_RDPFULLSYNC = 0xE9,
G_SETKEYGB = 0xEA,
G_SETKEYR = 0xEB,
G_SETCONVERT = 0xEC,
G_SETSCISSOR = 0xED,
G_SETPRIMDEPTH = 0xEE,
G_RDPSETOTHERMODE = 0xEF,
G_LOADTLUT = 0xF0,
G_SETTILESIZE = 0xF2,
G_LOADBLOCK = 0xF3,
G_LOADTILE = 0xF4,
G_SETTILE = 0xF5,
G_FILLRECT = 0xF6,
G_SETFILLCOLOR = 0xF7,
G_SETFOGCOLOR = 0xF8,
G_SETBLENDCOLOR = 0xF9,
G_SETPRIMCOLOR = 0xFA,
G_SETENVCOLOR = 0xFB,
G_SETCOMBINE = 0xFC,
G_SETTIMG = 0xFD,
G_SETZIMG = 0xFE,
G_SETCIMG = 0xFF
};
enum class F3DZEXOpcode
{
G_NOOP = 0x00,
G_VTX = 0x01,
G_MODIFYVTX = 0x02,
G_CULLDL = 0x03,
G_BRANCH_Z = 0x04,
G_TRI1 = 0x05,
G_TRI2 = 0x06,
G_QUAD = 0x07,
G_SPECIAL_3 = 0xD3,
G_SPECIAL_2 = 0xD4,
G_SPECIAL_1 = 0xD5,
G_DMA_IO = 0xD6,
G_TEXTURE = 0xD7,
G_POPMTX = 0xD8,
G_GEOMETRYMODE = 0xD9,
G_MTX = 0xDA,
G_MOVEWORD = 0xDB,
G_MOVEMEM = 0xDC,
G_LOAD_UCODE = 0xDD,
G_DL = 0xDE,
G_ENDDL = 0xDF,
G_SPNOOP = 0xE0,
G_RDPHALF_1 = 0xE1,
G_SETOTHERMODE_L = 0xE2,
G_SETOTHERMODE_H = 0xE3,
G_TEXRECT = 0xE4,
G_TEXRECTFLIP = 0xE5,
G_RDPLOADSYNC = 0xE6,
G_RDPPIPESYNC = 0xE7,
G_RDPTILESYNC = 0xE8,
G_RDPFULLSYNC = 0xE9,
G_SETKEYGB = 0xEA,
G_SETKEYR = 0xEB,
G_SETCONVERT = 0xEC,
G_SETSCISSOR = 0xED,
G_SETPRIMDEPTH = 0xEE,
G_RDPSETOTHERMODE = 0xEF,
G_LOADTLUT = 0xF0,
G_RDPHALF_2 = 0xF1,
G_SETTILESIZE = 0xF2,
G_LOADBLOCK = 0xF3,
G_LOADTILE = 0xF4,
G_SETTILE = 0xF5,
G_FILLRECT = 0xF6,
G_SETFILLCOLOR = 0xF7,
G_SETFOGCOLOR = 0xF8,
G_SETBLENDCOLOR = 0xF9,
G_SETPRIMCOLOR = 0xFA,
G_SETENVCOLOR = 0xFB,
G_SETCOMBINE = 0xFC,
G_SETTIMG = 0xFD,
G_SETZIMG = 0xFE,
G_SETCIMG = 0xFF,
};
enum class F3DZEXTexFormats
{
G_IM_FMT_RGBA,
G_IM_FMT_YUV,
G_IM_FMT_CI,
G_IM_FMT_IA,
G_IM_FMT_I
};
enum class F3DZEXTexSizes
{
G_IM_SIZ_4b,
G_IM_SIZ_8b,
G_IM_SIZ_16b,
G_IM_SIZ_32b
};
enum class DListType
{
F3DZEX,
F3DEX,
};
enum class OoTSegments
{
DirectReference = 0,
TitleStatic = 1,
Scene = 2,
Room = 3,
GameplayKeep = 4,
FieldDungeonKeep = 5,
Object = 6,
LinkAnimation = 7,
IconItemStatic = 8,
IconItem24Static = 9,
Unknown10 = 10,
Unknown11 = 11,
Unknown12 = 12,
IconFieldDungeonStatic = 13,
IconItemLanguageStatic = 14,
ZBuffer = 15,
FrameBuffer = 16,
};
#define G_MDSFT_ALPHACOMPARE 0
#define G_MDSFT_ZSRCSEL 2
#define G_MDSFT_RENDERMODE 3
#define G_MDSFT_BLENDER 16
#define G_RM_FOG_SHADE_A 0xC8000000
#define G_RM_FOG_PRIM_A 0xC4000000
#define G_RM_PASS 0x0C080000
#define G_RM_AA_ZB_OPA_SURF 0x442078
#define G_RM_AA_ZB_OPA_SURF2 0x112078
#define G_RM_AA_ZB_XLU_SURF 0x4049D8
#define G_RM_AA_ZB_XLU_SURF2 0x1049D8
#define G_RM_AA_ZB_OPA_DECAL 0x442D58
#define G_RM_AA_ZB_OPA_DECAL2 0x112D58
#define G_RM_AA_ZB_XLU_DECAL 0x404DD8
#define G_RM_AA_ZB_XLU_DECAL2 0x104DD8
#define G_RM_AA_ZB_OPA_INTER 0x442478
#define G_RM_AA_ZB_OPA_INTER2 0x112478
#define G_RM_AA_ZB_XLU_INTER 0x4045D8
#define G_RM_AA_ZB_XLU_INTER2 0x1045D8
#define G_RM_AA_ZB_XLU_LINE 0x407858
#define G_RM_AA_ZB_XLU_LINE2 0x107858
#define G_RM_AA_ZB_DEC_LINE 0x407F58
#define G_RM_AA_ZB_DEC_LINE2 0x107F58
#define G_RM_AA_ZB_TEX_EDGE 0x443078
#define G_RM_AA_ZB_TEX_EDGE2 0x113078
#define G_RM_AA_ZB_TEX_INTER 0x443478
#define G_RM_AA_ZB_TEX_INTER2 0x113478
#define G_RM_AA_ZB_SUB_SURF 0x442878
#define G_RM_AA_ZB_SUB_SURF2 0x112278
#define G_RM_AA_ZB_PCL_SURF 0x40007B
#define G_RM_AA_ZB_PCL_SURF2 0x10007B
#define G_RM_AA_ZB_OPA_TERR 0x402078
#define G_RM_AA_ZB_OPA_TERR2 0x102078
#define G_RM_AA_ZB_TEX_TERR 0x403078
#define G_RM_AA_ZB_TEX_TERR2 0x103078
#define G_RM_AA_ZB_SUB_TERR 0x402278
#define G_RM_AA_ZB_SUB_TERR2 0x102278
#define G_RM_RA_ZB_OPA_SURF 0x442038
#define G_RM_RA_ZB_OPA_SURF2 0x112038
#define G_RM_RA_ZB_OPA_DECAL 0x442D18
#define G_RM_RA_ZB_OPA_DECAL2 0x112D18
#define G_RM_RA_ZB_OPA_INTER 0x442438
#define G_RM_RA_ZB_OPA_INTER2 0x112438
#define G_RM_AA_OPA_SURF 0x442048
#define G_RM_AA_OPA_SURF2 0x112048
#define G_RM_AA_XLU_SURF 0x4041C8
#define G_RM_AA_XLU_SURF2 0x1041C8
#define G_RM_AA_XLU_LINE 0x407048
#define G_RM_AA_XLU_LINE2 0x107048
#define G_RM_AA_DEC_LINE 0x407248
#define G_RM_AA_DEC_LINE2 0x107248
#define G_RM_AA_TEX_EDGE 0x443048
#define G_RM_AA_TEX_EDGE2 0x113048
#define G_RM_AA_SUB_SURF 0x442248
#define G_RM_AA_SUB_SURF2 0x112248
#define G_RM_AA_PCL_SURF 0x40004B
#define G_RM_AA_PCL_SURF2 0x10004B
#define G_RM_AA_OPA_TERR 0x402048
#define G_RM_AA_OPA_TERR2 0x102048
#define G_RM_AA_TEX_TERR 0x403048
#define G_RM_AA_TEX_TERR2 0x103048
#define G_RM_AA_SUB_TERR 0x402248
#define G_RM_AA_SUB_TERR2 0x102248
#define G_RM_RA_OPA_SURF 0x442008
#define G_RM_RA_OPA_SURF2 0x112008
#define G_RM_ZB_OPA_SURF 0x442230
#define G_RM_ZB_OPA_SURF2 0x112230
#define G_RM_ZB_XLU_SURF 0x404A50
#define G_RM_ZB_XLU_SURF2 0x104A50
#define G_RM_ZB_OPA_DECAL 0x442E10
#define G_RM_ZB_OPA_DECAL2 0x112E10
#define G_RM_ZB_XLU_DECAL 0x404E50
#define G_RM_ZB_XLU_DECAL2 0x104E50
#define G_RM_ZB_CLD_SURF 0x404B50
#define G_RM_ZB_CLD_SURF2 0x104B50
#define G_RM_ZB_OVL_SURF 0x404F50
#define G_RM_ZB_OVL_SURF2 0x104F50
#define G_RM_ZB_PCL_SURF 0x0C080233
#define G_RM_ZB_PCL_SURF2 0x03020233
#define G_RM_OPA_SURF 0x0C084000
#define G_RM_OPA_SURF2 0x03024000
#define G_RM_XLU_SURF 0x00404200
#define G_RM_XLU_SURF2 0x00104240
#define G_RM_CLD_SURF 0x00404340
#define G_RM_CLD_SURF2 0x00104340
#define G_RM_TEX_EDGE 0x0C087008
#define G_RM_TEX_EDGE2 0x03027008
#define G_RM_PCL_SURF 0x0C084203
#define G_RM_PCL_SURF2 0x03024203
#define G_RM_ADD 0x04484340
#define G_RM_ADD2 0x01124340
#define G_RM_NOOP 0x00000000
#define G_RM_NOOP2 0x00000000
#define G_RM_VISCVG 0x0C844040
#define G_RM_VISCVG2 0x03214040
#define G_RM_OPA_CI 0x0C080000
#define G_RM_OPA_CI2 0x03020000
#define AA_EN 0x8
#define Z_CMP 0x10
#define Z_UPD 0x20
#define IM_RD 0x40
#define CLR_ON_CVG 0x80
#define CVG_DST_CLAMP 0
#define CVG_DST_WRAP 0x100
#define CVG_DST_FULL 0x200
#define CVG_DST_SAVE 0x300
#define ZMODE_OPA 0
#define ZMODE_INTER 0x400
#define ZMODE_XLU 0x800
#define ZMODE_DEC 0xc00
#define CVG_X_ALPHA 0x1000
#define ALPHA_CVG_SEL 0x2000
#define FORCE_BL 0x4000
#define TEX_EDGE 0x0000
class ZDisplayList : public ZResource
{
protected:
static TextureType TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSizes siz);
void ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, const std::string& prefix,
char* line);
void ParseF3DEX(F3DEXOpcode opcode, uint64_t data, const std::string& prefix, char* line);
// Various Instruction Optimizations
bool SequenceCheck(std::vector<F3DZEXOpcode> sequence, int32_t startIndex);
int32_t OptimizationChecks(int32_t startIndex, std::string& output, const std::string& prefix);
int32_t OptimizationCheck_LoadTextureBlock(int32_t startIndex, std::string& output,
const std::string& prefix);
// int32_t OptimizationCheck_LoadMultiBlock(int32_t startIndex, std::string& output, std::string
// prefix);
// F3DEX Specific Opcode Values
void Opcode_F3DEX_G_SETOTHERMODE_L(uint64_t data, char* line);
// Shared Opcodes between F3DZEX and F3DEX
void Opcode_G_DL(uint64_t data, const std::string& prefix, char* line);
void Opcode_G_MODIFYVTX(uint64_t data, char* line);
void Opcode_G_CULLDL(uint64_t data, char* line);
void Opcode_G_TRI1(uint64_t data, char* line);
void Opcode_G_TRI2(uint64_t data, char* line);
void Opcode_G_MTX(uint64_t data, char* line);
void Opcode_G_VTX(uint64_t data, char* line);
void Opcode_G_TEXTURE(uint64_t data, char* line);
void Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, char* line);
void Opcode_G_SETTILE(uint64_t data, char* line);
void Opcode_G_SETTILESIZE(uint64_t data, const std::string& prefix, char* line);
void Opcode_G_LOADBLOCK(uint64_t data, char* line);
void Opcode_G_SETCOMBINE(uint64_t data, char* line);
void Opcode_G_SETPRIMCOLOR(uint64_t data, char* line);
void Opcode_G_SETOTHERMODE_L(uint64_t data, char* line);
void Opcode_G_SETOTHERMODE_H(uint64_t data, char* line);
void Opcode_G_LOADTLUT(uint64_t data, const std::string& prefix, char* line);
void Opcode_G_ENDDL(const std::string& prefix, char* line);
public:
std::vector<uint64_t> instructions;
int32_t lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg;
F3DZEXTexFormats lastTexFmt;
F3DZEXTexSizes lastTexSiz, lastTexSizTest, lastCISiz;
bool lastTexLoaded;
bool lastTexIsPalette;
DListType dListType;
std::map<uint32_t, std::vector<ZVtx>> vertices;
std::vector<ZDisplayList*> otherDLists;
ZTexture* lastTexture = nullptr;
ZTexture* lastTlut = nullptr;
std::vector<segptr_t> references;
std::vector<ZMtx> mtxList;
ZDisplayList(ZFile* nParent);
~ZDisplayList();
void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override;
void ExtractFromBinary(uint32_t nRawDataIndex, int32_t rawDataSize);
void ParseRawData() override;
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetDefaultName(const std::string& prefix) const override;
void TextureGenCheck();
static bool TextureGenCheck(int32_t texWidth, int32_t texHeight, uint32_t texAddr,
uint32_t texSeg, F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz,
bool texLoaded, bool texIsPalette, ZDisplayList* self);
static int32_t GetDListLength(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex,
DListType dListType);
size_t GetRawDataSize() const override;
DeclarationAlignment GetDeclarationAlignment() const override;
void DeclareReferences(const std::string& prefix) override;
std::string ProcessLegacy(const std::string& prefix);
std::string ProcessGfxDis(const std::string& prefix);
bool IsExternalResource() const override;
std::string GetExternalExtension() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
protected:
size_t numInstructions;
};

1357
ZAPDTR/ZAPD/ZFile.cpp Normal file

File diff suppressed because it is too large Load Diff

137
ZAPDTR/ZAPD/ZFile.h Normal file
View File

@ -0,0 +1,137 @@
#pragma once
#include <string>
#include <vector>
#include "ZSymbol.h"
#include "ZTexture.h"
#include "tinyxml2.h"
enum class ZFileMode
{
BuildTexture,
BuildOverlay,
BuildBlob,
BuildSourceFile,
BuildBackground,
Extract,
ExternalFile,
Invalid,
Custom = 1000, // Used for exporter file modes
};
enum class ZGame
{
OOT_RETAIL,
OOT_SW97,
MM_RETAIL
};
class ZFile
{
public:
std::map<offset_t, Declaration*> declarations;
std::string defines;
std::vector<ZResource*> resources;
// Default to using virtual addresses
uint32_t segment = 0x80;
uint32_t baseAddress, rangeStart, rangeEnd;
bool isExternalFile = false;
ZFile(const fs::path& nOutPath, const std::string& nName);
ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBasePath,
const fs::path& nOutPath, const std::string& filename, const fs::path& nXmlFilePath);
~ZFile();
std::string GetName() const;
std::string GetOutName() const;
ZFileMode GetMode() const;
const fs::path& GetXmlFilePath() const;
const std::vector<uint8_t>& GetRawData() const;
void ExtractResources();
void BuildSourceFile();
void AddResource(ZResource* res);
ZResource* FindResource(uint32_t rawDataIndex);
std::vector<ZResource*> GetResourcesOfType(ZResourceType resType);
Declaration* AddDeclaration(offset_t address, DeclarationAlignment alignment, size_t size,
const std::string& varType, const std::string& varName,
const std::string& body);
Declaration* AddDeclarationArray(offset_t address, DeclarationAlignment alignment, size_t size,
const std::string& varType, const std::string& varName,
size_t arrayItemCnt, const std::string& body);
Declaration* AddDeclarationArray(offset_t address, DeclarationAlignment alignment, size_t size,
const std::string& varType, const std::string& varName,
const std::string& arrayItemCntStr, const std::string& body);
Declaration* AddDeclarationPlaceholder(offset_t address, const std::string& varName);
Declaration* AddDeclarationInclude(offset_t address, const std::string& includePath,
size_t size, const std::string& varType,
const std::string& varName);
Declaration* AddDeclarationIncludeArray(offset_t address, std::string& includePath, size_t size,
const std::string& varType, const std::string& varName,
size_t arrayItemCnt);
bool GetDeclarationPtrName(segptr_t segAddress, const std::string& expectedType,
std::string& declName) const;
bool GetDeclarationArrayIndexedName(segptr_t segAddress, size_t elementSize,
const std::string& expectedType,
std::string& declName) const;
Declaration* GetDeclaration(uint32_t address) const;
Declaration* GetDeclarationRanged(uint32_t address) const;
bool HasDeclaration(uint32_t address);
std::string GetHeaderInclude() const;
std::string GetZRoomHeaderInclude() const;
std::string GetExternalFileHeaderInclude() const;
void GeneratePlaceholderDeclarations();
void AddTextureResource(uint32_t offset, ZTexture* tex);
ZTexture* GetTextureResource(uint32_t offset) const;
void AddSymbolResource(uint32_t offset, ZSymbol* sym);
ZSymbol* GetSymbolResource(uint32_t offset) const;
ZSymbol* GetSymbolResourceRanged(uint32_t offset) const;
fs::path GetSourceOutputFolderPath() const;
bool IsOffsetInFileRange(uint32_t offset) const;
bool IsSegmentedInFilespaceRange(segptr_t segAddress) const;
static std::map<std::string, ZResourceFactoryFunc*>* GetNodeMap();
static void RegisterNode(std::string nodeName, ZResourceFactoryFunc* nodeFunc);
protected:
std::vector<uint8_t> rawData;
std::string name;
fs::path outName = "";
fs::path basePath;
fs::path outputPath;
fs::path xmlFilePath;
// Keep track of every texture of this ZFile.
// The pointers declared here are "borrowed" (somebody else is the owner),
// so ZFile shouldn't delete/free those textures.
std::map<uint32_t, ZTexture*> texturesResources;
std::map<uint32_t, ZSymbol*> symbolResources;
ZFileMode mode = ZFileMode::Invalid;
ZFile();
void ParseXML(tinyxml2::XMLElement* reader, const std::string& filename);
void DeclareResourceSubReferences();
void GenerateSourceFiles();
void GenerateSourceHeaderFiles();
bool AddDeclarationChecks(uint32_t address, const std::string& varName);
std::string ProcessDeclarations();
void ProcessDeclarationText(Declaration* decl);
std::string ProcessExterns();
std::string ProcessTextureIntersections(const std::string& prefix);
void HandleUnaccountedData();
bool HandleUnaccountedAddress(offset_t currentAddress, offset_t lastAddr, uint32_t& lastSize);
};

385
ZAPDTR/ZAPD/ZLimb.cpp Normal file
View File

@ -0,0 +1,385 @@
#include "ZLimb.h"
#include <cassert>
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "WarningHandler.h"
REGISTER_ZFILENODE(Limb, ZLimb);
ZLimb::ZLimb(ZFile* nParent) : ZResource(nParent), segmentStruct(nParent)
{
RegisterOptionalAttribute("LimbType");
RegisterOptionalAttribute("Type");
}
void ZLimb::ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nType)
{
rawDataIndex = nRawDataIndex;
type = nType;
// Don't parse raw data of external files
if (parent->GetMode() == ZFileMode::ExternalFile)
return;
ParseRawData();
}
void ZLimb::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
// Reading from a <Skeleton/>
std::string limbType = registeredAttributes.at("LimbType").value;
if (limbType == "") // Reading from a <Limb/>
limbType = registeredAttributes.at("Type").value;
if (limbType == "")
{
HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
"missing 'LimbType' attribute in <Limb>", "");
}
type = GetTypeByAttributeName(limbType);
if (type == ZLimbType::Invalid)
{
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
"invalid value found for 'LimbType' attribute", "");
}
}
void ZLimb::ParseRawData()
{
ZResource::ParseRawData();
const auto& rawData = parent->GetRawData();
if (type == ZLimbType::Curve)
{
childIndex = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0);
siblingIndex = BitConverter::ToUInt8BE(rawData, rawDataIndex + 1);
dListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
dList2Ptr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
return;
}
if (type == ZLimbType::Legacy)
{
dListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x00);
legTransX = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x04);
legTransY = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x08);
legTransZ = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x0C);
rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x10);
rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x12);
rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x14);
childPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x18);
siblingPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x1C);
return;
}
transX = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
transY = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
transZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
childIndex = rawData.at(rawDataIndex + 6);
siblingIndex = rawData.at(rawDataIndex + 7);
switch (type)
{
case ZLimbType::LOD:
dList2Ptr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12);
[[fallthrough]];
case ZLimbType::Standard:
dListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
break;
case ZLimbType::Skin:
skinSegmentType =
static_cast<ZLimbSkinType>(BitConverter::ToInt32BE(rawData, rawDataIndex + 8));
skinSegment = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12);
if (skinSegmentType == ZLimbSkinType::SkinType_4)
{
if (skinSegment != 0 && GETSEGNUM(skinSegment) == parent->segment)
{
uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress);
segmentStruct.ExtractFromFile(skinSegmentOffset);
}
}
break;
case ZLimbType::Curve:
case ZLimbType::Legacy:
break;
case ZLimbType::Invalid:
assert(!"whoops");
break;
}
}
void ZLimb::DeclareReferences(const std::string& prefix)
{
std::string varPrefix = name;
if (varPrefix == "")
varPrefix = prefix;
ZResource::DeclareReferences(varPrefix);
std::string suffix;
switch (type)
{
case ZLimbType::Legacy:
if (childPtr != 0 && GETSEGNUM(childPtr) == parent->segment)
{
uint32_t childOffset = Seg2Filespace(childPtr, parent->baseAddress);
if (!parent->HasDeclaration(childOffset))
{
ZLimb* child = new ZLimb(parent);
child->ExtractFromBinary(childOffset, ZLimbType::Legacy);
child->DeclareVar(varPrefix, "");
child->DeclareReferences(varPrefix);
parent->AddResource(child);
}
}
if (siblingPtr != 0 && GETSEGNUM(siblingPtr) == parent->segment)
{
uint32_t siblingdOffset = Seg2Filespace(siblingPtr, parent->baseAddress);
if (!parent->HasDeclaration(siblingdOffset))
{
ZLimb* sibling = new ZLimb(parent);
sibling->ExtractFromBinary(siblingdOffset, ZLimbType::Legacy);
sibling->DeclareVar(varPrefix, "");
sibling->DeclareReferences(varPrefix);
parent->AddResource(sibling);
}
}
break;
case ZLimbType::Curve:
case ZLimbType::LOD:
suffix = "Far";
if (type == ZLimbType::Curve)
suffix = "Curve2";
DeclareDList(dList2Ptr, varPrefix, suffix);
[[fallthrough]];
case ZLimbType::Standard:
suffix = "";
if (type == ZLimbType::Curve)
suffix = "Curve";
DeclareDList(dListPtr, varPrefix, suffix);
break;
case ZLimbType::Skin:
switch (skinSegmentType)
{
case ZLimbSkinType::SkinType_4:
if (skinSegment != 0 && GETSEGNUM(skinSegment) == parent->segment)
{
segmentStruct.DeclareReferences(varPrefix);
segmentStruct.GetSourceOutputCode(varPrefix);
}
break;
case ZLimbSkinType::SkinType_DList:
DeclareDList(skinSegment, varPrefix, "");
break;
default:
break;
}
break;
case ZLimbType::Invalid:
break;
}
}
size_t ZLimb::GetRawDataSize() const
{
switch (type)
{
case ZLimbType::Standard:
case ZLimbType::Curve:
return 0x0C;
case ZLimbType::LOD:
case ZLimbType::Skin:
return 0x10;
case ZLimbType::Legacy:
return 0x20;
case ZLimbType::Invalid:
break;
}
return 0x0C;
}
std::string ZLimb::GetBodySourceCode() const
{
std::string dListStr;
std::string dListStr2;
Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr);
Globals::Instance->GetSegmentedArrayIndexedName(dList2Ptr, 8, parent, "Gfx", dListStr2);
std::string entryStr = "\n\t";
if (type == ZLimbType::Legacy)
{
std::string childName;
std::string siblingName;
Globals::Instance->GetSegmentedPtrName(childPtr, parent, "LegacyLimb", childName);
Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "LegacyLimb", siblingName);
entryStr += StringHelper::Sprintf("%s,\n", dListStr.c_str());
entryStr +=
StringHelper::Sprintf("\t{ %ff, %ff, %ff },\n", legTransX, legTransY, legTransZ);
entryStr += StringHelper::Sprintf("\t{ 0x%04X, 0x%04X, 0x%04X },\n", rotX, rotY, rotZ);
entryStr += StringHelper::Sprintf("\t%s,\n", childName.c_str());
entryStr += StringHelper::Sprintf("\t%s\n", siblingName.c_str());
}
else
{
if (type != ZLimbType::Curve)
{
entryStr += StringHelper::Sprintf("{ %i, %i, %i }, ", transX, transY, transZ);
}
entryStr += StringHelper::Sprintf("0x%02X, 0x%02X,\n", childIndex, siblingIndex);
switch (type)
{
case ZLimbType::Standard:
entryStr += StringHelper::Sprintf("\t%s\n", dListStr.c_str());
break;
case ZLimbType::LOD:
case ZLimbType::Curve:
entryStr +=
StringHelper::Sprintf("\t{ %s, %s }\n", dListStr.c_str(), dListStr2.c_str());
break;
case ZLimbType::Skin:
{
std::string skinSegmentStr;
Globals::Instance->GetSegmentedPtrName(skinSegment, parent, "", skinSegmentStr);
entryStr +=
StringHelper::Sprintf("\t0x%02X, %s\n", skinSegmentType, skinSegmentStr.c_str());
}
break;
case ZLimbType::Legacy:
break;
case ZLimbType::Invalid:
break;
}
}
return entryStr;
}
std::string ZLimb::GetDefaultName(const std::string& prefix) const
{
return StringHelper::Sprintf("%sLimb_%06X", prefix.c_str(), rawDataIndex);
}
std::string ZLimb::GetSourceTypeName() const
{
return GetSourceTypeName(type);
}
ZResourceType ZLimb::GetResourceType() const
{
return ZResourceType::Limb;
}
ZLimbType ZLimb::GetLimbType()
{
return type;
}
void ZLimb::SetLimbType(ZLimbType value)
{
type = value;
}
const char* ZLimb::GetSourceTypeName(ZLimbType limbType)
{
switch (limbType)
{
case ZLimbType::Standard:
return "StandardLimb";
case ZLimbType::LOD:
return "LodLimb";
case ZLimbType::Skin:
return "SkinLimb";
case ZLimbType::Curve:
return "SkelCurveLimb";
case ZLimbType::Legacy:
return "LegacyLimb";
default:
return "StandardLimb";
}
}
ZLimbType ZLimb::GetTypeByAttributeName(const std::string& attrName)
{
if (attrName == "Standard")
{
return ZLimbType::Standard;
}
if (attrName == "LOD")
{
return ZLimbType::LOD;
}
if (attrName == "Skin")
{
return ZLimbType::Skin;
}
if (attrName == "Curve")
{
return ZLimbType::Curve;
}
if (attrName == "Legacy")
{
return ZLimbType::Legacy;
}
return ZLimbType::Invalid;
}
void ZLimb::DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix,
const std::string& limbSuffix)
{
if (dListSegmentedPtr == 0 || GETSEGNUM(dListSegmentedPtr) != parent->segment)
return;
uint32_t dlistOffset = Seg2Filespace(dListSegmentedPtr, parent->baseAddress);
if (parent->HasDeclaration(dlistOffset))
return;
if (!parent->IsOffsetInFileRange(dlistOffset) || dlistOffset >= parent->GetRawData().size())
return;
std::string dlistName;
bool declFound = Globals::Instance->GetSegmentedArrayIndexedName(dListSegmentedPtr, 8, parent,
"Gfx", dlistName);
if (declFound)
return;
int32_t dlistLength = ZDisplayList::GetDListLength(
parent->GetRawData(), dlistOffset,
Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX);
ZDisplayList* dlist = new ZDisplayList(parent);
dlist->ExtractFromBinary(dlistOffset, dlistLength);
std::string dListStr =
StringHelper::Sprintf("%s%sDL_%06X", prefix.c_str(), limbSuffix.c_str(), dlistOffset);
dlist->SetName(dListStr);
dlist->DeclareVar(prefix, "");
parent->AddResource(dlist);
}

65
ZAPDTR/ZAPD/ZLimb.h Normal file
View File

@ -0,0 +1,65 @@
#pragma once
#include <cstdint>
#include <string>
#include <vector>
#include "OtherStructs/SkinLimbStructs.h"
#include "ZDisplayList.h"
#include "ZFile.h"
enum class ZLimbType
{
Invalid,
Standard,
LOD,
Skin,
Curve,
Legacy,
};
class ZLimb : public ZResource
{
public:
ZLimbType type = ZLimbType::Standard;
ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only
segptr_t skinSegment = 0; // Skin only
Struct_800A5E28 segmentStruct; // Skin only
// Legacy only
float legTransX, legTransY, legTransZ; // Vec3f
uint16_t rotX, rotY, rotZ; // Vec3s
segptr_t childPtr; // LegacyLimb*
segptr_t siblingPtr; // LegacyLimb*
segptr_t dListPtr = 0;
segptr_t dList2Ptr = 0; // LOD and Curve Only
int16_t transX, transY, transZ;
uint8_t childIndex, siblingIndex;
ZLimb(ZFile* nParent);
void ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nType);
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetDefaultName(const std::string& prefix) const override;
size_t GetRawDataSize() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
ZLimbType GetLimbType();
void SetLimbType(ZLimbType value);
static const char* GetSourceTypeName(ZLimbType limbType);
static ZLimbType GetTypeByAttributeName(const std::string& attrName);
protected:
void DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix,
const std::string& limbSuffix);
};

58
ZAPDTR/ZAPD/ZMtx.cpp Normal file
View File

@ -0,0 +1,58 @@
#include "ZMtx.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Mtx, ZMtx);
ZMtx::ZMtx(ZFile* nParent) : ZResource(nParent)
{
}
void ZMtx::ParseRawData()
{
ZResource::ParseRawData();
const auto& rawData = parent->GetRawData();
for (size_t i = 0; i < 4; ++i)
for (size_t j = 0; j < 4; ++j)
mtx[i][j] = BitConverter::ToInt32BE(rawData, rawDataIndex + (i * 4 + j) * 4);
}
size_t ZMtx::GetRawDataSize() const
{
return 64;
}
std::string ZMtx::GetBodySourceCode() const
{
std::string bodyStr = "\n";
for (const auto& row : mtx)
{
bodyStr += " ";
for (int32_t val : row)
bodyStr += StringHelper::Sprintf("%-11i, ", val);
bodyStr += "\n";
}
return bodyStr;
}
std::string ZMtx::GetSourceTypeName() const
{
return "Mtx";
}
ZResourceType ZMtx::GetResourceType() const
{
return ZResourceType::Mtx;
}
DeclarationAlignment ZMtx::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align8;
}

24
ZAPDTR/ZAPD/ZMtx.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include <array>
#include <cstdint>
#include "ZResource.h"
class ZMtx : public ZResource
{
public:
ZMtx(ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
DeclarationAlignment GetDeclarationAlignment() const override;
public:
std::array<std::array<int32_t, 4>, 4> mtx;
};

209
ZAPDTR/ZAPD/ZPath.cpp Normal file
View File

@ -0,0 +1,209 @@
#include "ZPath.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
REGISTER_ZFILENODE(Path, ZPath);
ZPath::ZPath(ZFile* nParent) : ZResource(nParent)
{
numPaths = 1;
RegisterOptionalAttribute("NumPaths", "1");
}
void ZPath::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
numPaths = StringHelper::StrToL(registeredAttributes.at("NumPaths").value);
if (numPaths < 1)
{
HANDLE_ERROR_RESOURCE(
WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
StringHelper::Sprintf("invalid value '%d' found for 'NumPaths' attribute", numPaths),
"Should be at least '1'");
}
}
void ZPath::ParseRawData()
{
ZResource::ParseRawData();
uint32_t currentPtr = rawDataIndex;
for (size_t pathIndex = 0; pathIndex < numPaths; pathIndex++)
{
PathwayEntry path(parent);
path.ExtractFromFile(currentPtr);
if (path.GetListAddress() == 0)
break;
currentPtr += path.GetRawDataSize();
pathways.push_back(path);
}
}
void ZPath::DeclareReferences(const std::string& prefix)
{
ZResource::DeclareReferences(prefix);
for (auto& entry : pathways)
entry.DeclareReferences(prefix);
}
Declaration* ZPath::DeclareVar(const std::string& prefix, const std::string& bodyStr)
{
std::string auxName = name;
if (name == "")
auxName = GetDefaultName(prefix);
Declaration* decl =
parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(),
GetSourceTypeName(), name, pathways.size(), bodyStr);
decl->staticConf = staticConf;
return decl;
}
std::string ZPath::GetBodySourceCode() const
{
std::string declaration;
size_t index = 0;
for (const auto& entry : pathways)
{
declaration += StringHelper::Sprintf("\t{ %s },", entry.GetBodySourceCode().c_str());
if (index < pathways.size() - 1)
declaration += "\n";
index++;
}
return declaration;
}
std::string ZPath::GetSourceTypeName() const
{
return "Path";
}
ZResourceType ZPath::GetResourceType() const
{
return ZResourceType::Path;
}
size_t ZPath::GetRawDataSize() const
{
return pathways.size() * pathways.at(0).GetRawDataSize();
}
void ZPath::SetNumPaths(uint32_t nNumPaths)
{
numPaths = nNumPaths;
}
/* PathwayEntry */
PathwayEntry::PathwayEntry(ZFile* nParent) : ZResource(nParent)
{
}
void PathwayEntry::ParseRawData()
{
ZResource::ParseRawData();
auto parentRawData = parent->GetRawData();
numPoints = parentRawData.at(rawDataIndex + 0);
unk1 = parentRawData.at(rawDataIndex + 1);
unk2 = BitConverter::ToInt16BE(parentRawData, rawDataIndex + 2);
listSegmentAddress = BitConverter::ToInt32BE(parentRawData, rawDataIndex + 4);
uint32_t currentPtr = GETSEGOFFSET(listSegmentAddress);
for (int32_t i = 0; i < numPoints; i++)
{
ZVector vec(parent);
vec.ExtractFromBinary(currentPtr, ZScalarType::ZSCALAR_S16, 3);
currentPtr += vec.GetRawDataSize();
points.push_back(vec);
}
}
void PathwayEntry::DeclareReferences(const std::string& prefix)
{
ZResource::DeclareReferences(prefix);
if (points.empty())
return;
std::string pointsName;
bool addressFound =
Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", pointsName);
if (addressFound)
return;
std::string declaration = "";
size_t index = 0;
for (const auto& point : points)
{
declaration += StringHelper::Sprintf("\t{ %s },", point.GetBodySourceCode().c_str());
if (index < points.size() - 1)
declaration += "\n";
index++;
}
uint32_t pointsOffset = Seg2Filespace(listSegmentAddress, parent->baseAddress);
Declaration* decl = parent->GetDeclaration(pointsOffset);
if (decl == nullptr)
{
pointsName = StringHelper::Sprintf("%sPathwayList_%06X", prefix.c_str(), pointsOffset);
parent->AddDeclarationArray(pointsOffset, points.at(0).GetDeclarationAlignment(),
points.size() * 6, points.at(0).GetSourceTypeName(), pointsName,
points.size(), declaration);
}
else
decl->text = declaration;
}
std::string PathwayEntry::GetBodySourceCode() const
{
std::string declaration;
std::string listName;
Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", listName);
if (Globals::Instance->game == ZGame::MM_RETAIL)
declaration +=
StringHelper::Sprintf("%i, %i, %i, %s", numPoints, unk1, unk2, listName.c_str());
else
declaration += StringHelper::Sprintf("%i, %s", numPoints, listName.c_str());
return declaration;
}
std::string PathwayEntry::GetSourceTypeName() const
{
return "Path";
}
ZResourceType PathwayEntry::GetResourceType() const
{
return ZResourceType::Path;
}
size_t PathwayEntry::GetRawDataSize() const
{
return 0x08;
}
segptr_t PathwayEntry::GetListAddress() const
{
return listSegmentAddress;
}

51
ZAPDTR/ZAPD/ZPath.h Normal file
View File

@ -0,0 +1,51 @@
#pragma once
#include "ZResource.h"
#include "ZVector.h"
class PathwayEntry : public ZResource
{
public:
PathwayEntry(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
segptr_t GetListAddress() const;
public:
int32_t numPoints;
int8_t unk1; // (MM Only)
int16_t unk2; // (MM Only)
segptr_t listSegmentAddress;
std::vector<ZVector> points;
};
class ZPath : public ZResource
{
public:
ZPath(ZFile* nParent);
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
void SetNumPaths(uint32_t nNumPaths);
public:
uint32_t numPaths;
std::vector<PathwayEntry> pathways;
};

View File

@ -0,0 +1,97 @@
#include "ZPlayerAnimationData.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
REGISTER_ZFILENODE(PlayerAnimationData, ZPlayerAnimationData);
ZPlayerAnimationData::ZPlayerAnimationData(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("FrameCount");
}
void ZPlayerAnimationData::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
std::string& frameCountXml = registeredAttributes.at("FrameCount").value;
frameCount = StringHelper::StrToL(frameCountXml);
}
void ZPlayerAnimationData::ParseRawData()
{
ZResource::ParseRawData();
const auto& rawData = parent->GetRawData();
size_t totalSize = GetRawDataSize();
// Divided by 2 because each value is an s16
limbRotData.reserve(totalSize * frameCount / 2);
for (size_t i = 0; i < totalSize; i += 2)
{
limbRotData.push_back(BitConverter::ToUInt16BE(rawData, rawDataIndex + i));
}
}
Declaration* ZPlayerAnimationData::DeclareVar(const std::string& prefix, const std::string& bodyStr)
{
std::string auxName = name;
if (auxName == "")
auxName = GetDefaultName(prefix);
Declaration* decl =
parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(),
GetSourceTypeName(), name, limbRotData.size(), bodyStr);
decl->staticConf = staticConf;
return decl;
}
std::string ZPlayerAnimationData::GetBodySourceCode() const
{
std::string declaration = "";
size_t index = 0;
for (const auto& entry : limbRotData)
{
if (index % 8 == 0)
{
declaration += "\t";
}
declaration += StringHelper::Sprintf("0x%04X, ", entry);
if ((index + 1) % 8 == 0)
{
declaration += "\n";
}
index++;
}
return declaration;
}
std::string ZPlayerAnimationData::GetDefaultName(const std::string& prefix) const
{
return StringHelper::Sprintf("%sPlayerAnimationData_%06X", prefix.c_str(), rawDataIndex);
}
std::string ZPlayerAnimationData::GetSourceTypeName() const
{
return "s16";
}
ZResourceType ZPlayerAnimationData::GetResourceType() const
{
return ZResourceType::PlayerAnimationData;
}
size_t ZPlayerAnimationData::GetRawDataSize() const
{
// (sizeof(Vec3s) * limbCount + 2) * frameCount
return (6 * 22 + 2) * frameCount;
}

View File

@ -0,0 +1,28 @@
#pragma once
#include <cstdint>
#include <vector>
#include "ZResource.h"
class ZPlayerAnimationData : public ZResource
{
public:
int16_t frameCount = 0;
std::vector<uint16_t> limbRotData;
ZPlayerAnimationData(ZFile* nParent);
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
std::string GetBodySourceCode() const override;
std::string GetDefaultName(const std::string& prefix) const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
};

380
ZAPDTR/ZAPD/ZResource.cpp Normal file
View File

@ -0,0 +1,380 @@
#include "ZResource.h"
#include <cassert>
#include <regex>
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"
#include <Globals.h>
#include <ZDisplayList.h>
ZResource::ZResource(ZFile* nParent)
{
// assert(nParent != nullptr);
parent = nParent;
name = "";
outName = "";
sourceOutput = "";
rawDataIndex = 0;
outputDeclaration = true;
RegisterRequiredAttribute("Name");
RegisterOptionalAttribute("OutName");
RegisterOptionalAttribute("Offset");
RegisterOptionalAttribute("Custom");
RegisterOptionalAttribute("Static", "Global");
}
void ZResource::ExtractFromXML(tinyxml2::XMLElement* reader, offset_t nRawDataIndex)
{
rawDataIndex = nRawDataIndex;
declaredInXml = true;
if (reader != nullptr)
ParseXML(reader);
// Don't parse raw data of external files
if (parent->GetMode() != ZFileMode::ExternalFile)
{
ParseRawData();
CalcHash();
}
if (!isInner)
{
Declaration* decl = DeclareVar(parent->GetName(), "");
if (decl != nullptr)
{
decl->declaredInXml = true;
decl->staticConf = staticConf;
}
}
}
void ZResource::ExtractFromFile(offset_t nRawDataIndex)
{
rawDataIndex = nRawDataIndex;
// Don't parse raw data of external files
if (parent->GetMode() == ZFileMode::ExternalFile)
return;
ParseRawData();
CalcHash();
}
void ZResource::ParseXML(tinyxml2::XMLElement* reader)
{
if (reader != nullptr)
{
// If it is an inner node, then 'Name' isn't required
if (isInner)
{
registeredAttributes.at("Name").isRequired = false;
}
auto attrs = reader->FirstAttribute();
while (attrs != nullptr)
{
std::string attrName = attrs->Name();
bool attrDeclared = false;
if (registeredAttributes.find(attrName) != registeredAttributes.end())
{
registeredAttributes[attrName].value = attrs->Value();
registeredAttributes[attrName].wasSet = true;
attrDeclared = true;
}
if (!attrDeclared)
{
HANDLE_WARNING_RESOURCE(
WarningType::UnknownAttribute, parent, this, rawDataIndex,
StringHelper::Sprintf("unexpected '%s' attribute in resource <%s>",
attrName.c_str(), reader->Name()),
"");
}
attrs = attrs->Next();
}
if (!canHaveInner && !reader->NoChildren())
{
std::string errorHeader = StringHelper::Sprintf(
"resource '%s' with inner element/child detected", reader->Name());
HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, "");
}
for (const auto& attr : registeredAttributes)
{
if (attr.second.isRequired && attr.second.value == "")
{
std::string headerMsg =
StringHelper::Sprintf("missing required attribute '%s' in resource <%s>",
attr.first.c_str(), reader->Name());
HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex,
headerMsg, "");
}
}
name = registeredAttributes.at("Name").value;
static std::regex r("[a-zA-Z_]+[a-zA-Z0-9_]*", std::regex::icase | std::regex::optimize);
if (!isInner || (isInner && name != ""))
{
if (!std::regex_match(name, r))
{
HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this,
rawDataIndex, "invalid value found for 'Name' attribute", "");
}
}
outName = registeredAttributes.at("OutName").value;
if (outName == "")
outName = name;
isCustomAsset = registeredAttributes["Custom"].wasSet;
std::string& staticXml = registeredAttributes["Static"].value;
if (staticXml == "Global")
{
staticConf = StaticConfig::Global;
}
else if (staticXml == "On")
{
staticConf = StaticConfig::On;
}
else if (staticXml == "Off")
{
staticConf = StaticConfig::Off;
}
else
{
HANDLE_ERROR_RESOURCE(
WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
StringHelper::Sprintf("invalid value '%s' for 'Static' attribute", staticConf), "");
}
declaredInXml = true;
}
}
void ZResource::ParseRawData()
{
}
void ZResource::DeclareReferences([[maybe_unused]] const std::string& prefix)
{
}
void ZResource::ParseRawDataLate()
{
}
void ZResource::DeclareReferencesLate([[maybe_unused]] const std::string& prefix)
{
}
Declaration* ZResource::DeclareVar(const std::string& prefix, const std::string& bodyStr)
{
std::string auxName = name;
if (name == "")
auxName = GetDefaultName(prefix);
Declaration* decl =
parent->AddDeclaration(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(),
GetSourceTypeName(), auxName, bodyStr);
decl->staticConf = staticConf;
return decl;
}
void ZResource::Save([[maybe_unused]] const fs::path& outFolder)
{
}
const std::string& ZResource::GetName() const
{
return name;
}
const std::string& ZResource::GetOutName() const
{
return outName;
}
void ZResource::SetOutName(const std::string& nName)
{
outName = nName;
}
void ZResource::SetName(const std::string& nName)
{
name = nName;
}
bool ZResource::IsExternalResource() const
{
return false;
}
bool ZResource::DoesSupportArray() const
{
return false;
}
std::string ZResource::GetExternalExtension() const
{
return "";
}
DeclarationAlignment ZResource::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align4;
}
bool ZResource::WasDeclaredInXml() const
{
return declaredInXml;
}
StaticConfig ZResource::GetStaticConf() const
{
return staticConf;
}
offset_t ZResource::GetRawDataIndex() const
{
return rawDataIndex;
}
std::string ZResource::GetBodySourceCode() const
{
return "ERROR";
}
std::string ZResource::GetDefaultName(const std::string& prefix) const
{
return StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), GetSourceTypeName().c_str(),
rawDataIndex);
}
void ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix)
{
std::string bodyStr = GetBodySourceCode();
if (bodyStr != "ERROR")
{
Declaration* decl = parent->GetDeclaration(rawDataIndex);
if (decl == nullptr || decl->isPlaceholder)
decl = DeclareVar(prefix, bodyStr);
else
decl->text = bodyStr;
if (decl != nullptr)
decl->staticConf = staticConf;
}
}
std::string ZResource::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix)
{
if (Globals::Instance->otrMode && genOTRDef)
{
std::string str = "";;
std::string nameStr = StringHelper::Strip(StringHelper::Strip(name, "\n"), "\r");
std::string outName = parent->GetOutName();
std::string prefix = "";
if (GetResourceType() == ZResourceType::DisplayList || GetResourceType() == ZResourceType::Texture)
{
//ZDisplayList* dList = (ZDisplayList*)this;
if (StringHelper::Contains(outName, "_room_"))
{
outName = StringHelper::Split(outName, "_room")[0] + "_scene";
}
}
std::string xmlPath = StringHelper::Replace(parent->GetXmlFilePath().string(), "\\", "/");
if (StringHelper::Contains(outName, "_room_") || StringHelper::Contains(outName, "_scene"))
prefix = "scenes";
else if (StringHelper::Contains(xmlPath, "objects/"))
prefix = "objects";
else if (StringHelper::Contains(xmlPath, "textures/"))
prefix = "textures";
else if (StringHelper::Contains(xmlPath, "overlays/"))
prefix = "overlays";
else if (StringHelper::Contains(xmlPath, "misc/"))
prefix = "misc";
else if (StringHelper::Contains(xmlPath, "code/"))
prefix = "code";
else if (StringHelper::Contains(xmlPath, "text/"))
prefix = "text";
if (prefix != "")
str += StringHelper::Sprintf("#define %s \"__OTR__%s/%s/%s\"", name.c_str(), prefix.c_str(), outName.c_str(), nameStr.c_str());
else
str += StringHelper::Sprintf("#define %s \"__OTR__%s/%s\"", name.c_str(), outName.c_str(), nameStr.c_str());
return str;
}
else
return "";
}
ZResourceType ZResource::GetResourceType() const
{
return ZResourceType::Error;
}
void ZResource::CalcHash()
{
hash = 0;
}
void ZResource::SetInnerNode(bool inner)
{
isInner = inner;
}
void ZResource::RegisterRequiredAttribute(const std::string& attr)
{
ResourceAttribute resAtrr;
resAtrr.key = attr;
resAtrr.isRequired = true;
registeredAttributes[attr] = resAtrr;
}
void ZResource::RegisterOptionalAttribute(const std::string& attr, const std::string& defaultValue)
{
ResourceAttribute resAtrr;
resAtrr.key = attr;
resAtrr.value = defaultValue;
registeredAttributes[attr] = resAtrr;
}
offset_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress)
{
offset_t currentPtr = GETSEGOFFSET(segmentedAddress);
if (GETSEGNUM(segmentedAddress) == 0x80) // Is defined in code?
{
uint32_t parentBaseOffset = GETSEGOFFSET(parentBaseAddress);
if (parentBaseOffset > currentPtr)
{
HANDLE_ERROR(WarningType::Always,
StringHelper::Sprintf(
"resource address 0x%08X is smaller than 'BaseAddress' 0x%08X",
segmentedAddress, parentBaseAddress),
"Maybe your 'BaseAddress' is wrong?");
}
currentPtr -= parentBaseOffset;
}
return currentPtr;
}

244
ZAPDTR/ZAPD/ZResource.h Normal file
View File

@ -0,0 +1,244 @@
#pragma once
#include <cstdint>
#include <map>
#include <stdexcept>
#include <string>
#include <vector>
#include "Declaration.h"
#include "Utils/BinaryWriter.h"
#include "Utils/Directory.h"
#include "tinyxml2.h"
#define SEGMENT_SCENE 2
#define SEGMENT_ROOM 3
#define SEGMENT_KEEP 4
#define SEGMENT_FIELDDANGEON_KEEP 5
#define SEGMENT_OBJECT 6
#define SEGMENT_LINKANIMETION 7
#define GETSEGOFFSET(x) (x & 0x00FFFFFF)
#define GETSEGNUM(x) ((x >> 24) & 0xFF)
class ZFile;
enum class ZResourceType
{
Error,
Animation,
Array,
AltHeader,
Background,
Blob,
CollisionHeader,
Cutscene,
DisplayList,
Limb,
LimbTable,
Mtx,
Path,
PlayerAnimationData,
Room,
RoomCommand,
Scalar,
Scene,
Skeleton,
String,
Symbol,
Texture,
TextureAnimation,
TextureAnimationParams,
Vector,
Vertex,
Text
};
class ResourceAttribute
{
public:
std::string key;
std::string value;
bool isRequired = false;
bool wasSet = false;
};
class ZResource
{
public:
ZFile* parent;
bool outputDeclaration = true;
uint32_t hash = 0;
bool genOTRDef = false;
/**
* Constructor.
* Child classes should not declare any other constructor besides this one
*/
ZResource(ZFile* nParent);
virtual ~ZResource() = default;
// Parsing from File
virtual void ExtractFromXML(tinyxml2::XMLElement* reader, offset_t nRawDataIndex);
virtual void ExtractFromFile(offset_t nRawDataIndex);
// Misc
/**
* Parses additional attributes of the XML node.
* Extra attritbutes have to be registered using `RegisterRequiredAttribute` or
* `RegisterOptionalAttribute` in the constructor of the ZResource
*/
virtual void ParseXML(tinyxml2::XMLElement* reader);
/**
* Extracts data from the binary file
*/
virtual void ParseRawData();
/**
* Declares any data pointed by this resource that has not been declared already.
* For example, a Vtx referenced by a Dlist should be declared here if it wasn't
* declared previously by something else
*/
virtual void DeclareReferences(const std::string& prefix);
virtual void ParseRawDataLate();
virtual void DeclareReferencesLate(const std::string& prefix);
/**
* Adds this resource as a Declaration of its parent ZFile
*/
virtual Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr);
/**
* Returns the body of the variable of the extracted resource, without any side-effect
*/
[[nodiscard]] virtual std::string GetBodySourceCode() const;
/**
* Creates an automatically generated variable name for the current resource
*/
[[nodiscard]] virtual std::string GetDefaultName(const std::string& prefix) const;
virtual void GetSourceOutputCode(const std::string& prefix);
virtual std::string GetSourceOutputHeader(const std::string& prefix);
virtual void CalcHash();
/**
* Exports the resource to binary format
*/
virtual void Save(const fs::path& outFolder);
// Properties
/**
* Returns true if the resource will be externalized, and included back to the C file using
* `#include`s
*/
virtual bool IsExternalResource() const;
/**
* Can this type be wrapped in an <Array> node?
*/
virtual bool DoesSupportArray() const;
/**
* The type of the resource as a C struct
*/
[[nodiscard]] virtual std::string GetSourceTypeName() const = 0;
/**
* The type in the ZResource enum
*/
[[nodiscard]] virtual ZResourceType GetResourceType() const = 0;
/**
* The filename extension for assets extracted as standalone files
*/
[[nodiscard]] virtual std::string GetExternalExtension() const;
// Getters/Setters
[[nodiscard]] const std::string& GetName() const;
void SetName(const std::string& nName);
[[nodiscard]] const std::string& GetOutName() const;
void SetOutName(const std::string& nName);
[[nodiscard]] offset_t GetRawDataIndex() const;
/**
* The size of the current struct being extracted, not counting data referenced by it
*/
[[nodiscard]] virtual size_t GetRawDataSize() const = 0;
/**
* The alignment of the extracted struct
*/
[[nodiscard]] virtual DeclarationAlignment GetDeclarationAlignment() const;
void SetInnerNode(bool inner);
/**
* Returns `true` if this ZResource was declared using an XML node,
* `false` otherwise (for example, a Vtx extracted indirectly by a DList)
*/
[[nodiscard]] bool WasDeclaredInXml() const;
[[nodiscard]] StaticConfig GetStaticConf() const;
protected:
std::string name;
std::string outName;
offset_t rawDataIndex;
std::string sourceOutput;
// Inner is used mostly for <Array> nodes
/**
* Is this resource an inner node of another resource?
* (namely inside an <Array>)
*/
bool isInner = false;
/**
* Can this type have an inner node?
*/
bool canHaveInner = false;
/**
* If set to true, create a reference for the asset in the file, but don't
* actually try to extract it from the file
*/
bool isCustomAsset;
bool declaredInXml = false;
StaticConfig staticConf = StaticConfig::Global;
// Reading from this XMLs attributes should be performed in the overrided `ParseXML` method.
std::map<std::string, ResourceAttribute> registeredAttributes;
// XML attributes registers.
// Registering XML attributes should be done in constructors.
// The resource needs this attribute. If it is not provided, then the program will throw an
// exception.
void RegisterRequiredAttribute(const std::string& attr);
// Optional attribute. The resource has to do manual checks and manual warnings. It may or may
// not have a value.
void RegisterOptionalAttribute(const std::string& attr, const std::string& defaultValue = "");
};
class ZResourceExporter
{
public:
ZResourceExporter() = default;
virtual ~ZResourceExporter() = default;
virtual void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) = 0;
};
offset_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress);
typedef ZResource*(ZResourceFactoryFunc)(ZFile* nParent);
#define REGISTER_ZFILENODE(nodeName, zResClass) \
static ZResource* ZResourceFactory_##zResClass_##nodeName(ZFile* nParent) \
{ \
return static_cast<ZResource*>(new zResClass(nParent)); \
} \
\
class ZRes_##nodeName \
{ \
public: \
ZRes_##nodeName() \
{ \
ZFile::RegisterNode(#nodeName, &ZResourceFactory_##zResClass_##nodeName); \
} \
}; \
static ZRes_##nodeName inst_ZRes_##nodeName
#define REGISTER_EXPORTER(expFunc) \
class ZResExp_##expFunc \
{ \
public: \
ZResExp_##expFunc() { expFunc(); } \
}; \
static ZResExp_##expFunc inst_ZResExp_##expFunc

View File

@ -0,0 +1,20 @@
#include "EndMarker.h"
EndMarker::EndMarker(ZFile* nParent) : ZRoomCommand(nParent)
{
}
std::string EndMarker::GetBodySourceCode() const
{
return "SCENE_CMD_END()";
}
std::string EndMarker::GetCommandCName() const
{
return "SCmdEndMarker";
}
RoomCommand EndMarker::GetRoomCommand() const
{
return RoomCommand::EndMarker;
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class EndMarker : public ZRoomCommand
{
public:
EndMarker(ZFile* nParent);
std::string GetBodySourceCode() const override;
std::string GetCommandCName() const override;
RoomCommand GetRoomCommand() const override;
};

View File

@ -0,0 +1,93 @@
#include "SetActorCutsceneList.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetActorCutsceneList::SetActorCutsceneList(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetActorCutsceneList::ParseRawData()
{
ZRoomCommand::ParseRawData();
int numCutscenes = cmdArg1;
int32_t currentPtr = segmentOffset;
for (int32_t i = 0; i < numCutscenes; i++)
{
ActorCutsceneEntry entry(parent->GetRawData(), currentPtr);
cutscenes.push_back(entry);
currentPtr += 16;
}
}
void SetActorCutsceneList::DeclareReferences(const std::string& prefix)
{
if (cutscenes.size() > 0)
{
std::string declaration;
for (size_t i = 0; i < cutscenes.size(); i++)
{
const auto& entry = cutscenes.at(i);
declaration += StringHelper::Sprintf(" { %s },", entry.GetBodySourceCode().c_str());
if (i + 1 < cutscenes.size())
{
declaration += "\n";
}
}
std::string typeName = cutscenes.at(0).GetSourceTypeName();
parent->AddDeclarationArray(
segmentOffset, GetDeclarationAlignment(), cutscenes.size() * 16, typeName,
StringHelper::Sprintf("%s%sList_%06X", prefix.c_str(), typeName.c_str(), segmentOffset),
cutscenes.size(), declaration);
}
}
std::string SetActorCutsceneList::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorCutscene", listName);
return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_LIST(%i, %s)", cutscenes.size(),
listName.c_str());
}
std::string SetActorCutsceneList::GetCommandCName() const
{
return "SCmdCutsceneActorList";
}
RoomCommand SetActorCutsceneList::GetRoomCommand() const
{
return RoomCommand::SetActorCutsceneList;
}
ActorCutsceneEntry::ActorCutsceneEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
: priority(BitConverter::ToInt16BE(rawData, rawDataIndex + 0)),
length(BitConverter::ToInt16BE(rawData, rawDataIndex + 2)),
unk4(BitConverter::ToInt16BE(rawData, rawDataIndex + 4)),
unk6(BitConverter::ToInt16BE(rawData, rawDataIndex + 6)),
additionalCutscene(BitConverter::ToInt16BE(rawData, rawDataIndex + 8)),
sound(rawData[rawDataIndex + 0xA]), unkB(rawData[rawDataIndex + 0xB]),
unkC(BitConverter::ToInt16BE(rawData, rawDataIndex + 0xC)), unkE(rawData[rawDataIndex + 0xE]),
letterboxSize(rawData[rawDataIndex + 0xF])
{
}
std::string ActorCutsceneEntry::GetBodySourceCode() const
{
return StringHelper::Sprintf("%i, %i, %i, %i, %i, %i, %i, %i, %i, %i", priority, length, unk4,
unk6, additionalCutscene, sound, unkB, unkC, unkE, letterboxSize);
}
std::string ActorCutsceneEntry::GetSourceTypeName() const
{
return "ActorCutscene";
}

View File

@ -0,0 +1,42 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class ActorCutsceneEntry
{
protected:
int16_t priority;
int16_t length;
int16_t unk4;
int16_t unk6;
int16_t additionalCutscene;
uint8_t sound;
uint8_t unkB;
int16_t unkC;
uint8_t unkE;
uint8_t letterboxSize;
public:
ActorCutsceneEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
std::string GetSourceTypeName() const;
};
class SetActorCutsceneList : public ZRoomCommand
{
public:
std::vector<ActorCutsceneEntry> cutscenes;
SetActorCutsceneList(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetCommandCName() const override;
RoomCommand GetRoomCommand() const override;
private:
};

View File

@ -0,0 +1,179 @@
#include "SetActorList.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZNames.h"
#include "ZRoom/ZRoom.h"
SetActorList::SetActorList(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetActorList::ParseRawData()
{
ZRoomCommand::ParseRawData();
numActors = cmdArg1;
}
void SetActorList::DeclareReferences(const std::string& prefix)
{
if (numActors != 0 && cmdArg2 != 0)
{
std::string varName =
StringHelper::Sprintf("%sActorList_%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationPlaceholder(segmentOffset, varName);
}
}
void SetActorList::ParseRawDataLate()
{
ZRoomCommand::ParseRawDataLate();
size_t actorsAmount = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 0x10;
uint32_t currentPtr = segmentOffset;
for (size_t i = 0; i < actorsAmount; i++)
{
ActorSpawnEntry entry(parent->GetRawData(), currentPtr);
currentPtr += entry.GetRawDataSize();
actors.push_back(entry);
}
}
void SetActorList::DeclareReferencesLate(const std::string& prefix)
{
if (actors.empty())
return;
std::string declaration;
size_t largestlength = 0;
for (const auto& entry : actors)
{
size_t actorNameLength = ZNames::GetActorName(entry.GetActorId()).size();
if (actorNameLength > largestlength)
largestlength = actorNameLength;
}
size_t index = 0;
for (auto& entry : actors)
{
entry.SetLargestActorName(largestlength);
declaration += StringHelper::Sprintf("\t{ %s },", entry.GetBodySourceCode().c_str());
if (index < actors.size() - 1)
declaration += "\n";
index++;
}
const auto& entry = actors.front();
std::string varName = StringHelper::Sprintf("%sActorList_%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4,
actors.size() * entry.GetRawDataSize(), entry.GetSourceTypeName(),
varName, GetActorListArraySize(), declaration);
}
std::string SetActorList::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName);
if (numActors != actors.size())
{
printf("%s: numActors(%i) ~ actors(%li)\n", parent->GetName().c_str(), numActors,
actors.size());
}
return StringHelper::Sprintf("SCENE_CMD_ACTOR_LIST(%i, %s)", numActors, listName.c_str());
}
size_t SetActorList::GetActorListArraySize() const
{
size_t actorCount = 0;
// Doing an else-if here so we only do the loop when the game is SW97.
// Actor 0x22 is removed from SW97, so we need to ensure that we don't increment the actor count
// for it.
if (Globals::Instance->game == ZGame::OOT_SW97)
{
actorCount = 0;
for (const auto& entry : actors)
if (entry.GetActorId() != 0x22)
actorCount++;
}
else
{
actorCount = actors.size();
}
return actorCount;
}
std::string SetActorList::GetCommandCName() const
{
return "SCmdActorList";
}
RoomCommand SetActorList::GetRoomCommand() const
{
return RoomCommand::SetActorList;
}
ActorSpawnEntry::ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
{
actorNum = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 8);
rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 10);
rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 12);
initVar = BitConverter::ToInt16BE(rawData, rawDataIndex + 14);
}
std::string ActorSpawnEntry::GetBodySourceCode() const
{
std::string body;
std::string actorNameFmt = StringHelper::Sprintf("%%-%zus ", largestActorName + 1);
body =
StringHelper::Sprintf(actorNameFmt.c_str(), (ZNames::GetActorName(actorNum) + ",").c_str());
body += StringHelper::Sprintf("{ %6i, %6i, %6i }, ", posX, posY, posZ);
if (Globals::Instance->game == ZGame::MM_RETAIL)
body += StringHelper::Sprintf("{ SPAWN_ROT_FLAGS(%#5hX, 0x%04X)"
", SPAWN_ROT_FLAGS(%#5hX, 0x%04X)"
", SPAWN_ROT_FLAGS(%#5hX, 0x%04X) }, ",
(rotX >> 7) & 0b111111111, rotX & 0b1111111,
(rotY >> 7) & 0b111111111, rotY & 0b1111111,
(rotZ >> 7) & 0b111111111, rotZ & 0b1111111);
else
body += StringHelper::Sprintf("{ %#6hX, %#6hX, %#6hX }, ", rotX, rotY, rotZ);
body += StringHelper::Sprintf("0x%04X", initVar);
return body;
}
std::string ActorSpawnEntry::GetSourceTypeName() const
{
return "ActorEntry";
}
int32_t ActorSpawnEntry::GetRawDataSize() const
{
return 16;
}
uint16_t ActorSpawnEntry::GetActorId() const
{
return actorNum;
}
void ActorSpawnEntry::SetLargestActorName(size_t nameSize)
{
largestActorName = nameSize;
}

View File

@ -0,0 +1,50 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class ActorSpawnEntry
{
public:
uint16_t actorNum;
int16_t posX;
int16_t posY;
int16_t posZ;
uint16_t rotX;
uint16_t rotY;
uint16_t rotZ;
uint16_t initVar;
size_t largestActorName = 16;
ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
std::string GetSourceTypeName() const;
int32_t GetRawDataSize() const;
uint16_t GetActorId() const;
void SetLargestActorName(size_t nameSize);
};
class SetActorList : public ZRoomCommand
{
public:
uint8_t numActors;
std::vector<ActorSpawnEntry> actors;
SetActorList(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
void ParseRawDataLate() override;
void DeclareReferencesLate(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
protected:
size_t GetActorListArraySize() const;
};

View File

@ -0,0 +1,81 @@
#include "SetAlternateHeaders.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
SetAlternateHeaders::SetAlternateHeaders(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetAlternateHeaders::DeclareReferences([[maybe_unused]] const std::string& prefix)
{
if (cmdArg2 != 0)
{
std::string varName =
StringHelper::Sprintf("%sAlternateHeaders0x%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationPlaceholder(segmentOffset, varName);
}
}
void SetAlternateHeaders::ParseRawDataLate()
{
int numHeaders = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 4;
for (int32_t i = 0; i < numHeaders; i++)
{
int32_t address = BitConverter::ToInt32BE(parent->GetRawData(), segmentOffset + (i * 4));
headers.push_back(address);
if (address != 0 && parent->GetDeclaration(GETSEGOFFSET(address)) == nullptr)
{
ZRoom* altheader = new ZRoom(parent);
altheader->ExtractFromBinary(GETSEGOFFSET(address), zRoom->GetResourceType());
altheader->DeclareReferences(parent->GetName());
parent->resources.push_back(altheader);
}
}
}
void SetAlternateHeaders::DeclareReferencesLate(const std::string& prefix)
{
if (!headers.empty())
{
std::string declaration;
for (size_t i = 0; i < headers.size(); i++)
{
std::string altHeaderName;
Globals::Instance->GetSegmentedPtrName(headers.at(i), parent, "", altHeaderName);
declaration += StringHelper::Sprintf("\t%s,", altHeaderName.c_str());
if (i + 1 < headers.size())
declaration += "\n";
}
std::string varName =
StringHelper::Sprintf("%sAlternateHeaders0x%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationArray(segmentOffset, GetDeclarationAlignment(), headers.size() * 4,
"SceneCmd*", varName, headers.size(), declaration);
}
}
std::string SetAlternateHeaders::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "SceneCmd*", listName);
return StringHelper::Sprintf("SCENE_CMD_ALTERNATE_HEADER_LIST(%s)", listName.c_str());
}
std::string SetAlternateHeaders::GetCommandCName() const
{
return "SCmdAltHeaders";
}
RoomCommand SetAlternateHeaders::GetRoomCommand() const
{
return RoomCommand::SetAlternateHeaders;
}

View File

@ -0,0 +1,23 @@
#pragma once
#include "ZRoom/ZRoom.h"
#include "ZRoom/ZRoomCommand.h"
class SetAlternateHeaders : public ZRoomCommand
{
public:
std::vector<uint32_t> headers;
SetAlternateHeaders(ZFile* nParent);
void DeclareReferences(const std::string& prefix) override;
void ParseRawDataLate() override;
void DeclareReferencesLate(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
private:
};

View File

@ -0,0 +1,48 @@
/**
* File: SetAnimatedMaterialList.cpp
* Description: Defines a class SetAnimatedMaterialList to enable ZRoom to declare
* ZTextureAnimations, using that ZResource to do the work.
*/
#include "SetAnimatedMaterialList.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
#include "ZTextureAnimation.h"
SetAnimatedMaterialList::SetAnimatedMaterialList(ZFile* nParent)
: ZRoomCommand(nParent), textureAnimation(nParent)
{
}
void SetAnimatedMaterialList::ParseRawData()
{
ZRoomCommand::ParseRawData();
textureAnimation.ExtractFromFile(segmentOffset);
}
void SetAnimatedMaterialList::DeclareReferences(const std::string& prefix)
{
textureAnimation.SetName(textureAnimation.GetDefaultName(prefix.c_str()));
textureAnimation.DeclareReferences(prefix);
textureAnimation.GetSourceOutputCode(prefix);
}
std::string SetAnimatedMaterialList::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "AnimatedMaterial", listName);
return StringHelper::Sprintf("SCENE_CMD_ANIMATED_MATERIAL_LIST(%s)", listName.c_str());
}
std::string SetAnimatedMaterialList::GetCommandCName() const
{
return "SCmdTextureAnimations";
}
RoomCommand SetAnimatedMaterialList::GetRoomCommand() const
{
return RoomCommand::SetAnimatedMaterialList;
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
#include "ZTextureAnimation.h"
class SetAnimatedMaterialList : public ZRoomCommand
{
public:
SetAnimatedMaterialList(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
private:
ZTextureAnimation textureAnimation;
};

View File

@ -0,0 +1,31 @@
#include "SetCameraSettings.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
SetCameraSettings::SetCameraSettings(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetCameraSettings::ParseRawData()
{
ZRoomCommand::ParseRawData();
cameraMovement = cmdArg1;
mapHighlight = BitConverter::ToUInt32BE(parent->GetRawData(), rawDataIndex + 4);
}
std::string SetCameraSettings::GetBodySourceCode() const
{
return StringHelper::Sprintf("SCENE_CMD_MISC_SETTINGS(0x%02X, 0x%08X)", cameraMovement,
mapHighlight);
}
std::string SetCameraSettings::GetCommandCName() const
{
return "SCmdMiscSettings";
}
RoomCommand SetCameraSettings::GetRoomCommand() const
{
return RoomCommand::SetCameraSettings;
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class SetCameraSettings : public ZRoomCommand
{
public:
uint8_t cameraMovement;
uint32_t mapHighlight;
SetCameraSettings(ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetCommandCName() const override;
RoomCommand GetRoomCommand() const override;
private:
};

View File

@ -0,0 +1,44 @@
#include "SetCollisionHeader.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetCollisionHeader::SetCollisionHeader(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetCollisionHeader::ParseRawData()
{
ZRoomCommand::ParseRawData();
collisionHeader = new ZCollisionHeader(parent);
collisionHeader->SetName(
StringHelper::Sprintf("%sCollisionHeader_%06X", parent->GetName().c_str(), segmentOffset));
collisionHeader->ExtractFromFile(segmentOffset);
parent->AddResource(collisionHeader);
}
void SetCollisionHeader::DeclareReferences(const std::string& prefix)
{
collisionHeader->DeclareVar(prefix, "");
}
std::string SetCollisionHeader::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CollisionHeader", listName);
return StringHelper::Sprintf("SCENE_CMD_COL_HEADER(%s)", listName.c_str());
}
std::string SetCollisionHeader::GetCommandCName() const
{
return "SCmdColHeader";
}
RoomCommand SetCollisionHeader::GetRoomCommand() const
{
return RoomCommand::SetCollisionHeader;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "ZCollision.h"
#include "ZRoom/ZRoomCommand.h"
class SetCollisionHeader : public ZRoomCommand
{
public:
ZCollisionHeader* collisionHeader;
SetCollisionHeader(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetCommandCName() const override;
RoomCommand GetRoomCommand() const override;
};

View File

@ -0,0 +1,152 @@
#include "SetCsCamera.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetCsCamera::SetCsCamera(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetCsCamera::ParseRawData()
{
ZRoomCommand::ParseRawData();
int numCameras = cmdArg1;
uint32_t currentPtr = segmentOffset;
int32_t numPoints = 0;
for (int32_t i = 0; i < numCameras; i++)
{
CsCameraEntry entry(parent->GetRawData(), currentPtr);
numPoints += entry.GetNumPoints();
currentPtr += entry.GetRawDataSize();
cameras.push_back(entry);
}
if (numPoints > 0)
{
uint32_t currentPtr = cameras.at(0).GetSegmentOffset();
for (int32_t i = 0; i < numPoints; i++)
{
ZVector vec(parent);
vec.ExtractFromBinary(currentPtr, ZScalarType::ZSCALAR_S16, 3);
currentPtr += vec.GetRawDataSize();
points.push_back(vec);
}
}
}
void SetCsCamera::DeclareReferences(const std::string& prefix)
{
if (points.size() > 0)
{
std::string declaration;
size_t index = 0;
for (auto& point : points)
{
declaration += StringHelper::Sprintf("\t{ %s },", point.GetBodySourceCode().c_str());
if (index < points.size() - 1)
declaration += "\n";
index++;
}
uint32_t segOffset = cameras.at(0).GetSegmentOffset();
parent->AddDeclarationArray(
segOffset, DeclarationAlignment::Align4, points.size() * points.at(0).GetRawDataSize(),
points.at(0).GetSourceTypeName().c_str(),
StringHelper::Sprintf("%sCsCameraPoints_%06X", prefix.c_str(), segOffset),
points.size(), declaration);
}
if (!cameras.empty())
{
std::string camPointsName;
Globals::Instance->GetSegmentedPtrName(cameras.at(0).GetCamAddress(), parent, "Vec3s",
camPointsName);
std::string declaration;
size_t index = 0;
size_t pointsIndex = 0;
for (const auto& entry : cameras)
{
declaration +=
StringHelper::Sprintf("\t{ %i, %i, &%s[%i] },", entry.type, entry.numPoints,
camPointsName.c_str(), pointsIndex);
if (index < cameras.size() - 1)
declaration += "\n";
index++;
pointsIndex += entry.GetNumPoints();
}
const auto& entry = cameras.front();
std::string camTypename = entry.GetSourceTypeName();
parent->AddDeclarationArray(
segmentOffset, DeclarationAlignment::Align4, cameras.size() * entry.GetRawDataSize(),
camTypename,
StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), camTypename.c_str(), segmentOffset),
cameras.size(), declaration);
}
}
std::string SetCsCamera::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CsCameraEntry", listName);
return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST(%i, %s)", cameras.size(),
listName.c_str());
}
std::string SetCsCamera::GetCommandCName() const
{
return "SCmdCsCameraList";
}
RoomCommand SetCsCamera::GetRoomCommand() const
{
return RoomCommand::SetCsCamera;
}
CsCameraEntry::CsCameraEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
: baseOffset(rawDataIndex), type(BitConverter::ToInt16BE(rawData, rawDataIndex + 0)),
numPoints(BitConverter::ToInt16BE(rawData, rawDataIndex + 2))
{
camAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 4);
segmentOffset = GETSEGOFFSET(camAddress);
}
std::string CsCameraEntry::GetSourceTypeName() const
{
return "CsCameraEntry";
}
int32_t CsCameraEntry::GetRawDataSize() const
{
return 8;
}
int16_t CsCameraEntry::GetNumPoints() const
{
return numPoints;
}
segptr_t CsCameraEntry::GetCamAddress() const
{
return camAddress;
}
uint32_t CsCameraEntry::GetSegmentOffset() const
{
return segmentOffset;
}

View File

@ -0,0 +1,40 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
#include "ZVector.h"
class CsCameraEntry
{
public:
CsCameraEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetSourceTypeName() const;
int32_t GetRawDataSize() const;
int16_t GetNumPoints() const;
segptr_t GetCamAddress() const;
uint32_t GetSegmentOffset() const;
int baseOffset;
int16_t type;
int16_t numPoints;
segptr_t camAddress;
uint32_t segmentOffset;
};
class SetCsCamera : public ZRoomCommand
{
public:
std::vector<CsCameraEntry> cameras;
std::vector<ZVector> points;
SetCsCamera(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
};

View File

@ -0,0 +1,112 @@
#include "SetCutscenes.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetCutscenes::SetCutscenes(ZFile* nParent) : ZRoomCommand(nParent)
{
}
SetCutscenes::~SetCutscenes()
{
for (ZCutsceneBase* cutscene : cutscenes)
delete cutscene;
}
void SetCutscenes::ParseRawData()
{
ZRoomCommand::ParseRawData();
std::string output;
numCutscenes = cmdArg1;
if (Globals::Instance->game == ZGame::OOT_RETAIL || Globals::Instance->game == ZGame::OOT_SW97)
{
ZCutscene* cutscene = new ZCutscene(parent);
cutscene->ExtractFromFile(segmentOffset);
auto decl = parent->GetDeclaration(segmentOffset);
if (decl == nullptr)
{
cutscene->DeclareVar(zRoom->GetName().c_str(), "");
}
cutscenes.push_back(cutscene);
}
else
{
int32_t currentPtr = segmentOffset;
std::string declaration;
for (uint8_t i = 0; i < numCutscenes; i++)
{
CutsceneEntry entry(parent->GetRawData(), currentPtr);
cutsceneEntries.push_back(entry);
currentPtr += 8;
// TODO: don't hardcode %sCutsceneData_%06X, look up for the declared name instead
declaration += StringHelper::Sprintf(
" { %sCutsceneData_%06X, 0x%04X, 0x%02X, 0x%02X },", zRoom->GetName().c_str(),
entry.segmentOffset, entry.exit, entry.entrance, entry.flag);
if (i < numCutscenes - 1)
declaration += "\n";
ZCutsceneMM* cutscene = new ZCutsceneMM(parent);
cutscene->ExtractFromFile(entry.segmentOffset);
cutscenes.push_back(cutscene);
}
parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4,
cutsceneEntries.size() * 8, "CutsceneEntry",
StringHelper::Sprintf("%sCutsceneEntryList_%06X",
zRoom->GetName().c_str(), segmentOffset),
cutsceneEntries.size(), declaration);
}
for (ZCutsceneBase* cutscene : cutscenes)
{
if (cutscene->GetRawDataIndex() != 0)
{
Declaration* decl = parent->GetDeclaration(cutscene->GetRawDataIndex());
if (decl == nullptr)
{
cutscene->GetSourceOutputCode(zRoom->GetName());
}
else if (decl->text == "")
{
decl->text = cutscene->GetBodySourceCode();
}
}
}
}
std::string SetCutscenes::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CutsceneData", listName);
if (Globals::Instance->game == ZGame::MM_RETAIL)
return StringHelper::Sprintf("SCENE_CMD_CUTSCENE_LIST(%i, %s)", numCutscenes,
listName.c_str());
return StringHelper::Sprintf("SCENE_CMD_CUTSCENE_DATA(%s)", listName.c_str());
}
std::string SetCutscenes::GetCommandCName() const
{
return "SCmdCutsceneData";
}
RoomCommand SetCutscenes::GetRoomCommand() const
{
return RoomCommand::SetCutscenes;
}
CutsceneEntry::CutsceneEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
: segmentOffset(GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 0))),
exit(BitConverter::ToInt16BE(rawData, rawDataIndex + 4)), entrance(rawData[rawDataIndex + 6]),
flag(rawData[rawDataIndex + 7])
{
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "ZCutscene.h"
#include "ZCutsceneMM.h"
#include "ZRoom/ZRoomCommand.h"
class CutsceneEntry
{
public:
CutsceneEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
uint32_t segmentOffset;
uint16_t exit;
uint8_t entrance;
uint8_t flag;
};
class SetCutscenes : public ZRoomCommand
{
public:
std::vector<ZCutsceneBase*> cutscenes;
std::vector<CutsceneEntry> cutsceneEntries; // (MM Only)
uint8_t numCutscenes; // (MM Only)
SetCutscenes(ZFile* nParent);
~SetCutscenes();
void ParseRawData() override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
};

View File

@ -0,0 +1,27 @@
#include "SetEchoSettings.h"
#include "Utils/StringHelper.h"
SetEchoSettings::SetEchoSettings(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetEchoSettings::ParseRawData()
{
ZRoomCommand::ParseRawData();
echo = parent->GetRawData().at(rawDataIndex + 0x07);
}
std::string SetEchoSettings::GetBodySourceCode() const
{
return StringHelper::Sprintf("SCENE_CMD_ECHO_SETTINGS(%i)", echo);
}
std::string SetEchoSettings::GetCommandCName() const
{
return "SCmdEchoSettings";
}
RoomCommand SetEchoSettings::GetRoomCommand() const
{
return RoomCommand::SetEchoSettings;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class SetEchoSettings : public ZRoomCommand
{
public:
uint8_t echo;
SetEchoSettings(ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetCommandCName() const override;
RoomCommand GetRoomCommand() const override;
};

View File

@ -0,0 +1,89 @@
#include "SetEntranceList.h"
#include "Globals.h"
#include "SetStartPositionList.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetEntranceList::SetEntranceList(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetEntranceList::DeclareReferences([[maybe_unused]] const std::string& prefix)
{
if (segmentOffset != 0)
{
std::string varName =
StringHelper::Sprintf("%sEntranceList0x%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationPlaceholder(segmentOffset, varName);
}
}
void SetEntranceList::ParseRawDataLate()
{
// Parse Entrances and Generate Declaration
int numEntrances = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 2;
uint32_t currentPtr = segmentOffset;
for (int32_t i = 0; i < numEntrances; i++)
{
EntranceEntry entry(parent->GetRawData(), currentPtr);
entrances.push_back(entry);
currentPtr += 2;
}
}
void SetEntranceList::DeclareReferencesLate([[maybe_unused]] const std::string& prefix)
{
if (!entrances.empty())
{
std::string declaration;
size_t index = 0;
for (const auto& entry : entrances)
{
declaration += StringHelper::Sprintf(" { %s },", entry.GetBodySourceCode().c_str());
if (index + 1 < entrances.size())
declaration += "\n";
index++;
}
std::string varName =
StringHelper::Sprintf("%sEntranceList0x%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4,
entrances.size() * 2, "EntranceEntry", varName,
entrances.size(), declaration);
}
}
std::string SetEntranceList::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "EntranceEntry", listName);
return StringHelper::Sprintf("SCENE_CMD_ENTRANCE_LIST(%s)", listName.c_str());
}
std::string SetEntranceList::GetCommandCName() const
{
return "SCmdEntranceList";
}
RoomCommand SetEntranceList::GetRoomCommand() const
{
return RoomCommand::SetEntranceList;
}
EntranceEntry::EntranceEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
{
startPositionIndex = rawData.at(rawDataIndex + 0);
roomToLoad = rawData.at(rawDataIndex + 1);
}
std::string EntranceEntry::GetBodySourceCode() const
{
return StringHelper::Sprintf("0x%02X, 0x%02X", startPositionIndex, roomToLoad);
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class EntranceEntry
{
public:
uint8_t startPositionIndex;
uint8_t roomToLoad;
EntranceEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
};
class SetEntranceList : public ZRoomCommand
{
public:
std::vector<EntranceEntry> entrances;
SetEntranceList(ZFile* nParent);
void DeclareReferences(const std::string& prefix) override;
void ParseRawDataLate() override;
void DeclareReferencesLate(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
};

View File

@ -0,0 +1,73 @@
#include "SetExitList.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetExitList::SetExitList(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetExitList::DeclareReferences([[maybe_unused]] const std::string& prefix)
{
if (segmentOffset != 0)
{
std::string varName =
StringHelper::Sprintf("%sExitList_%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationPlaceholder(segmentOffset, varName);
}
}
void SetExitList::ParseRawDataLate()
{
// Parse Entrances and Generate Declaration
int numEntrances = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 2;
uint32_t currentPtr = segmentOffset;
for (int32_t i = 0; i < numEntrances; i++)
{
uint16_t exit = BitConverter::ToUInt16BE(parent->GetRawData(), currentPtr);
exits.push_back(exit);
currentPtr += 2;
}
}
void SetExitList::DeclareReferencesLate([[maybe_unused]] const std::string& prefix)
{
if (!exits.empty())
{
std::string declaration;
for (size_t i = 0; i < exits.size(); i++)
{
declaration += StringHelper::Sprintf(" 0x%04X,", exits.at(i));
if (i + 1 < exits.size())
declaration += "\n";
}
std::string varName =
StringHelper::Sprintf("%sExitList_%06X", prefix.c_str(), segmentOffset);
parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4, exits.size() * 2,
"u16", varName, exits.size(), declaration);
}
}
std::string SetExitList::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "u16", listName);
return StringHelper::Sprintf("SCENE_CMD_EXIT_LIST(%s)", listName.c_str());
}
std::string SetExitList::GetCommandCName() const
{
return "SCmdExitList";
}
RoomCommand SetExitList::GetRoomCommand() const
{
return RoomCommand::SetExitList;
}

View File

@ -0,0 +1,20 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class SetExitList : public ZRoomCommand
{
public:
std::vector<uint16_t> exits;
SetExitList(ZFile* nParent);
void DeclareReferences(const std::string& prefix) override;
void ParseRawDataLate() override;
void DeclareReferencesLate(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
};

View File

@ -0,0 +1,97 @@
#include "SetLightList.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
SetLightList::SetLightList(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetLightList::ParseRawData()
{
ZRoomCommand::ParseRawData();
std::string declarations;
numLights = cmdArg1;
int32_t currentPtr = segmentOffset;
for (int i = 0; i < this->numLights; i++)
{
LightInfo light(parent->GetRawData(), currentPtr);
currentPtr += light.GetRawDataSize();
lights.push_back(light);
}
}
void SetLightList::DeclareReferences(const std::string& prefix)
{
if (!lights.empty())
{
std::string declarations;
for (size_t i = 0; i < lights.size(); i++)
{
declarations +=
StringHelper::Sprintf("\t{ %s },", lights.at(i).GetBodySourceCode().c_str());
if (i < lights.size() - 1)
declarations += "\n";
}
const auto& light = lights.front();
parent->AddDeclarationArray(
segmentOffset, DeclarationAlignment::Align4, lights.size() * light.GetRawDataSize(),
light.GetSourceTypeName(),
StringHelper::Sprintf("%sLightInfo0x%06X", prefix.c_str(), segmentOffset),
lights.size(), declarations);
}
}
std::string SetLightList::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightInfo", listName);
return StringHelper::Sprintf("SCENE_CMD_LIGHT_LIST(%i, %s)", numLights, listName.c_str());
}
std::string SetLightList::GetCommandCName() const
{
return "SCmdLightList";
}
RoomCommand SetLightList::GetRoomCommand() const
{
return RoomCommand::SetLightList;
}
LightInfo::LightInfo(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
{
type = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0);
x = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
y = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
z = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
r = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8);
g = BitConverter::ToUInt8BE(rawData, rawDataIndex + 9);
b = BitConverter::ToUInt8BE(rawData, rawDataIndex + 10);
drawGlow = BitConverter::ToUInt8BE(rawData, rawDataIndex + 11);
radius = BitConverter::ToInt16BE(rawData, rawDataIndex + 12);
}
std::string LightInfo::GetBodySourceCode() const
{
return StringHelper::Sprintf(
"0x%02X, { %i, %i, %i, { 0x%02X, 0x%02X, 0x%02X }, 0x%02X, 0x%04X }", type, x, y, z, r, g,
b, drawGlow, radius);
}
std::string LightInfo::GetSourceTypeName() const
{
return "LightInfo";
}
size_t LightInfo::GetRawDataSize() const
{
return 0x0E;
}

View File

@ -0,0 +1,42 @@
#pragma once
#include <string>
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
#include "ZRoom/ZRoomCommand.h"
class LightInfo
{
public:
LightInfo(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
std::string GetSourceTypeName() const;
size_t GetRawDataSize() const;
public:
uint8_t type;
int16_t x, y, z;
uint8_t r, g, b;
uint8_t drawGlow;
int16_t radius;
};
class SetLightList : public ZRoomCommand
{
public:
uint8_t numLights;
std::vector<LightInfo> lights;
SetLightList(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
};

View File

@ -0,0 +1,105 @@
#include "SetLightingSettings.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetLightingSettings::SetLightingSettings(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetLightingSettings::ParseRawData()
{
ZRoomCommand::ParseRawData();
uint8_t numLights = cmdArg1;
for (int i = 0; i < numLights; i++)
settings.push_back(LightingSettings(parent->GetRawData(), segmentOffset + (i * 22)));
}
void SetLightingSettings::DeclareReferences(const std::string& prefix)
{
if (settings.size() > 0)
{
std::string declaration;
for (size_t i = 0; i < settings.size(); i++)
{
declaration +=
StringHelper::Sprintf("\t{ %s },", settings.at(i).GetBodySourceCode().c_str());
if (i + 1 < settings.size())
declaration += "\n";
}
parent->AddDeclarationArray(
segmentOffset, DeclarationAlignment::Align4,
settings.size() * settings.front().GetRawDataSize(), "LightSettings",
StringHelper::Sprintf("%sLightSettings0x%06X", prefix.c_str(), segmentOffset),
settings.size(), declaration);
}
}
std::string SetLightingSettings::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightSettings", listName);
return StringHelper::Sprintf("SCENE_CMD_ENV_LIGHT_SETTINGS(%i, %s)", settings.size(),
listName.c_str());
}
std::string SetLightingSettings::GetCommandCName() const
{
return "SCmdLightSettingList";
}
RoomCommand SetLightingSettings::GetRoomCommand() const
{
return RoomCommand::SetLightingSettings;
}
LightingSettings::LightingSettings(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
{
ambientClrR = rawData.at(rawDataIndex + 0);
ambientClrG = rawData.at(rawDataIndex + 1);
ambientClrB = rawData.at(rawDataIndex + 2);
diffuseClrA_R = rawData.at(rawDataIndex + 3);
diffuseClrA_G = rawData.at(rawDataIndex + 4);
diffuseClrA_B = rawData.at(rawDataIndex + 5);
diffuseDirA_X = rawData.at(rawDataIndex + 6);
diffuseDirA_Y = rawData.at(rawDataIndex + 7);
diffuseDirA_Z = rawData.at(rawDataIndex + 8);
diffuseClrB_R = rawData.at(rawDataIndex + 9);
diffuseClrB_G = rawData.at(rawDataIndex + 10);
diffuseClrB_B = rawData.at(rawDataIndex + 11);
diffuseDirB_X = rawData.at(rawDataIndex + 12);
diffuseDirB_Y = rawData.at(rawDataIndex + 13);
diffuseDirB_Z = rawData.at(rawDataIndex + 14);
fogClrR = rawData.at(rawDataIndex + 15);
fogClrG = rawData.at(rawDataIndex + 16);
fogClrB = rawData.at(rawDataIndex + 17);
unk = BitConverter::ToInt16BE(rawData, rawDataIndex + 18);
drawDistance = BitConverter::ToInt16BE(rawData, rawDataIndex + 20);
}
std::string LightingSettings::GetBodySourceCode() const
{
return StringHelper::Sprintf(
"0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, "
"0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%04X, 0x%04X",
ambientClrR, ambientClrG, ambientClrB, diffuseClrA_R, diffuseClrA_G, diffuseClrA_B,
diffuseDirA_X, diffuseDirA_Y, diffuseDirA_Z, diffuseClrB_R, diffuseClrB_G, diffuseClrB_B,
diffuseDirB_X, diffuseDirB_Y, diffuseDirB_Z, fogClrR, fogClrG, fogClrB, unk, drawDistance);
}
size_t LightingSettings::GetRawDataSize() const
{
return 0x16;
}

View File

@ -0,0 +1,38 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class LightingSettings
{
public:
uint8_t ambientClrR, ambientClrG, ambientClrB;
uint8_t diffuseClrA_R, diffuseClrA_G, diffuseClrA_B;
uint8_t diffuseDirA_X, diffuseDirA_Y, diffuseDirA_Z;
uint8_t diffuseClrB_R, diffuseClrB_G, diffuseClrB_B;
uint8_t diffuseDirB_X, diffuseDirB_Y, diffuseDirB_Z;
uint8_t fogClrR, fogClrG, fogClrB;
uint16_t unk;
uint16_t drawDistance;
LightingSettings(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
size_t GetRawDataSize() const;
};
class SetLightingSettings : public ZRoomCommand
{
public:
std::vector<LightingSettings> settings;
SetLightingSettings(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
};

View File

@ -0,0 +1,612 @@
#include "SetMesh.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/Path.h"
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZBackground.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
void GenDListDeclarations(ZRoom* zRoom, ZFile* parent, ZDisplayList* dList);
SetMesh::SetMesh(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetMesh::ParseRawData()
{
ZRoomCommand::ParseRawData();
auto& parentRawData = parent->GetRawData();
meshHeaderType = parentRawData.at(segmentOffset);
switch (meshHeaderType)
{
case 0:
polyType = std::make_shared<PolygonType2>(parent, segmentOffset, zRoom);
break;
case 1:
polyType = std::make_shared<PolygonType1>(parent, segmentOffset, zRoom);
break;
case 2:
polyType = std::make_shared<PolygonType2>(parent, segmentOffset, zRoom);
break;
default:
HANDLE_ERROR(WarningType::InvalidExtractedData,
StringHelper::Sprintf("unknown meshHeaderType: %i", meshHeaderType), "");
}
polyType->ParseRawData();
}
void SetMesh::DeclareReferences(const std::string& prefix)
{
polyType->SetName(polyType->GetDefaultName(prefix));
polyType->DeclareReferences(prefix);
polyType->DeclareAndGenerateOutputCode(prefix);
}
// TODO: is this really needed?
void GenDListDeclarations(ZRoom* zRoom, ZFile* parent, ZDisplayList* dList)
{
if (dList == nullptr)
return;
dList->DeclareReferences(zRoom->GetName());
for (ZDisplayList* otherDList : dList->otherDLists)
GenDListDeclarations(zRoom, parent, otherDList);
}
std::string SetMesh::GenDListExterns(ZDisplayList* dList)
{
std::string sourceOutput;
sourceOutput += StringHelper::Sprintf("extern Gfx %sDL_%06X[];\n", zRoom->GetName().c_str(),
dList->GetRawDataIndex());
for (ZDisplayList* otherDList : dList->otherDLists)
sourceOutput += GenDListExterns(otherDList);
return sourceOutput;
}
std::string SetMesh::GetBodySourceCode() const
{
std::string list;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "", list);
return StringHelper::Sprintf("SCENE_CMD_MESH(%s)", list.c_str());
}
std::string SetMesh::GetCommandCName() const
{
return "SCmdMesh";
}
RoomCommand SetMesh::GetRoomCommand() const
{
return RoomCommand::SetMesh;
}
PolygonDlist::PolygonDlist(ZFile* nParent) : ZResource(nParent)
{
}
void PolygonDlist::ParseRawData()
{
const auto& rawData = parent->GetRawData();
switch (polyType)
{
case 2:
x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
y = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
z = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
unk_06 = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
opa = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
xlu = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12);
break;
default:
opa = BitConverter::ToUInt32BE(rawData, rawDataIndex);
xlu = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
break;
}
}
void PolygonDlist::DeclareReferences(const std::string& prefix)
{
opaDList = MakeDlist(opa, prefix);
xluDList = MakeDlist(xlu, prefix);
}
std::string PolygonDlist::GetBodySourceCode() const
{
std::string bodyStr;
std::string opaStr;
std::string xluStr;
Globals::Instance->GetSegmentedPtrName(opa, parent, "Gfx", opaStr);
Globals::Instance->GetSegmentedPtrName(xlu, parent, "Gfx", xluStr);
if (polyType == 2)
{
bodyStr += StringHelper::Sprintf("{ %6i, %6i, %6i }, %6i, ", x, y, z, unk_06);
}
bodyStr += StringHelper::Sprintf("%s, %s", opaStr.c_str(), xluStr.c_str());
return bodyStr;
}
void PolygonDlist::GetSourceOutputCode(const std::string& prefix)
{
std::string bodyStr = StringHelper::Sprintf("\n\t%s\n", GetBodySourceCode().c_str());
Declaration* decl = parent->GetDeclaration(rawDataIndex);
if (decl == nullptr)
DeclareVar(prefix, bodyStr);
else
decl->text = bodyStr;
}
std::string PolygonDlist::GetSourceTypeName() const
{
switch (polyType)
{
case 2:
return "PolygonDlist2";
default:
return "PolygonDlist";
}
}
ZResourceType PolygonDlist::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
size_t PolygonDlist::GetRawDataSize() const
{
switch (polyType)
{
case 2:
return 0x10;
default:
return 0x08;
}
}
void PolygonDlist::SetPolyType(uint8_t nPolyType)
{
polyType = nPolyType;
}
ZDisplayList* PolygonDlist::MakeDlist(segptr_t ptr, [[maybe_unused]] const std::string& prefix)
{
if (ptr == 0)
{
return nullptr;
}
uint32_t dlistAddress = Seg2Filespace(ptr, parent->baseAddress);
int32_t dlistLength = ZDisplayList::GetDListLength(
parent->GetRawData(), dlistAddress,
Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX);
ZDisplayList* dlist = new ZDisplayList(parent);
parent->AddResource(dlist);
dlist->ExtractFromBinary(dlistAddress, dlistLength);
dlist->SetName(dlist->GetDefaultName(prefix));
GenDListDeclarations(zRoom, parent, dlist);
return dlist;
}
/* BgImage */
BgImage::BgImage(ZFile* nParent) : ZResource(nParent)
{
}
BgImage::BgImage(bool nIsSubStruct, const std::string& prefix, uint32_t nRawDataIndex,
ZFile* nParent)
: BgImage(nParent)
{
rawDataIndex = nRawDataIndex;
parent = nParent;
isSubStruct = nIsSubStruct;
name = GetDefaultName(prefix);
ParseRawData();
sourceBackground = MakeBackground(source, prefix);
}
void BgImage::ParseRawData()
{
size_t pad = 0x00;
const auto& rawData = parent->GetRawData();
if (!isSubStruct)
{
pad = 0x04;
unk_00 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x00);
id = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x02);
}
source = BitConverter::ToUInt32BE(rawData, rawDataIndex + pad + 0x00);
unk_0C = BitConverter::ToUInt32BE(rawData, rawDataIndex + pad + 0x04);
tlut = BitConverter::ToUInt32BE(rawData, rawDataIndex + pad + 0x08);
width = BitConverter::ToUInt16BE(rawData, rawDataIndex + pad + 0x0C);
height = BitConverter::ToUInt16BE(rawData, rawDataIndex + pad + 0x0E);
fmt = BitConverter::ToUInt8BE(rawData, rawDataIndex + pad + 0x10);
siz = BitConverter::ToUInt8BE(rawData, rawDataIndex + pad + 0x11);
mode0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + pad + 0x12);
tlutCount = BitConverter::ToUInt16BE(rawData, rawDataIndex + pad + 0x14);
}
ZBackground* BgImage::MakeBackground(segptr_t ptr, const std::string& prefix)
{
if (ptr == 0)
return nullptr;
uint32_t backAddress = Seg2Filespace(ptr, parent->baseAddress);
ZBackground* background = new ZBackground(parent);
background->ExtractFromFile(backAddress);
std::string defaultName = background->GetDefaultName(prefix);
background->SetName(defaultName);
background->SetOutName(defaultName);
background->DeclareVar(prefix, "");
parent->resources.push_back(background);
return background;
}
size_t BgImage::GetRawDataSize() const
{
return 0x1C;
}
std::string BgImage::GetBodySourceCode() const
{
std::string bodyStr = " ";
if (!isSubStruct)
{
bodyStr += "{ \n ";
}
if (!isSubStruct)
{
bodyStr += StringHelper::Sprintf("0x%04X, ", unk_00);
bodyStr += StringHelper::Sprintf("%i, ", id);
bodyStr += "\n ";
bodyStr += " ";
}
std::string backgroundName;
Globals::Instance->GetSegmentedPtrName(source, parent, "", backgroundName);
bodyStr += StringHelper::Sprintf("%s, ", backgroundName.c_str());
bodyStr += "\n ";
if (!isSubStruct)
{
bodyStr += " ";
}
bodyStr += StringHelper::Sprintf("0x%08X, ", unk_0C);
bodyStr += StringHelper::Sprintf("0x%08X, ", tlut);
bodyStr += "\n ";
if (!isSubStruct)
{
bodyStr += " ";
}
bodyStr += StringHelper::Sprintf("%i, ", width);
bodyStr += StringHelper::Sprintf("%i, ", height);
bodyStr += "\n ";
if (!isSubStruct)
{
bodyStr += " ";
}
bodyStr += StringHelper::Sprintf("%i, ", fmt);
bodyStr += StringHelper::Sprintf("%i, ", siz);
bodyStr += "\n ";
if (!isSubStruct)
{
bodyStr += " ";
}
bodyStr += StringHelper::Sprintf("0x%04X, ", mode0);
bodyStr += StringHelper::Sprintf("0x%04X, ", tlutCount);
if (!isSubStruct)
{
bodyStr += " \n }, ";
}
else
{
bodyStr += "\n";
}
return bodyStr;
}
std::string BgImage::GetSourceTypeName() const
{
return "BgImage";
}
ZResourceType BgImage::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
/* PolygonType section */
PolygonTypeBase::PolygonTypeBase(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom)
: ZResource(nParent), zRoom{nRoom}
{
rawDataIndex = nRawDataIndex;
type = BitConverter::ToUInt8BE(parent->GetRawData(), rawDataIndex);
}
void PolygonTypeBase::DeclareAndGenerateOutputCode(const std::string& prefix)
{
std::string bodyStr = GetBodySourceCode();
Declaration* decl = parent->GetDeclaration(rawDataIndex);
if (decl == nullptr)
{
DeclareVar(prefix, bodyStr);
}
else
{
decl->text = bodyStr;
}
}
std::string PolygonTypeBase::GetSourceTypeName() const
{
switch (type)
{
case 2:
return "PolygonType2";
case 1:
return "PolygonType1";
default:
return "PolygonType0";
}
}
ZResourceType PolygonTypeBase::GetResourceType() const
{
// TODO
return ZResourceType::Error;
}
PolygonType1::PolygonType1(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom)
: PolygonTypeBase(nParent, nRawDataIndex, nRoom), single(nParent)
{
}
void PolygonType1::ParseRawData()
{
const auto& rawData = parent->GetRawData();
format = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x01);
dlist = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x04);
if (format == 2)
{
count = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08);
list = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0C);
}
if (dlist != 0)
{
PolygonDlist polyGfxList(parent);
polyGfxList.zRoom = zRoom;
polyGfxList.SetPolyType(type);
polyGfxList.ExtractFromFile(Seg2Filespace(dlist, parent->baseAddress));
polyGfxList.DeclareReferences(zRoom->GetName());
polyDLists.push_back(polyGfxList);
}
}
void PolygonType1::DeclareReferences(const std::string& prefix)
{
polyDLists.at(0).GetSourceOutputCode(prefix);
uint32_t listAddress;
std::string bgImageArrayBody;
switch (format)
{
case 1:
single = BgImage(true, prefix, rawDataIndex + 0x08, parent);
break;
case 2:
if (list != 0)
{
listAddress = Seg2Filespace(list, parent->baseAddress);
uint32_t auxPtr = listAddress;
for (size_t i = 0; i < count; ++i)
{
BgImage bg(false, prefix, auxPtr, parent);
multiList.push_back(bg);
auxPtr += bg.GetRawDataSize();
bgImageArrayBody += bg.GetBodySourceCode();
if (i + 1 < count)
{
bgImageArrayBody += "\n";
}
}
Declaration* decl = parent->GetDeclaration(listAddress);
if (decl == nullptr)
{
parent->AddDeclarationArray(
listAddress, DeclarationAlignment::Align4,
count * multiList.at(0).GetRawDataSize(), multiList.at(0).GetSourceTypeName(),
multiList.at(0).GetName().c_str(), count, bgImageArrayBody);
}
}
break;
default:
HANDLE_ERROR(WarningType::InvalidExtractedData,
StringHelper::Sprintf("unknown format: %i", format), "");
break;
}
}
size_t PolygonType1::GetRawDataSize() const
{
switch (format)
{
case 1:
return 0x20;
case 2:
return 0x10;
}
return 0x20;
}
std::string PolygonType1::GetBodySourceCode() const
{
std::string bodyStr = "\n ";
bodyStr += "{ ";
bodyStr += StringHelper::Sprintf("%i, %i, ", type, format);
std::string dlistStr;
Globals::Instance->GetSegmentedPtrName(dlist, parent, "", dlistStr);
bodyStr += StringHelper::Sprintf("%s, ", dlistStr.c_str());
bodyStr += "}, \n";
std::string listStr = "NULL";
switch (format)
{
case 1:
bodyStr += single.GetBodySourceCode();
break;
case 2:
Globals::Instance->GetSegmentedPtrName(list, parent, "BgImage", listStr);
bodyStr += StringHelper::Sprintf(" %i, %s, \n", count, listStr.c_str());
break;
default:
break;
}
return bodyStr;
}
std::string PolygonType1::GetSourceTypeName() const
{
switch (format)
{
case 1:
return "MeshHeader1Single";
case 2:
return "MeshHeader1Multi";
}
return "ERROR";
// return "PolygonType1";
}
PolygonType2::PolygonType2(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom)
: PolygonTypeBase(nParent, nRawDataIndex, nRoom)
{
}
void PolygonType2::ParseRawData()
{
const auto& rawData = parent->GetRawData();
num = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x01);
start = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x04);
end = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x08);
uint32_t currentPtr = GETSEGOFFSET(start);
for (size_t i = 0; i < num; i++)
{
PolygonDlist entry(parent);
entry.zRoom = zRoom;
entry.SetPolyType(type);
entry.ExtractFromFile(currentPtr);
entry.DeclareReferences(zRoom->GetName());
polyDLists.push_back(entry);
currentPtr += entry.GetRawDataSize();
}
}
void PolygonType2::DeclareReferences(const std::string& prefix)
{
if (num > 0)
{
std::string declaration;
for (size_t i = 0; i < polyDLists.size(); i++)
{
declaration +=
StringHelper::Sprintf("\t{ %s },", polyDLists.at(i).GetBodySourceCode().c_str());
if (i + 1 < polyDLists.size())
declaration += "\n";
}
std::string polyDlistType = polyDLists.at(0).GetSourceTypeName();
std::string polyDListName;
polyDListName = StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), polyDlistType.c_str(),
GETSEGOFFSET(start));
Declaration* decl = parent->AddDeclarationArray(
GETSEGOFFSET(start), DeclarationAlignment::Align4,
polyDLists.size() * polyDLists.at(0).GetRawDataSize(), polyDlistType, polyDListName,
polyDLists.size(), declaration);
decl->forceArrayCnt = true;
}
parent->AddDeclaration(GETSEGOFFSET(end), DeclarationAlignment::Align4, 4, "s32",
StringHelper::Sprintf("%s_terminatorMaybe_%06X",
parent->GetName().c_str(), GETSEGOFFSET(end)),
"0x01000000");
}
std::string PolygonType2::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(start, parent, "", listName);
std::string body = StringHelper::Sprintf("\n %i, %i,\n", type, polyDLists.size());
body += StringHelper::Sprintf(" %s,\n", listName.c_str());
body +=
StringHelper::Sprintf(" %s + ARRAY_COUNTU(%s)\n", listName.c_str(), listName.c_str());
return body;
}
size_t PolygonType2::GetRawDataSize() const
{
return 0x0C;
}
DeclarationAlignment PolygonType2::GetDeclarationAlignment() const
{
return DeclarationAlignment::Align4;
}

View File

@ -0,0 +1,159 @@
#pragma once
#include <memory>
#include "ZBackground.h"
#include "ZDisplayList.h"
#include "ZRoom/ZRoomCommand.h"
class PolygonDlist : public ZResource
{
public:
ZRoom* zRoom;
uint8_t polyType;
int16_t x, y, z; // polyType == 2
int16_t unk_06; // polyType == 2
segptr_t opa = 0; // Gfx*
segptr_t xlu = 0; // Gfx*
ZDisplayList* opaDList = nullptr; // Gfx*
ZDisplayList* xluDList = nullptr; // Gfx*
PolygonDlist(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
void GetSourceOutputCode(const std::string& prefix) override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
void SetPolyType(uint8_t nPolyType);
protected:
ZDisplayList* MakeDlist(segptr_t ptr, const std::string& prefix);
};
class BgImage : public ZResource
{
public:
uint16_t unk_00;
uint8_t id;
segptr_t source;
uint32_t unk_0C;
uint32_t tlut;
uint16_t width;
uint16_t height;
uint8_t fmt;
uint8_t siz;
uint16_t mode0;
uint16_t tlutCount;
ZBackground* sourceBackground;
bool isSubStruct;
BgImage(ZFile* nParent);
BgImage(bool nIsSubStruct, const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent);
void ParseRawData() override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
size_t GetRawDataSize() const override;
protected:
ZBackground* MakeBackground(segptr_t ptr, const std::string& prefix);
};
class PolygonTypeBase : public ZResource
{
public:
uint8_t type;
std::vector<PolygonDlist> polyDLists;
PolygonTypeBase(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom);
void DeclareAndGenerateOutputCode(const std::string& prefix);
std::string GetSourceTypeName() const override;
ZResourceType GetResourceType() const override;
protected:
ZRoom* zRoom;
};
class PolygonType1 : public PolygonTypeBase
{
public:
uint8_t format;
segptr_t dlist;
// single
BgImage single;
// multi
uint8_t count;
segptr_t list; // BgImage*
std::vector<BgImage> multiList;
PolygonType1(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
std::string GetSourceTypeName() const override;
size_t GetRawDataSize() const override;
};
class PolygonType2 : public PolygonTypeBase
{
public:
uint8_t num;
segptr_t start;
segptr_t end;
PolygonType2(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
size_t GetRawDataSize() const override;
DeclarationAlignment GetDeclarationAlignment() const override;
};
class SetMesh : public ZRoomCommand
{
public:
uint8_t data;
uint8_t meshHeaderType;
std::shared_ptr<PolygonTypeBase> polyType;
SetMesh(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
private:
std::string GenDListExterns(ZDisplayList* dList);
};

View File

@ -0,0 +1,81 @@
#include "SetMinimapChests.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetMinimapChests::SetMinimapChests(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetMinimapChests::ParseRawData()
{
ZRoomCommand::ParseRawData();
int numChests = cmdArg1;
int32_t currentPtr = segmentOffset;
for (int32_t i = 0; i < numChests; i++)
{
MinimapChest chest(parent->GetRawData(), currentPtr);
chests.push_back(chest);
currentPtr += 10;
}
}
void SetMinimapChests::DeclareReferences(const std::string& prefix)
{
std::string declaration;
size_t index = 0;
for (const auto& chest : chests)
{
declaration += StringHelper::Sprintf(" { %s },", chest.GetBodySourceCode().c_str());
if (index < chests.size() - 1)
declaration += "\n";
index++;
}
parent->AddDeclarationArray(
segmentOffset, DeclarationAlignment::Align4, chests.size() * 10, "MinimapChest",
StringHelper::Sprintf("%sMinimapChests0x%06X", prefix.c_str(), segmentOffset),
chests.size(), declaration);
}
std::string SetMinimapChests::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapChest", listName);
return StringHelper::Sprintf("SCENE_CMD_MINIMAP_COMPASS_ICON_INFO(0x%02X, %s)", chests.size(),
listName.c_str());
}
std::string SetMinimapChests::GetCommandCName() const
{
return "SCmdMinimapChests";
}
RoomCommand SetMinimapChests::GetRoomCommand() const
{
return RoomCommand::SetMinimapChests;
}
MinimapChest::MinimapChest(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
: unk0(BitConverter::ToUInt16BE(rawData, rawDataIndex + 0)),
unk2(BitConverter::ToUInt16BE(rawData, rawDataIndex + 2)),
unk4(BitConverter::ToUInt16BE(rawData, rawDataIndex + 4)),
unk6(BitConverter::ToUInt16BE(rawData, rawDataIndex + 6)),
unk8(BitConverter::ToUInt16BE(rawData, rawDataIndex + 8))
{
}
std::string MinimapChest::GetBodySourceCode() const
{
return StringHelper::Sprintf("0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X", unk0, unk2, unk4, unk6,
unk8);
}

View File

@ -0,0 +1,34 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class MinimapChest
{
public:
MinimapChest(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
protected:
uint16_t unk0;
uint16_t unk2;
uint16_t unk4;
uint16_t unk6;
uint16_t unk8;
};
class SetMinimapChests : public ZRoomCommand
{
public:
std::vector<MinimapChest> chests;
SetMinimapChests(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
};

View File

@ -0,0 +1,95 @@
#include "SetMinimapList.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
#include "Utils/StringHelper.h"
#include "ZFile.h"
#include "ZRoom/ZRoom.h"
SetMinimapList::SetMinimapList(ZFile* nParent) : ZRoomCommand(nParent)
{
}
void SetMinimapList::ParseRawData()
{
ZRoomCommand::ParseRawData();
listSegmentAddr = BitConverter::ToInt32BE(parent->GetRawData(), segmentOffset);
listSegmentOffset = GETSEGOFFSET(listSegmentAddr);
unk4 = BitConverter::ToInt32BE(parent->GetRawData(), segmentOffset + 4);
int32_t currentPtr = listSegmentOffset;
for (int32_t i = 0; i < zRoom->roomCount; i++)
{
MinimapEntry entry(parent->GetRawData(), currentPtr);
minimaps.push_back(entry);
currentPtr += 10;
}
}
void SetMinimapList::DeclareReferences(const std::string& prefix)
{
{
std::string declaration;
size_t index = 0;
for (const auto& entry : minimaps)
{
declaration += StringHelper::Sprintf(" { %s },", entry.GetBodySourceCode().c_str());
if (index < minimaps.size() - 1)
declaration += "\n";
index++;
}
parent->AddDeclarationArray(
listSegmentOffset, DeclarationAlignment::Align4, minimaps.size() * 10, "MinimapEntry",
StringHelper::Sprintf("%sMinimapEntryList0x%06X", prefix.c_str(), listSegmentOffset),
minimaps.size(), declaration);
}
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(listSegmentAddr, parent, "MinimapEntry", listName);
std::string declaration = StringHelper::Sprintf("\n\t%s, 0x%08X\n", listName.c_str(), unk4);
parent->AddDeclaration(
segmentOffset, DeclarationAlignment::Align4, 8, "MinimapList",
StringHelper::Sprintf("%sMinimapList0x%06X", prefix.c_str(), segmentOffset),
declaration);
}
}
std::string SetMinimapList::GetBodySourceCode() const
{
std::string listName;
Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapList", listName);
return StringHelper::Sprintf("SCENE_CMD_MINIMAP_INFO(%s)", listName.c_str());
}
std::string SetMinimapList::GetCommandCName() const
{
return "SCmdMinimapSettings";
}
RoomCommand SetMinimapList::GetRoomCommand() const
{
return RoomCommand::SetMinimapList;
}
MinimapEntry::MinimapEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
: unk0(BitConverter::ToUInt16BE(rawData, rawDataIndex + 0)),
unk2(BitConverter::ToUInt16BE(rawData, rawDataIndex + 2)),
unk4(BitConverter::ToUInt16BE(rawData, rawDataIndex + 4)),
unk6(BitConverter::ToUInt16BE(rawData, rawDataIndex + 6)),
unk8(BitConverter::ToUInt16BE(rawData, rawDataIndex + 8))
{
}
std::string MinimapEntry::GetBodySourceCode() const
{
return StringHelper::Sprintf("0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X", unk0, unk2, unk4, unk6,
unk8);
}

View File

@ -0,0 +1,39 @@
#pragma once
#include "ZRoom/ZRoomCommand.h"
class MinimapEntry
{
public:
MinimapEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
std::string GetBodySourceCode() const;
protected:
uint16_t unk0;
uint16_t unk2;
uint16_t unk4;
uint16_t unk6;
uint16_t unk8;
};
class SetMinimapList : public ZRoomCommand
{
public:
std::vector<MinimapEntry> minimaps;
SetMinimapList(ZFile* nParent);
void ParseRawData() override;
void DeclareReferences(const std::string& prefix) override;
std::string GetBodySourceCode() const override;
RoomCommand GetRoomCommand() const override;
std::string GetCommandCName() const override;
private:
segptr_t listSegmentAddr;
uint32_t listSegmentOffset;
uint32_t unk4;
};

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