first commit
This commit is contained in:
84
ZAPDTR/.clang-format
Normal file
84
ZAPDTR/.clang-format
Normal 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
|
||||
...
|
||||
|
||||
83
ZAPDTR/.github/workflows/main.yml
vendored
Normal file
83
ZAPDTR/.github/workflows/main.yml
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
name: Build ZAPD
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: self-hosted-runner
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build ZAPD
|
||||
run: make -j WERROR=1
|
||||
|
||||
- name: Checkout Repos
|
||||
run: echo "Checkout Repos"
|
||||
|
||||
- name: Checkout oot
|
||||
run: |
|
||||
git clone https://github.com/zeldaret/oot.git
|
||||
cd oot
|
||||
git submodule update --init --recursive
|
||||
|
||||
- name: Checkout mm
|
||||
run: |
|
||||
git clone https://github.com/zeldaret/mm.git
|
||||
cd mm
|
||||
|
||||
- name: Set up repos
|
||||
run: echo "Set up repos"
|
||||
|
||||
- name: Setup OOT
|
||||
run: |
|
||||
cd oot
|
||||
mkdir -p baseroms/gc-eu-mq-dbg
|
||||
cp ~/baserom_original.z64 ./baseroms/gc-eu-mq-dbg/baserom.z64
|
||||
make venv
|
||||
make -C tools -j
|
||||
cp ../ZAPD.out tools/ZAPD/
|
||||
.venv/bin/python3 tools/decompress_baserom.py gc-eu-mq-dbg
|
||||
.venv/bin/python3 extract_baserom.py
|
||||
.venv/bin/python3 extract_assets.py -j 4
|
||||
|
||||
- name: Install Python dependencies
|
||||
run: |
|
||||
cd mm
|
||||
python3 -m venv .mm-env
|
||||
source .mm-env/bin/activate
|
||||
python3 -m pip install -r requirements.txt
|
||||
|
||||
- name: Setup MM
|
||||
run: |
|
||||
cd mm
|
||||
cp ~/baserom.mm.us.rev1.z64 ./baserom.mm.us.rev1.z64
|
||||
make -C tools -j
|
||||
cp ../ZAPD.out tools/ZAPD/
|
||||
python3 tools/fixbaserom.py
|
||||
python3 tools/extract_baserom.py
|
||||
python3 tools/decompress_yars.py
|
||||
python3 extract_assets.py -j $(nproc)
|
||||
|
||||
- name: Build Repos
|
||||
run: echo "Build Repos"
|
||||
|
||||
- name: Build oot
|
||||
run: |
|
||||
cd oot
|
||||
make venv
|
||||
make -j
|
||||
|
||||
- name: Build mm
|
||||
run: |
|
||||
cd mm
|
||||
make -j disasm
|
||||
make -j
|
||||
|
||||
- name: Clean workspace
|
||||
run: git clean -fdX
|
||||
341
ZAPDTR/.gitignore
vendored
Normal file
341
ZAPDTR/.gitignore
vendored
Normal 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
|
||||
76
ZAPDTR/ExporterTest/CollisionExporter.cpp
Normal file
76
ZAPDTR/ExporterTest/CollisionExporter.cpp
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "CollisionExporter.h"
|
||||
|
||||
void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]] const 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].normX);
|
||||
writer->Write(col->polygons[i].normY);
|
||||
writer->Write(col->polygons[i].normZ);
|
||||
writer->Write(col->polygons[i].dist);
|
||||
}
|
||||
|
||||
writer->Seek(col->polyTypeDefSegmentOffset, SeekOffsetType::Start);
|
||||
|
||||
for (const auto& poly : col->polygonTypes)
|
||||
{
|
||||
writer->Write(poly.data[0]);
|
||||
writer->Write(poly.data[1]);
|
||||
}
|
||||
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);
|
||||
}
|
||||
10
ZAPDTR/ExporterTest/CollisionExporter.h
Normal file
10
ZAPDTR/ExporterTest/CollisionExporter.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZCollision.h"
|
||||
#include "ZResource.h"
|
||||
|
||||
class ExporterExample_Collision : public ZResourceExporter
|
||||
{
|
||||
public:
|
||||
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
||||
};
|
||||
160
ZAPDTR/ExporterTest/ExporterTest.vcxproj
Normal file
160
ZAPDTR/ExporterTest/ExporterTest.vcxproj
Normal 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>v143</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>v143</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>
|
||||
42
ZAPDTR/ExporterTest/ExporterTest.vcxproj.filters
Normal file
42
ZAPDTR/ExporterTest/ExporterTest.vcxproj.filters
Normal 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>
|
||||
79
ZAPDTR/ExporterTest/Main.cpp
Normal file
79
ZAPDTR/ExporterTest/Main.cpp
Normal 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);
|
||||
28
ZAPDTR/ExporterTest/Makefile
Normal file
28
ZAPDTR/ExporterTest/Makefile
Normal 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 $@ $^
|
||||
372
ZAPDTR/ExporterTest/RoomExporter.cpp
Normal file
372
ZAPDTR/ExporterTest/RoomExporter.cpp
Normal file
@@ -0,0 +1,372 @@
|
||||
#include "RoomExporter.h"
|
||||
#include "CollisionExporter.h"
|
||||
#include "Utils/BinaryWriter.h"
|
||||
#include <Utils/DiskFile.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, const 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.params);
|
||||
}
|
||||
|
||||
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();
|
||||
// DiskFile::WriteAllBytes(StringHelper::Sprintf("%s", res->GetName().c_str()),
|
||||
// memStream->ToVector());
|
||||
}
|
||||
10
ZAPDTR/ExporterTest/RoomExporter.h
Normal file
10
ZAPDTR/ExporterTest/RoomExporter.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZResource.h"
|
||||
#include "ZRoom/ZRoom.h"
|
||||
|
||||
class ExporterExample_Room : public ZResourceExporter
|
||||
{
|
||||
public:
|
||||
void Save(ZResource* res, const fs::path& outPath, BinaryWriter* writer) override;
|
||||
};
|
||||
14
ZAPDTR/ExporterTest/TextureExporter.cpp
Normal file
14
ZAPDTR/ExporterTest/TextureExporter.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "TextureExporter.h"
|
||||
#include "../ZAPD/ZFile.h"
|
||||
|
||||
void ExporterExample_Texture::Save(ZResource* res, [[maybe_unused]] const 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]);
|
||||
}
|
||||
11
ZAPDTR/ExporterTest/TextureExporter.h
Normal file
11
ZAPDTR/ExporterTest/TextureExporter.h
Normal 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, const fs::path& outPath, BinaryWriter* writer) override;
|
||||
};
|
||||
21
ZAPDTR/LICENSE
Normal file
21
ZAPDTR/LICENSE
Normal 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
134
ZAPDTR/Makefile
Normal 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/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)
|
||||
163
ZAPDTR/README.md
Normal file
163
ZAPDTR/README.md
Normal file
@@ -0,0 +1,163 @@
|
||||
# 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.
|
||||
|
||||
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`
|
||||
- `-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:
|
||||
|
||||

|
||||
521
ZAPDTR/ZAPD/CMakeLists.txt
Normal file
521
ZAPDTR/ZAPD/CMakeLists.txt
Normal file
@@ -0,0 +1,521 @@
|
||||
set(PROJECT_NAME ZAPDLib)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20 CACHE STRING "The C++ standard to use")
|
||||
#set(CMAKE_C_STANDARD 11 CACHE STRING "The C standard to use")
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
################################################################################
|
||||
# Source groups
|
||||
################################################################################
|
||||
set(Header_Files
|
||||
"../lib/tinyxml2/tinyxml2.h"
|
||||
"CRC32.h"
|
||||
"Declaration.h"
|
||||
"FileWorker.h"
|
||||
"GameConfig.h"
|
||||
"Globals.h"
|
||||
"ImageBackend.h"
|
||||
"OutputFormatter.h"
|
||||
"WarningHandler.h"
|
||||
"CrashHandler.h"
|
||||
)
|
||||
source_group("Header Files" FILES ${Header_Files})
|
||||
|
||||
set(Header_Files__Libraries
|
||||
"ctpl_stl.h"
|
||||
)
|
||||
source_group("Header Files\\Libraries" FILES ${Header_Files__Libraries})
|
||||
|
||||
set(Header_Files__Libraries__libgfxd
|
||||
"../lib/libgfxd/gbi.h"
|
||||
"../lib/libgfxd/gfxd.h"
|
||||
"../lib/libgfxd/priv.h"
|
||||
)
|
||||
source_group("Header Files\\Libraries\\libgfxd" FILES ${Header_Files__Libraries__libgfxd})
|
||||
|
||||
set(Header_Files__Yaz0
|
||||
"yaz0/readwrite.h"
|
||||
"yaz0/yaz0.h"
|
||||
)
|
||||
source_group("Header Files\\Yaz0" FILES ${Header_Files__Yaz0})
|
||||
|
||||
set(Header_Files__Z64
|
||||
"OtherStructs/SkinLimbStructs.h"
|
||||
"OtherStructs/CutsceneMM_Commands.h"
|
||||
"OtherStructs/Cutscene_Commands.h"
|
||||
"ZAnimation.h"
|
||||
"ZActorList.h"
|
||||
"ZArray.h"
|
||||
"ZAudio.h"
|
||||
"ZBackground.h"
|
||||
"ZBlob.h"
|
||||
"ZCollision.h"
|
||||
"ZCollisionPoly.h"
|
||||
"ZCutscene.h"
|
||||
"ZDisplayList.h"
|
||||
"ZFile.h"
|
||||
"ZLimb.h"
|
||||
"ZMtx.h"
|
||||
"ZPath.h"
|
||||
"ZPlayerAnimationData.h"
|
||||
"ZResource.h"
|
||||
"ZRom.h"
|
||||
"ZScalar.h"
|
||||
"ZSkeleton.h"
|
||||
"ZSurfaceType.h"
|
||||
"ZString.h"
|
||||
"ZSymbol.h"
|
||||
"ZText.h"
|
||||
"ZTexture.h"
|
||||
"ZTextureAnimation.h"
|
||||
"ZVector.h"
|
||||
"ZVtx.h"
|
||||
)
|
||||
source_group("Header Files\\Z64" FILES ${Header_Files__Z64})
|
||||
|
||||
set(Header_Files__Z64__ZRoom
|
||||
"ZRoom/ZRoom.h"
|
||||
"ZRoom/ZRoomCommand.h"
|
||||
)
|
||||
source_group("Header Files\\Z64\\ZRoom" FILES ${Header_Files__Z64__ZRoom})
|
||||
|
||||
set(Header_Files__Z64__ZRoom__Commands
|
||||
"ZRoom/Commands/EndMarker.h"
|
||||
"ZRoom/Commands/SetActorCutsceneList.h"
|
||||
"ZRoom/Commands/SetActorList.h"
|
||||
"ZRoom/Commands/SetAlternateHeaders.h"
|
||||
"ZRoom/Commands/SetAnimatedMaterialList.h"
|
||||
"ZRoom/Commands/SetCameraSettings.h"
|
||||
"ZRoom/Commands/SetCollisionHeader.h"
|
||||
"ZRoom/Commands/SetCsCamera.h"
|
||||
"ZRoom/Commands/SetCutscenes.h"
|
||||
"ZRoom/Commands/SetEchoSettings.h"
|
||||
"ZRoom/Commands/SetEntranceList.h"
|
||||
"ZRoom/Commands/SetExitList.h"
|
||||
"ZRoom/Commands/SetLightingSettings.h"
|
||||
"ZRoom/Commands/SetLightList.h"
|
||||
"ZRoom/Commands/SetMesh.h"
|
||||
"ZRoom/Commands/SetMinimapChests.h"
|
||||
"ZRoom/Commands/SetMinimapList.h"
|
||||
"ZRoom/Commands/SetObjectList.h"
|
||||
"ZRoom/Commands/SetPathways.h"
|
||||
"ZRoom/Commands/SetRoomBehavior.h"
|
||||
"ZRoom/Commands/SetRoomList.h"
|
||||
"ZRoom/Commands/SetSkyboxModifier.h"
|
||||
"ZRoom/Commands/SetSkyboxSettings.h"
|
||||
"ZRoom/Commands/SetSoundSettings.h"
|
||||
"ZRoom/Commands/SetSpecialObjects.h"
|
||||
"ZRoom/Commands/SetStartPositionList.h"
|
||||
"ZRoom/Commands/SetTimeSettings.h"
|
||||
"ZRoom/Commands/SetTransitionActorList.h"
|
||||
"ZRoom/Commands/SetWind.h"
|
||||
"ZRoom/Commands/SetWorldMapVisited.h"
|
||||
"ZRoom/Commands/Unused09.h"
|
||||
"ZRoom/Commands/Unused1D.h"
|
||||
"ZRoom/Commands/ZRoomCommandUnk.h"
|
||||
)
|
||||
source_group("Header Files\\Z64\\ZRoom\\Commands" FILES ${Header_Files__Z64__ZRoom__Commands})
|
||||
|
||||
set(Resource_Files
|
||||
"../../OTRExporter/CFG/SymbolMap_OoTMqDbg.txt"
|
||||
)
|
||||
source_group("Resource Files" FILES ${Resource_Files})
|
||||
|
||||
set(Source_Files
|
||||
"CrashHandler.cpp"
|
||||
"Declaration.cpp"
|
||||
"FileWorker.cpp"
|
||||
"GameConfig.cpp"
|
||||
"Globals.cpp"
|
||||
"ImageBackend.cpp"
|
||||
"Main.cpp"
|
||||
"OutputFormatter.cpp"
|
||||
"WarningHandler.cpp"
|
||||
)
|
||||
source_group("Source Files" FILES ${Source_Files})
|
||||
|
||||
set(Source_Files__Libraries__libgfxd
|
||||
"../lib/libgfxd/gfxd.c"
|
||||
"../lib/libgfxd/uc.c"
|
||||
"../lib/libgfxd/uc_f3dex2.c"
|
||||
)
|
||||
source_group("Source Files\\Libraries\\libgfxd" FILES ${Source_Files__Libraries__libgfxd})
|
||||
|
||||
set(Source_Files__Yaz0
|
||||
"yaz0/yaz0.cpp"
|
||||
)
|
||||
source_group("Source Files\\Yaz0" FILES ${Source_Files__Yaz0})
|
||||
|
||||
set(Source_Files__Z64
|
||||
"OtherStructs/SkinLimbStructs.cpp"
|
||||
"OtherStructs/CutsceneMM_Commands.cpp"
|
||||
"OtherStructs/Cutscene_Commands.cpp"
|
||||
"ZAnimation.cpp"
|
||||
"ZActorList.cpp"
|
||||
"ZArray.cpp"
|
||||
"ZAudio.cpp"
|
||||
"ZAudioDecode.cpp"
|
||||
"ZBackground.cpp"
|
||||
"ZBlob.cpp"
|
||||
"ZCollision.cpp"
|
||||
"ZCollisionPoly.cpp"
|
||||
"ZCutscene.cpp"
|
||||
"ZDisplayList.cpp"
|
||||
"ZFile.cpp"
|
||||
"ZLimb.cpp"
|
||||
"ZMtx.cpp"
|
||||
"ZPath.cpp"
|
||||
"ZPlayerAnimationData.cpp"
|
||||
"ZResource.cpp"
|
||||
"ZRom.cpp"
|
||||
"ZScalar.cpp"
|
||||
"ZSkeleton.cpp"
|
||||
"ZSurfaceType.cpp"
|
||||
"ZString.cpp"
|
||||
"ZSymbol.cpp"
|
||||
"ZText.cpp"
|
||||
"ZTexture.cpp"
|
||||
"ZTextureAnimation.cpp"
|
||||
"ZVector.cpp"
|
||||
"ZVtx.cpp"
|
||||
)
|
||||
source_group("Source Files\\Z64" FILES ${Source_Files__Z64})
|
||||
|
||||
set(Source_Files__Z64__ZRoom
|
||||
"ZRoom/ZRoom.cpp"
|
||||
"ZRoom/ZRoomCommand.cpp"
|
||||
)
|
||||
source_group("Source Files\\Z64\\ZRoom" FILES ${Source_Files__Z64__ZRoom})
|
||||
|
||||
set(Source_Files__Z64__ZRoom__Commands
|
||||
"ZRoom/Commands/EndMarker.cpp"
|
||||
"ZRoom/Commands/SetActorCutsceneList.cpp"
|
||||
"ZRoom/Commands/SetActorList.cpp"
|
||||
"ZRoom/Commands/SetAlternateHeaders.cpp"
|
||||
"ZRoom/Commands/SetAnimatedMaterialList.cpp"
|
||||
"ZRoom/Commands/SetCameraSettings.cpp"
|
||||
"ZRoom/Commands/SetCollisionHeader.cpp"
|
||||
"ZRoom/Commands/SetCsCamera.cpp"
|
||||
"ZRoom/Commands/SetCutscenes.cpp"
|
||||
"ZRoom/Commands/SetEchoSettings.cpp"
|
||||
"ZRoom/Commands/SetEntranceList.cpp"
|
||||
"ZRoom/Commands/SetExitList.cpp"
|
||||
"ZRoom/Commands/SetLightingSettings.cpp"
|
||||
"ZRoom/Commands/SetLightList.cpp"
|
||||
"ZRoom/Commands/SetMesh.cpp"
|
||||
"ZRoom/Commands/SetMinimapChests.cpp"
|
||||
"ZRoom/Commands/SetMinimapList.cpp"
|
||||
"ZRoom/Commands/SetObjectList.cpp"
|
||||
"ZRoom/Commands/SetPathways.cpp"
|
||||
"ZRoom/Commands/SetRoomBehavior.cpp"
|
||||
"ZRoom/Commands/SetRoomList.cpp"
|
||||
"ZRoom/Commands/SetSkyboxModifier.cpp"
|
||||
"ZRoom/Commands/SetSkyboxSettings.cpp"
|
||||
"ZRoom/Commands/SetSoundSettings.cpp"
|
||||
"ZRoom/Commands/SetSpecialObjects.cpp"
|
||||
"ZRoom/Commands/SetStartPositionList.cpp"
|
||||
"ZRoom/Commands/SetTimeSettings.cpp"
|
||||
"ZRoom/Commands/SetTransitionActorList.cpp"
|
||||
"ZRoom/Commands/SetWind.cpp"
|
||||
"ZRoom/Commands/SetWorldMapVisited.cpp"
|
||||
"ZRoom/Commands/Unused09.cpp"
|
||||
"ZRoom/Commands/Unused1D.cpp"
|
||||
"ZRoom/Commands/ZRoomCommandUnk.cpp"
|
||||
)
|
||||
source_group("Source Files\\Z64\\ZRoom\\Commands" FILES ${Source_Files__Z64__ZRoom__Commands})
|
||||
|
||||
file(GLOB Source_Files__Utils RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Utils/*.c" "Utils/*.cpp")
|
||||
source_group("Source Files\\Utils" FILES ${Source_Files__Utils})
|
||||
|
||||
file(GLOB Header_Files__Utils RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "Utils/*.h")
|
||||
source_group("Header Files\\Utils" FILES ${Header_Files__Utils})
|
||||
|
||||
set(ALL_FILES
|
||||
${Header_Files}
|
||||
${Header_Files__Libraries}
|
||||
${Header_Files__Libraries__libgfxd}
|
||||
${Header_Files__Yaz0}
|
||||
${Header_Files__Z64}
|
||||
${Header_Files__Z64__ZRoom}
|
||||
${Header_Files__Z64__ZRoom__Commands}
|
||||
${Header_Files__Utils}
|
||||
${Resource_Files}
|
||||
${Source_Files}
|
||||
${Source_Files__Libraries__libgfxd}
|
||||
${Source_Files__Yaz0}
|
||||
${Source_Files__Z64}
|
||||
${Source_Files__Z64__ZRoom}
|
||||
${Source_Files__Z64__ZRoom__Commands}
|
||||
${Source_Files__Utils}
|
||||
${any__any}
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Target
|
||||
################################################################################
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${ALL_FILES})
|
||||
|
||||
add_executable(ZAPD ExecutableMain.cpp)
|
||||
target_link_libraries(ZAPD ${PROJECT_NAME})
|
||||
|
||||
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
use_props(${PROJECT_NAME} "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
use_props(ZAPD "${CMAKE_CONFIGURATION_TYPES}" "${DEFAULT_CXX_PROPS}")
|
||||
endif()
|
||||
################################################################################
|
||||
# Includes for CMake from *.props
|
||||
################################################################################
|
||||
|
||||
set(ROOT_NAMESPACE ZAPD)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
|
||||
)
|
||||
endif()
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux|Darwin")
|
||||
set_target_properties(ZAPD PROPERTIES
|
||||
OUTPUT_NAME "ZAPD.out"
|
||||
)
|
||||
endif()
|
||||
################################################################################
|
||||
# MSVC runtime library
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
foreach(ZTarget ${PROJECT_NAME} ZAPD)
|
||||
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${ZTarget} PROPERTY MSVC_RUNTIME_LIBRARY)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
|
||||
$<$<CONFIG:Debug>:
|
||||
MultiThreadedDebug
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
MultiThreaded
|
||||
>
|
||||
$<$<NOT:$<OR:$<CONFIG:Debug>,$<CONFIG:Release>>>:${MSVC_RUNTIME_LIBRARY_DEFAULT}>
|
||||
)
|
||||
endif()
|
||||
set_target_properties(${ZTarget} PROPERTIES MSVC_RUNTIME_LIBRARY ${MSVC_RUNTIME_LIBRARY_STR})
|
||||
endforeach()
|
||||
endif()
|
||||
################################################################################
|
||||
# Compile definitions
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"_CRT_SECURE_NO_WARNINGS;"
|
||||
"_MBCS"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE
|
||||
"$<$<CONFIG:Debug>:"
|
||||
"_CRT_SECURE_NO_WARNINGS"
|
||||
">"
|
||||
"_MBCS"
|
||||
STORMLIB_NO_AUTO_LINK
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Compile and link options
|
||||
################################################################################
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(CMAKE_FIND_FRAMEWORK LAST)
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Find/download PNG for Android
|
||||
################################################################################
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
find_package(PNG QUIET)
|
||||
if (NOT ${PNG_FOUND})
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
png
|
||||
GIT_REPOSITORY https://github.com/glennrp/libpng.git
|
||||
GIT_TAG v1.6.37
|
||||
OVERRIDE_FIND_PACKAGE
|
||||
)
|
||||
message("PNG not found. Downloading now...")
|
||||
FetchContent_MakeAvailable(png)
|
||||
message("PNG downloaded to " ${FETCHCONTENT_BASE_DIR}/png-src)
|
||||
set (PNG_PNG_INCLUDE_DIR ${png_BINARY_DIR} ${png_SOURCE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/src/resource
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../libultraship/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../ZAPDTR/lib/libgfxd
|
||||
${PNG_PNG_INCLUDE_DIR}/
|
||||
.
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/Od;
|
||||
/RTC1
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_compile_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/Od
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/O2;
|
||||
/Oi;
|
||||
/Gy
|
||||
>
|
||||
/permissive-;
|
||||
/sdl;
|
||||
/W3;
|
||||
${DEFAULT_CXX_DEBUG_INFORMATION_FORMAT};
|
||||
${DEFAULT_CXX_EXCEPTION_HANDLING}
|
||||
)
|
||||
endif()
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/PROFILE
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/DEBUG:FULL
|
||||
)
|
||||
elseif("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x86")
|
||||
target_link_options(${PROJECT_NAME} PRIVATE
|
||||
$<$<CONFIG:Debug>:
|
||||
/PROFILE
|
||||
>
|
||||
$<$<CONFIG:Release>:
|
||||
/OPT:REF;
|
||||
/OPT:ICF
|
||||
>
|
||||
/DEBUG:FULL
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU|Clang|AppleClang")
|
||||
target_compile_options(${PROJECT_NAME} PUBLIC
|
||||
-Wall -Wextra -Wno-error
|
||||
-Wno-unused-parameter
|
||||
-Wno-unused-function
|
||||
-Wno-unused-variable
|
||||
-Wno-missing-field-initializers
|
||||
-Wno-parentheses
|
||||
-Wno-narrowing
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-deprecated-enum-enum-conversion>
|
||||
-pthread
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
target_link_options(${PROJECT_NAME} PUBLIC
|
||||
-pthread
|
||||
)
|
||||
else()
|
||||
target_link_options(${PROJECT_NAME} PUBLIC
|
||||
-pthread
|
||||
-Wl,-export-dynamic
|
||||
)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
# Dependencies
|
||||
################################################################################
|
||||
add_dependencies(${PROJECT_NAME}
|
||||
OTRExporter
|
||||
libultraship
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
||||
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"-WHOLEARCHIVE:$<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter>"
|
||||
"libultraship;"
|
||||
storm
|
||||
PNG::PNG
|
||||
)
|
||||
endif()
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
-Wl,-force_load $<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter>
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
${CMAKE_DL_LIBS}
|
||||
Threads::Threads
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "NintendoSwitch")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
-Wl,--whole-archive $<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter> -Wl,--no-whole-archive
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
Threads::Threads
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
-Wl,--whole-archive $<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter> -Wl,--no-whole-archive
|
||||
"libultraship;"
|
||||
png
|
||||
Threads::Threads
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "CafeOS")
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
)
|
||||
else()
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
set(ADDITIONAL_LIBRARY_DEPENDENCIES
|
||||
-Wl,--whole-archive $<TARGET_LINKER_FILE_DIR:OTRExporter>/$<TARGET_LINKER_FILE_NAME:OTRExporter> -Wl,--no-whole-archive
|
||||
"libultraship;"
|
||||
PNG::PNG
|
||||
${CMAKE_DL_LIBS}
|
||||
Threads::Threads
|
||||
)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "NintendoSwitch|CafeOS")
|
||||
add_library(pathconf OBJECT pathconf.c)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC "${ADDITIONAL_LIBRARY_DEPENDENCIES}" $<TARGET_OBJECTS:pathconf> )
|
||||
else()
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC "${ADDITIONAL_LIBRARY_DEPENDENCIES}")
|
||||
endif()
|
||||
23
ZAPDTR/ZAPD/CRC32.h
Normal file
23
ZAPDTR/ZAPD/CRC32.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
static uint32_t CRC32B(const 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);
|
||||
}
|
||||
205
ZAPDTR/ZAPD/CrashHandler.cpp
Normal file
205
ZAPDTR/ZAPD/CrashHandler.cpp
Normal file
@@ -0,0 +1,205 @@
|
||||
#include "CrashHandler.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
#if __has_include(<unistd.h>) && !defined(__ANDROID__)
|
||||
#define HAS_POSIX 1
|
||||
#else
|
||||
#define HAS_POSIX 0
|
||||
#endif
|
||||
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
#if HAS_POSIX == 1
|
||||
#include <csignal>
|
||||
#include <cxxabi.h> // for __cxa_demangle
|
||||
#include <dlfcn.h> // for dladdr
|
||||
#include <execinfo.h>
|
||||
#include <unistd.h>
|
||||
#elif defined(_MSC_VER)
|
||||
#include <Windows.h>
|
||||
#include <DbgHelp.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#pragma comment(lib, "Dbghelp.lib")
|
||||
#endif
|
||||
|
||||
// Feel free to add more crash messages.
|
||||
static std::array<const char* const, 14> 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.",
|
||||
"\tIT'S A SECRET TO EVERYBODY. \n\tBut it shouldn't be, you'd better ask about it!",
|
||||
"\tI AM ERROR.",
|
||||
"\tGRUMBLE,GRUMBLE...",
|
||||
"\tDODONGO DISLIKES SMOKE \n\tAnd ZAPD dislikes whatever you fed it.",
|
||||
"\tMay the way of the Hero lead \n\tto the debugger.",
|
||||
"\tTHE WIND FISH SLUMBERS LONG... \n\tTHE HERO'S LIFE GONE... ",
|
||||
"\tSEA BEARS FOAM, SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY CRASSSH!",
|
||||
"\tYou've met with a terrible fate, haven't you?",
|
||||
"\tMaster, I calculate a 100% probability that ZAPD has crashed. \n\tAdditionally, the "
|
||||
"batteries in your Wii Remote are nearly depleted.",
|
||||
"\t CONGRATURATIONS! \n"
|
||||
"\tAll Pages are displayed.\n"
|
||||
"\t THANK YOU! \n"
|
||||
"\t You are great debugger!",
|
||||
"\tRCP is HUNG UP!!\n"
|
||||
"\tOh! MY GOD!!",
|
||||
};
|
||||
|
||||
#if HAS_POSIX == 1
|
||||
void ErrorHandler(int sig)
|
||||
{
|
||||
std::array<void*, 4096> arr;
|
||||
constexpr size_t nMaxFrames = arr.size();
|
||||
size_t size = backtrace(arr.data(), nMaxFrames);
|
||||
char** symbols = backtrace_symbols(arr.data(), nMaxFrames);
|
||||
|
||||
fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig);
|
||||
|
||||
srand(time(nullptr));
|
||||
auto easterIndex = rand() % crashEasterEgg.size();
|
||||
|
||||
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(arr[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*)arr[i] - (char*)info.dli_saddr);
|
||||
free(demangled);
|
||||
}
|
||||
|
||||
fprintf(stderr, "%-3zd %s\n", i, functionName.c_str());
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
free(symbols);
|
||||
exit(1);
|
||||
}
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
void printStack(CONTEXT* ctx)
|
||||
{
|
||||
BOOL result;
|
||||
HANDLE process;
|
||||
HANDLE thread;
|
||||
HMODULE hModule;
|
||||
ULONG frame;
|
||||
DWORD64 displacement;
|
||||
DWORD disp;
|
||||
|
||||
srand(time(nullptr));
|
||||
auto easterIndex = rand() % crashEasterEgg.size();
|
||||
|
||||
fprintf(stderr, "\n%s\n\n", crashEasterEgg[easterIndex]);
|
||||
|
||||
#if defined(_M_AMD64)
|
||||
STACKFRAME64 stack;
|
||||
memset(&stack, 0, sizeof(STACKFRAME64));
|
||||
#else
|
||||
STACKFRAME stack;
|
||||
memset(&stack, 0, sizeof(STACKFRAME));
|
||||
#endif
|
||||
|
||||
char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME + sizeof(TCHAR)];
|
||||
char module[512];
|
||||
|
||||
PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
|
||||
|
||||
CONTEXT ctx2;
|
||||
memcpy(&ctx2, ctx, sizeof(CONTEXT));
|
||||
|
||||
process = GetCurrentProcess();
|
||||
thread = GetCurrentThread();
|
||||
SymInitialize(process, nullptr, TRUE);
|
||||
|
||||
constexpr DWORD machineType =
|
||||
#if defined(_M_AMD64)
|
||||
IMAGE_FILE_MACHINE_AMD64;
|
||||
#else
|
||||
IMAGE_FILE_MACHINE_I386;
|
||||
#endif
|
||||
|
||||
displacement = 0;
|
||||
|
||||
for (frame = 0;; frame++)
|
||||
{
|
||||
result = StackWalk(machineType, process, thread, &stack, &ctx2, nullptr,
|
||||
SymFunctionTableAccess, SymGetModuleBase, nullptr);
|
||||
if (!result)
|
||||
{
|
||||
break;
|
||||
}
|
||||
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
|
||||
symbol->MaxNameLen = MAX_SYM_NAME;
|
||||
SymFromAddr(process, (ULONG64)stack.AddrPC.Offset, &displacement, symbol);
|
||||
#if defined(_M_AMD64)
|
||||
IMAGEHLP_LINE64 line;
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
#else
|
||||
IMAGEHLP_LINE line;
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||
#endif
|
||||
if (SymGetLineFromAddr(process, stack.AddrPC.Offset, &disp, &line))
|
||||
{
|
||||
fprintf(stderr, "%u\t %s in %s: line: %lu: \n", frame, symbol->Name, line.FileName,
|
||||
line.LineNumber);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%u\tat % s\n", frame, symbol->Name);
|
||||
hModule = nullptr;
|
||||
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
(LPCTSTR)(stack.AddrPC.Offset), &hModule);
|
||||
|
||||
if (hModule != nullptr)
|
||||
{
|
||||
GetModuleFileNameA(hModule, module, 512 - 1);
|
||||
}
|
||||
fprintf(stderr, "%u\tIn %s\n", frame, module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LONG seh_filter(_EXCEPTION_POINTERS* ex)
|
||||
{
|
||||
fprintf(stderr, "EXCEPTION 0x%x occured\n", ex->ExceptionRecord->ExceptionCode);
|
||||
printStack(ex->ContextRecord);
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CrashHandler_Init()
|
||||
{
|
||||
#if HAS_POSIX == 1
|
||||
signal(SIGSEGV, ErrorHandler);
|
||||
signal(SIGABRT, ErrorHandler);
|
||||
#elif defined(_MSC_VER)
|
||||
SetUnhandledExceptionFilter(seh_filter);
|
||||
#elif !defined(__ANDROID__)
|
||||
HANDLE_WARNING(WarningType::Always,
|
||||
"tried to set error handler, but this ZAPD build lacks support for one", "");
|
||||
#endif
|
||||
}
|
||||
6
ZAPDTR/ZAPD/CrashHandler.h
Normal file
6
ZAPDTR/ZAPD/CrashHandler.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#ifndef CRASH_HANDLER_H
|
||||
#define CRASH_HANDLER_H
|
||||
|
||||
void CrashHandler_Init();
|
||||
|
||||
#endif
|
||||
236
ZAPDTR/ZAPD/Declaration.cpp
Normal file
236
ZAPDTR/ZAPD/Declaration.cpp
Normal file
@@ -0,0 +1,236 @@
|
||||
#include "Declaration.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "ZVtx.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;
|
||||
}
|
||||
|
||||
Declaration::~Declaration()
|
||||
{
|
||||
//for (auto item : vertexHack)
|
||||
//delete item;
|
||||
}
|
||||
|
||||
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 == "" || isUnaccounted)
|
||||
{
|
||||
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());
|
||||
}
|
||||
87
ZAPDTR/ZAPD/Declaration.h
Normal file
87
ZAPDTR/ZAPD/Declaration.h
Normal file
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
// 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 ZVtx;
|
||||
|
||||
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;
|
||||
|
||||
std::vector<ZVtx*> vertexHack;
|
||||
|
||||
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);
|
||||
|
||||
~Declaration();
|
||||
|
||||
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);
|
||||
};
|
||||
5
ZAPDTR/ZAPD/ExecutableMain.cpp
Normal file
5
ZAPDTR/ZAPD/ExecutableMain.cpp
Normal file
@@ -0,0 +1,5 @@
|
||||
extern "C" int zapd_main(int argc, char* argv[]);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
return zapd_main(argc, argv);
|
||||
}
|
||||
27
ZAPDTR/ZAPD/ExporterSet.h
Normal file
27
ZAPDTR/ZAPD/ExporterSet.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
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 (*ExporterSetFuncVoid4)(tinyxml2::XMLElement* reader);
|
||||
typedef void (*ExporterSetResSave)(ZResource* res, BinaryWriter& writer);
|
||||
//processCompilableFunc
|
||||
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;
|
||||
ExporterSetFuncVoid3 endProgramFunc = nullptr;
|
||||
ExporterSetFuncVoid4 processCompilableFunc = nullptr;
|
||||
};
|
||||
0
ZAPDTR/ZAPD/FileWorker.cpp
Normal file
0
ZAPDTR/ZAPD/FileWorker.cpp
Normal file
15
ZAPDTR/ZAPD/FileWorker.h
Normal file
15
ZAPDTR/ZAPD/FileWorker.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "ZFile.h"
|
||||
|
||||
class FileWorker
|
||||
{
|
||||
public:
|
||||
std::vector<ZFile*> files;
|
||||
std::vector<ZFile*> externalFiles;
|
||||
std::vector<int32_t> segments;
|
||||
std::map<int32_t, std::vector<ZFile*>> segmentRefFiles;
|
||||
};
|
||||
207
ZAPDTR/ZAPD/GameConfig.cpp
Normal file
207
ZAPDTR/ZAPD/GameConfig.cpp
Normal file
@@ -0,0 +1,207 @@
|
||||
#include "GameConfig.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string_view>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Utils/Directory.h"
|
||||
#include <Utils/DiskFile.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 = DiskFile::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 =
|
||||
DiskFile::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 =
|
||||
DiskFile::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName);
|
||||
|
||||
for (auto& line : lines)
|
||||
objectList.emplace_back(std::move(line));
|
||||
}
|
||||
|
||||
void GameConfig::ConfigFunc_EntranceList(const tinyxml2::XMLElement& element)
|
||||
{
|
||||
std::string fileName = element.Attribute("File");
|
||||
std::vector<std::string> lines =
|
||||
DiskFile::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName);
|
||||
|
||||
for (auto& line : lines)
|
||||
entranceList.emplace_back(std::move(line));
|
||||
}
|
||||
|
||||
void GameConfig::ConfigFunc_specialEntranceList(const tinyxml2::XMLElement& element)
|
||||
{
|
||||
std::string fileName = element.Attribute("File");
|
||||
std::vector<std::string> lines =
|
||||
DiskFile::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName);
|
||||
|
||||
for (auto& line : lines)
|
||||
specialEntranceList.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::unordered_map<std::string, ConfigFunc> ConfigFuncDictionary = {
|
||||
{"SymbolMap", &GameConfig::ConfigFunc_SymbolMap},
|
||||
{"ActorList", &GameConfig::ConfigFunc_ActorList},
|
||||
{"ObjectList", &GameConfig::ConfigFunc_ObjectList},
|
||||
{"EntranceList", &GameConfig::ConfigFunc_EntranceList},
|
||||
{"SpecialEntranceList", &GameConfig::ConfigFunc_specialEntranceList},
|
||||
{"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);
|
||||
}
|
||||
}
|
||||
62
ZAPDTR/ZAPD/GameConfig.h
Normal file
62
ZAPDTR/ZAPD/GameConfig.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#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::vector<std::string> entranceList;
|
||||
std::vector<std::string> specialEntranceList;
|
||||
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_EntranceList(const tinyxml2::XMLElement& element);
|
||||
void ConfigFunc_specialEntranceList(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);
|
||||
};
|
||||
325
ZAPDTR/ZAPD/Globals.cpp
Normal file
325
ZAPDTR/ZAPD/Globals.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
#include "Globals.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string_view>
|
||||
|
||||
#include <Utils/DiskFile.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;
|
||||
singleThreaded = true;
|
||||
verbosity = VerbosityLevel::VERBOSITY_SILENT;
|
||||
outputPath = Directory::GetCurrentDirectory();
|
||||
}
|
||||
|
||||
Globals::~Globals()
|
||||
{
|
||||
for (const auto& w : workerData)
|
||||
{
|
||||
delete w.second;
|
||||
}
|
||||
|
||||
if (rom != nullptr)
|
||||
{
|
||||
delete rom;
|
||||
}
|
||||
}
|
||||
|
||||
void Globals::AddSegment(int32_t segment, ZFile* file, int workerID)
|
||||
{
|
||||
if (!Globals::Instance->singleThreaded)
|
||||
{
|
||||
auto worker = workerData[workerID];
|
||||
|
||||
if (std::find(worker->segments.begin(), worker->segments.end(), segment) ==
|
||||
worker->segments.end())
|
||||
worker->segments.push_back(segment);
|
||||
if (worker->segmentRefFiles.find(segment) == worker->segmentRefFiles.end())
|
||||
worker->segmentRefFiles[segment] = std::vector<ZFile*>();
|
||||
|
||||
worker->segmentRefFiles[segment].push_back(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
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, int workerID)
|
||||
{
|
||||
if (!Globals::Instance->singleThreaded)
|
||||
return std::find(workerData[workerID]->segments.begin(),
|
||||
workerData[workerID]->segments.end(), segment) != workerData[workerID]->segments.end();
|
||||
else
|
||||
return std::find(segments.begin(), segments.end(), segment) != segments.end();
|
||||
}
|
||||
|
||||
ZFile* Globals::GetSegment(int32_t segment, int workerID)
|
||||
{
|
||||
if (!Globals::Instance->singleThreaded)
|
||||
{
|
||||
if (HasSegment(segment, workerID))
|
||||
{
|
||||
int idx = std::find(workerData[workerID]->segments.begin(),
|
||||
workerData[workerID]->segments.end(), segment) -
|
||||
workerData[workerID]->segments.begin();
|
||||
return workerData[workerID]->files[idx];
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (HasSegment(segment, workerID))
|
||||
{
|
||||
int idx = std::find(segments.begin(), segments.end(), segment) - segments.begin();
|
||||
return files[idx];
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
std::map<int32_t, std::vector<ZFile*>> Globals::GetSegmentRefFiles(int workerID)
|
||||
{
|
||||
if (!Globals::Instance->singleThreaded)
|
||||
return workerData[workerID]->segmentRefFiles;
|
||||
else
|
||||
return cfg.segmentRefFiles;
|
||||
}
|
||||
|
||||
void Globals::AddFile(ZFile* file, int workerID)
|
||||
{
|
||||
if (singleThreaded)
|
||||
files.push_back(file);
|
||||
else
|
||||
workerData[workerID]->files.push_back(file);
|
||||
}
|
||||
|
||||
void Globals::AddExternalFile(ZFile* file, int workerID)
|
||||
{
|
||||
if (singleThreaded)
|
||||
externalFiles.push_back(file);
|
||||
else
|
||||
workerData[workerID]->externalFiles.push_back(file);
|
||||
}
|
||||
|
||||
void Globals::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 (DiskFile::Exists(cfgPath))
|
||||
name = DiskFile::ReadAllText(cfgPath);
|
||||
|
||||
std::string src = tex.GetBodySourceCode();
|
||||
|
||||
DiskFile::WriteAllBytes(outPath.string(), src.c_str(), src.size());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> Globals::GetBaseromFile(std::string fileName)
|
||||
{
|
||||
if (fileMode == ZFileMode::ExtractDirectory)
|
||||
{
|
||||
if (StringHelper::Contains(fileName, "baserom/"))
|
||||
fileName = StringHelper::Split(fileName, "baserom/")[1];
|
||||
|
||||
return rom->GetFile(fileName);
|
||||
|
||||
}
|
||||
else
|
||||
return DiskFile::ReadAllBytes(fileName);
|
||||
}
|
||||
|
||||
bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile,
|
||||
const std::string& expectedType, std::string& declName, int workerID)
|
||||
{
|
||||
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, workerID))
|
||||
{
|
||||
// OTRTODO: Multithreading
|
||||
auto segs = GetSegmentRefFiles(workerID);
|
||||
for (auto file : segs[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, int workerID)
|
||||
{
|
||||
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, workerID))
|
||||
{
|
||||
// OTRTODO: Multithreading
|
||||
auto segs = GetSegmentRefFiles(workerID);
|
||||
for (auto file : segs[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;
|
||||
}
|
||||
}
|
||||
113
ZAPDTR/ZAPD/Globals.h
Normal file
113
ZAPDTR/ZAPD/Globals.h
Normal file
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "GameConfig.h"
|
||||
#include "ZFile.h"
|
||||
#include <ZRom.h>
|
||||
#include <FileWorker.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 (*ExporterSetFuncVoid4)(tinyxml2::XMLElement* reader);
|
||||
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;
|
||||
ExporterSetFuncVoid3 endProgramFunc = nullptr;
|
||||
|
||||
ExporterSetFuncVoid4 processCompilableFunc = 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;
|
||||
bool singleThreaded;
|
||||
VerbosityLevel verbosity; // ZAPD outputs additional information
|
||||
ZFileMode fileMode = ZFileMode::Invalid;
|
||||
fs::path baseRomPath, inputPath, outputPath, sourceOutputPath, cfgPath, fileListPath;
|
||||
TextureType texType;
|
||||
ZGame game;
|
||||
GameConfig cfg;
|
||||
bool verboseUnaccounted = false;
|
||||
bool gccCompat = false;
|
||||
bool forceStatic = false;
|
||||
bool forceUnaccountedStatic = false;
|
||||
bool otrMode = true;
|
||||
bool buildRawTexture = false;
|
||||
bool onlyGenCustomOtr = false;
|
||||
|
||||
ZRom* rom = nullptr;
|
||||
std::vector<ZFile*> files;
|
||||
std::vector<ZFile*> externalFiles;
|
||||
std::vector<int32_t> segments;
|
||||
|
||||
std::map<int, FileWorker*> workerData;
|
||||
|
||||
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, int workerID);
|
||||
bool HasSegment(int32_t segment, int workerID);
|
||||
ZFile* GetSegment(int32_t segment, int workerID);
|
||||
std::map<int32_t, std::vector<ZFile*>> GetSegmentRefFiles(int workerID);
|
||||
void AddFile(ZFile* file, int workerID);
|
||||
void AddExternalFile(ZFile* file, int workerID);
|
||||
void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const fs::path& outPath);
|
||||
|
||||
ZResourceExporter* GetExporter(ZResourceType resType);
|
||||
ExporterSet* GetExporterSet();
|
||||
|
||||
std::vector<uint8_t> GetBaseromFile(std::string fileName);
|
||||
|
||||
/**
|
||||
* 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, int workerID);
|
||||
|
||||
bool GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize, ZFile* currentFile,
|
||||
const std::string& expectedType, std::string& declName, int workerID);
|
||||
};
|
||||
506
ZAPDTR/ZAPD/ImageBackend.cpp
Normal file
506
ZAPDTR/ZAPD/ImageBackend.cpp
Normal 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.string().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, uint32_t offset)
|
||||
{
|
||||
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 + offset, 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;
|
||||
}
|
||||
72
ZAPDTR/ZAPD/ImageBackend.h
Normal file
72
ZAPDTR/ZAPD/ImageBackend.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#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 SetIndexedPixel(size_t y, size_t x, uint8_t index, RGBAPixel pixel);
|
||||
void SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA);
|
||||
void SetPalette(const ImageBackend& pal, uint32_t offset = 0);
|
||||
|
||||
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();
|
||||
};
|
||||
596
ZAPDTR/ZAPD/Main.cpp
Normal file
596
ZAPDTR/ZAPD/Main.cpp
Normal file
@@ -0,0 +1,596 @@
|
||||
#include "Globals.h"
|
||||
#include "Utils/Directory.h"
|
||||
#include <Utils/DiskFile.h>
|
||||
#include "Utils/Path.h"
|
||||
#include "WarningHandler.h"
|
||||
|
||||
#include "ZAnimation.h"
|
||||
ZNormalAnimation nAnim(nullptr);
|
||||
ZCurveAnimation cAnim(nullptr);
|
||||
ZLinkAnimation lAnim(nullptr);
|
||||
ZLegacyAnimation lAnim2(nullptr);
|
||||
|
||||
#include "ZArray.h"
|
||||
ZArray arr(nullptr);
|
||||
|
||||
#include "ZAudio.h"
|
||||
ZAudio audio(nullptr);
|
||||
|
||||
#include "ZBackground.h"
|
||||
ZBackground back(nullptr);
|
||||
|
||||
#include "ZBlob.h"
|
||||
ZBlob blob(nullptr);
|
||||
|
||||
#include "ZCollision.h"
|
||||
ZCollisionHeader colHeader(nullptr);
|
||||
|
||||
#include "ZCutscene.h"
|
||||
ZCutscene cs(nullptr);
|
||||
|
||||
#include "ZLimb.h"
|
||||
ZLimb limb(nullptr);
|
||||
|
||||
#include "ZMtx.h"
|
||||
ZMtx mtx(nullptr);
|
||||
|
||||
#include "ZPath.h"
|
||||
ZPath path(nullptr);
|
||||
|
||||
#include "ZPlayerAnimationData.h"
|
||||
ZPlayerAnimationData pAnimData(nullptr);
|
||||
|
||||
#include "ZScalar.h"
|
||||
ZScalar scalar(nullptr);
|
||||
|
||||
#include "ZSkeleton.h"
|
||||
ZLimbTable limbTbl(nullptr);
|
||||
ZSkeleton skel(nullptr);
|
||||
|
||||
#include "ZString.h"
|
||||
ZString str(nullptr);
|
||||
|
||||
#include "ZSymbol.h"
|
||||
ZSymbol sym(nullptr);
|
||||
|
||||
#include "ZText.h"
|
||||
ZText txt(nullptr);
|
||||
|
||||
#include "ZTexture.h"
|
||||
ZTexture tex(nullptr);
|
||||
|
||||
#include "ZVector.h"
|
||||
ZVector vec(nullptr);
|
||||
|
||||
#include "ZVtx.h"
|
||||
ZVtx vtx(nullptr);
|
||||
|
||||
#include "ZRoom/ZRoom.h"
|
||||
ZRoom room(nullptr);
|
||||
|
||||
#include "ZFile.h"
|
||||
#include "ZTexture.h"
|
||||
|
||||
#include "CrashHandler.h"
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include "tinyxml2.h"
|
||||
#include <ctpl_stl.h>
|
||||
|
||||
//extern const char gBuildHash[];
|
||||
const char gBuildHash[] = "";
|
||||
|
||||
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
|
||||
ZFileMode fileMode, int workerID);
|
||||
|
||||
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);
|
||||
int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileMode fileMode);
|
||||
|
||||
volatile int numWorkersLeft = 0;
|
||||
|
||||
extern void ImportExporters();
|
||||
|
||||
extern "C" int zapd_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 == "-fl") // Set baserom filelist path
|
||||
{
|
||||
Globals::Instance->fileListPath = argv[++i];
|
||||
}
|
||||
else if (arg == "-rconf") // Read Config File
|
||||
{
|
||||
Globals::Instance->cfg.ReadConfigFile(argv[++i]);
|
||||
}
|
||||
else if (arg == "-eh") // Enable Error Handler
|
||||
{
|
||||
CrashHandler_Init();
|
||||
}
|
||||
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
|
||||
{
|
||||
ImportExporters();
|
||||
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;
|
||||
}
|
||||
else if (arg == "-brt" || arg == "--build-raw-texture")
|
||||
{
|
||||
Globals::Instance->buildRawTexture = true;
|
||||
}
|
||||
else if (arg == "--norom")
|
||||
{
|
||||
Globals::Instance->onlyGenCustomOtr = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse File Mode
|
||||
ExporterSet* exporterSet = Globals::Instance->GetExporterSet();
|
||||
|
||||
// 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->onlyGenCustomOtr) {
|
||||
if (exporterSet != nullptr) {
|
||||
exporterSet->endProgramFunc();
|
||||
} else {
|
||||
printf("Error: No exporter set, unable to make custom otr.\n");
|
||||
}
|
||||
|
||||
delete g;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 == "bsf")
|
||||
fileMode = ZFileMode::BuildSourceFile;
|
||||
else if (buildMode == "bblb")
|
||||
fileMode = ZFileMode::BuildBlob;
|
||||
else if (buildMode == "e")
|
||||
fileMode = ZFileMode::Extract;
|
||||
else if (buildMode == "ed")
|
||||
fileMode = ZFileMode::ExtractDirectory;
|
||||
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;
|
||||
}
|
||||
|
||||
Globals::Instance->fileMode = fileMode;
|
||||
|
||||
if (fileMode == ZFileMode::ExtractDirectory)
|
||||
Globals::Instance->rom = new ZRom(Globals::Instance->baseRomPath.string());
|
||||
|
||||
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 || fileMode == ZFileMode::ExtractDirectory)
|
||||
{
|
||||
bool procFileModeSuccess = false;
|
||||
|
||||
if (exporterSet != nullptr && exporterSet->processFileModeFunc != nullptr)
|
||||
procFileModeSuccess = exporterSet->processFileModeFunc(fileMode);
|
||||
|
||||
if (!procFileModeSuccess)
|
||||
{
|
||||
if (fileMode == ZFileMode::ExtractDirectory)
|
||||
{
|
||||
std::vector<std::string> fileList =
|
||||
Directory::ListFiles(Globals::Instance->inputPath.string());
|
||||
|
||||
const int num_threads = std::thread::hardware_concurrency();
|
||||
ctpl::thread_pool pool(num_threads > 1 ? num_threads / 2 : 1);
|
||||
|
||||
bool parseSuccessful;
|
||||
|
||||
auto start = std::chrono::steady_clock::now();
|
||||
int fileListSize = fileList.size();
|
||||
Globals::Instance->singleThreaded = false;
|
||||
|
||||
for (int i = 0; i < fileListSize; i++)
|
||||
Globals::Instance->workerData[i] = new FileWorker();
|
||||
|
||||
numWorkersLeft = fileListSize;
|
||||
|
||||
for (int i = 0; i < fileListSize; i++)
|
||||
{
|
||||
if (Globals::Instance->singleThreaded)
|
||||
{
|
||||
ExtractFunc(i, fileList.size(), fileList[i], fileMode);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fileListItem = fileList[i];
|
||||
pool.push([i, fileListSize, fileListItem, fileMode](int) {
|
||||
ExtractFunc(i, fileListSize, fileListItem, fileMode);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (!Globals::Instance->singleThreaded)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (numWorkersLeft <= 0)
|
||||
break;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(250));
|
||||
}
|
||||
}
|
||||
|
||||
auto end = std::chrono::steady_clock::now();
|
||||
auto diff =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(end - start).count();
|
||||
|
||||
printf("Generated OTR File Data in %i seconds\n", diff);
|
||||
}
|
||||
else
|
||||
{
|
||||
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, 0);
|
||||
|
||||
if (!parseSuccessful)
|
||||
return 1;
|
||||
}
|
||||
|
||||
parseSuccessful =
|
||||
Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath,
|
||||
Globals::Instance->outputPath, fileMode, 0);
|
||||
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);
|
||||
}
|
||||
|
||||
if (exporterSet != nullptr && exporterSet->endProgramFunc != nullptr)
|
||||
exporterSet->endProgramFunc();
|
||||
|
||||
end:
|
||||
delete exporterSet;
|
||||
|
||||
//Globals::Instance->GetExporterSet() = nullptr; //TODO NULL this out. Compiler complains about lvalue assignment.
|
||||
|
||||
delete g;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ExtractFunc(int workerID, int fileListSize, std::string fileListItem, ZFileMode fileMode)
|
||||
{
|
||||
bool parseSuccessful;
|
||||
|
||||
printf("(%i / %i): %s\n", (workerID + 1), fileListSize, fileListItem.c_str());
|
||||
|
||||
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, workerID);
|
||||
|
||||
if (!parseSuccessful)
|
||||
return 1;
|
||||
}
|
||||
|
||||
parseSuccessful = Parse(fileListItem, Globals::Instance->baseRomPath,
|
||||
Globals::Instance->outputPath, fileMode, workerID);
|
||||
|
||||
if (!parseSuccessful)
|
||||
return 1;
|
||||
|
||||
if (Globals::Instance->singleThreaded)
|
||||
{
|
||||
for (int i = 0; i < Globals::Instance->files.size(); i++)
|
||||
{
|
||||
delete Globals::Instance->files[i];
|
||||
Globals::Instance->files.erase(Globals::Instance->files.begin() + i);
|
||||
i--;
|
||||
}
|
||||
|
||||
Globals::Instance->externalFiles.clear();
|
||||
Globals::Instance->segments.clear();
|
||||
Globals::Instance->cfg.segmentRefFiles.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < Globals::Instance->workerData[workerID]->files.size(); i++)
|
||||
{
|
||||
delete Globals::Instance->workerData[workerID]->files[i];
|
||||
Globals::Instance->workerData[workerID]->files.erase(
|
||||
Globals::Instance->workerData[workerID]->files.begin() +
|
||||
i);
|
||||
i--;
|
||||
}
|
||||
|
||||
Globals::Instance->workerData[workerID]->externalFiles.clear();
|
||||
Globals::Instance->workerData[workerID]->segments.clear();
|
||||
Globals::Instance->workerData[workerID]->segmentRefFiles.clear();
|
||||
|
||||
numWorkersLeft--;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath,
|
||||
ZFileMode fileMode, int workerID)
|
||||
{
|
||||
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, workerID);
|
||||
Globals::Instance->AddFile(file, workerID);
|
||||
if (fileMode == ZFileMode::ExternalFile)
|
||||
{
|
||||
Globals::Instance->AddExternalFile(file, workerID);
|
||||
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, workerID);
|
||||
}
|
||||
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();
|
||||
|
||||
std::vector<ZFile*> files;
|
||||
|
||||
if (Globals::Instance->singleThreaded)
|
||||
files = Globals::Instance->files;
|
||||
else
|
||||
files = Globals::Instance->workerData[workerID]->files;
|
||||
|
||||
for (ZFile* file : 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)
|
||||
{
|
||||
return Globals::Instance->BuildAssetTexture(pngFilePath, texType, outPath);
|
||||
}
|
||||
|
||||
void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath)
|
||||
{
|
||||
ZBackground background(nullptr);
|
||||
background.ParseBinaryFile(imageFilePath.string(), false);
|
||||
|
||||
DiskFile::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();
|
||||
|
||||
DiskFile::WriteAllText(outPath.string(), src);
|
||||
|
||||
delete blob;
|
||||
}
|
||||
0
ZAPDTR/ZAPD/NuGet/libpng.static.txt
Normal file
0
ZAPDTR/ZAPD/NuGet/libpng.static.txt
Normal file
213
ZAPDTR/ZAPD/OtherStructs/CutsceneMM_Commands.cpp
Normal file
213
ZAPDTR/ZAPD/OtherStructs/CutsceneMM_Commands.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
#include "CutsceneMM_Commands.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
// Specific for command lists where each entry has size 8 bytes
|
||||
const std::unordered_map<CutsceneMMCommands, CsCommandListDescriptor> csCommandsDescMM = {
|
||||
{CutsceneMMCommands::CS_CMD_MISC, {"CS_MISC", "(0x%02X, %i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_SET_LIGHTING, {"CS_LIGHTING", "(0x%02X, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_SCENE_TRANS_FX, {"CS_SCENE_TRANS_FX", "(%i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_MOTIONBLUR, {"CS_MOTIONBLUR", "(%i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_GIVETATL, {"CS_GIVETATL", "(%i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_PLAYSEQ, {"CS_PLAYSEQ", "(0x%04X, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_130, {"CS_SCENE_UNK_130", "(0x%04X, %i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_131, {"CS_SCENE_UNK_131", "(0x%04X, %i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_132, {"CS_SCENE_UNK_132", "(%i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_STOPSEQ, {"CS_STOPSEQ", "(0x%04X, %i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_PLAYAMBIENCE, {"CS_PLAYAMBIENCE", "(0x%04X, %i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_FADEAMBIENCE, {"CS_FADEAMBIENCE", "(0x%04X, %i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_TERMINATOR, {"CS_TERMINATOR", "(%i, %i, %i)"}},
|
||||
{CutsceneMMCommands::CS_CMD_CHOOSE_CREDITS_SCENES,
|
||||
{"CS_CHOOSE_CREDITS_SCENES", "(%i, %i, %i)"}},
|
||||
};
|
||||
|
||||
CutsceneSubCommandEntry_GenericMMCmd::CutsceneSubCommandEntry_GenericMMCmd(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex, CutsceneMMCommands cmdId)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex), commandId(cmdId)
|
||||
{
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_GenericMMCmd::GetBodySourceCode() const
|
||||
{
|
||||
const auto& element = csCommandsDescMM.find(commandId);
|
||||
std::string entryFmt = "CS_UNK_DATA(0x%02X, %i, %i, %i)";
|
||||
|
||||
if (element != csCommandsDescMM.end())
|
||||
{
|
||||
entryFmt = element->second.cmdMacro;
|
||||
entryFmt += element->second.args;
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf(entryFmt.c_str(), base, startFrame, endFrame, pad);
|
||||
}
|
||||
|
||||
CutsceneMMCommand_GenericCmd::CutsceneMMCommand_GenericCmd(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex,
|
||||
CutsceneMMCommands cmdId)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
commandID = static_cast<uint32_t>(cmdId);
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_GenericMMCmd(rawData, rawDataIndex, cmdId);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneMMCommand_GenericCmd::GetCommandMacro() const
|
||||
{
|
||||
const auto& element = csCommandsDescMM.find(static_cast<CutsceneMMCommands>(commandID));
|
||||
|
||||
if (element != csCommandsDescMM.end())
|
||||
{
|
||||
return StringHelper::Sprintf("%s_LIST(%i)", element->second.cmdMacro, numEntries);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%X, %i)", commandID, numEntries);
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_Camera::CutsceneSubCommandEntry_Camera(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_Camera::GetBodySourceCode() const
|
||||
{
|
||||
return StringHelper::Sprintf("CMD_HH(0x%04X, 0x%04X)", base, startFrame);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_Camera::GetRawSize() const
|
||||
{
|
||||
return 0x04;
|
||||
}
|
||||
|
||||
CutsceneMMCommand_Camera::CutsceneMMCommand_Camera(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries / 4; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_Camera(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneMMCommand_Camera::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_CAMERA_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_FadeScreen::CutsceneSubCommandEntry_FadeScreen(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
unk_06 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x06);
|
||||
unk_07 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x07);
|
||||
unk_08 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08);
|
||||
unk_09 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x09);
|
||||
unk_0A = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0A);
|
||||
unk_0B = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0B);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_FadeScreen::GetBodySourceCode() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_FADESCREEN(0x%02X, %i, %i, %i, %i, %i)", base, startFrame,
|
||||
endFrame, unk_06, unk_07, unk_08);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_FadeScreen::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneMMCommand_FadeScreen::CutsceneMMCommand_FadeScreen(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_FadeScreen(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneMMCommand_FadeScreen::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_FADESCREEN_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_FadeSeq::CutsceneSubCommandEntry_FadeSeq(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
unk_08 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_FadeSeq::GetBodySourceCode() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_FADESEQ(%i, %i, %i)", base, startFrame, endFrame);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_FadeSeq::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneMMCommand_FadeSeq::CutsceneMMCommand_FadeSeq(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_FadeSeq(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneMMCommand_FadeSeq::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_FADESEQ_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_NonImplemented::CutsceneSubCommandEntry_NonImplemented(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
}
|
||||
|
||||
CutsceneMMCommand_NonImplemented::CutsceneMMCommand_NonImplemented(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_NonImplemented(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
140
ZAPDTR/ZAPD/OtherStructs/CutsceneMM_Commands.h
Normal file
140
ZAPDTR/ZAPD/OtherStructs/CutsceneMM_Commands.h
Normal file
@@ -0,0 +1,140 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cutscene_Commands.h"
|
||||
|
||||
enum class CutsceneMMCommands
|
||||
{
|
||||
/* 0x00A */ CS_CMD_TEXTBOX = 0xA,
|
||||
/* 0x05A */ CS_CMD_CAMERA = 0x5A,
|
||||
/* 0x096 */ CS_CMD_MISC = 0x96,
|
||||
/* 0x097 */ CS_CMD_SET_LIGHTING,
|
||||
/* 0x098 */ CS_CMD_SCENE_TRANS_FX,
|
||||
/* 0x099 */ CS_CMD_MOTIONBLUR,
|
||||
/* 0x09A */ CS_CMD_GIVETATL,
|
||||
/* 0x09B */ CS_CMD_FADESCREEN,
|
||||
/* 0x09C */ CS_CMD_FADESEQ,
|
||||
/* 0x09D */ CS_CMD_SETTIME,
|
||||
/* 0x0C8 */ CS_CMD_SET_PLAYER_ACTION = 0xC8,
|
||||
/* 0x0FA */ CS_CMD_UNK_FA = 0xFA,
|
||||
/* 0x0FE */ CS_CMD_UNK_FE = 0xFE,
|
||||
/* 0x0FF */ CS_CMD_UNK_FF,
|
||||
/* 0x100 */ CS_CMD_UNK_100,
|
||||
/* 0x101 */ CS_CMD_UNK_101,
|
||||
/* 0x102 */ CS_CMD_UNK_102,
|
||||
/* 0x103 */ CS_CMD_UNK_103,
|
||||
/* 0x104 */ CS_CMD_UNK_104,
|
||||
/* 0x105 */ CS_CMD_UNK_105,
|
||||
/* 0x108 */ CS_CMD_UNK_108 = 0x108,
|
||||
/* 0x109 */ CS_CMD_UNK_109,
|
||||
/* 0x12C */ CS_CMD_PLAYSEQ = 0x12C,
|
||||
/* 0x12D */ CS_CMD_UNK_12D,
|
||||
/* 0x130 */ CS_CMD_130 = 0x130,
|
||||
/* 0x131 */ CS_CMD_131 = 0x131,
|
||||
/* 0x132 */ CS_CMD_132 = 0x132,
|
||||
/* 0x133 */ CS_CMD_STOPSEQ,
|
||||
/* 0x134 */ CS_CMD_PLAYAMBIENCE,
|
||||
/* 0x135 */ CS_CMD_FADEAMBIENCE,
|
||||
/* 0x15E */ CS_CMD_TERMINATOR = 0x15E,
|
||||
/* 0x15F */ CS_CMD_CHOOSE_CREDITS_SCENES,
|
||||
/* 0x190 */ CS_CMD_RUMBLE = 0x190,
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_GenericMMCmd : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
CutsceneMMCommands commandId;
|
||||
|
||||
CutsceneSubCommandEntry_GenericMMCmd(const std::vector<uint8_t>& rawData, offset_t rawDataIndex,
|
||||
CutsceneMMCommands cmdId);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
};
|
||||
|
||||
class CutsceneMMCommand_GenericCmd : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneMMCommand_GenericCmd(const std::vector<uint8_t>& rawData, offset_t rawDataIndex,
|
||||
CutsceneMMCommands cmdId);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
// TODO: MM cutscene camera command is implemented as a placeholder until we better understand how
|
||||
// it works
|
||||
class CutsceneSubCommandEntry_Camera : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint32_t unk_08;
|
||||
|
||||
CutsceneSubCommandEntry_Camera(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneMMCommand_Camera : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneMMCommand_Camera(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_FadeScreen : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint8_t unk_06;
|
||||
uint8_t unk_07;
|
||||
uint8_t unk_08;
|
||||
uint8_t unk_09;
|
||||
uint8_t unk_0A;
|
||||
uint8_t unk_0B;
|
||||
|
||||
CutsceneSubCommandEntry_FadeScreen(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneMMCommand_FadeScreen : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneMMCommand_FadeScreen(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_FadeSeq : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint32_t unk_08;
|
||||
|
||||
CutsceneSubCommandEntry_FadeSeq(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneMMCommand_FadeSeq : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneMMCommand_FadeSeq(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_NonImplemented : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
CutsceneSubCommandEntry_NonImplemented(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex);
|
||||
};
|
||||
|
||||
class CutsceneMMCommand_NonImplemented : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneMMCommand_NonImplemented(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
};
|
||||
458
ZAPDTR/ZAPD/OtherStructs/CutsceneOoT_Commands.cpp
Normal file
458
ZAPDTR/ZAPD/OtherStructs/CutsceneOoT_Commands.cpp
Normal file
@@ -0,0 +1,458 @@
|
||||
#include "CutsceneOoT_Commands.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_map>
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
/**** GENERIC ****/
|
||||
|
||||
// Specific for command lists where each entry has size 0x30 bytes
|
||||
const std::unordered_map<CutsceneOoT_CommandType, CsCommandListDescriptor> csCommandsDesc = {
|
||||
{CutsceneOoT_CommandType::CS_CMD_MISC,
|
||||
{"CS_MISC", "(%s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneOoT_CommandType::CS_CMD_LIGHT_SETTING,
|
||||
{"CS_LIGHT_SETTING", "(0x%02X, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneOoT_CommandType::CS_CMD_START_SEQ,
|
||||
{"CS_START_SEQ", "(%s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneOoT_CommandType::CS_CMD_STOP_SEQ,
|
||||
{"CS_STOP_SEQ", "(%s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneOoT_CommandType::CS_CMD_FADE_OUT_SEQ,
|
||||
{"CS_FADE_OUT_SEQ", "(%s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
};
|
||||
|
||||
CutsceneOoTSubCommandEntry_GenericCmd::CutsceneOoTSubCommandEntry_GenericCmd(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex, CutsceneOoT_CommandType cmdId)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex), commandId(cmdId)
|
||||
{
|
||||
word0 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0);
|
||||
word1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x4);
|
||||
|
||||
unused1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x8);
|
||||
unused2 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0xC);
|
||||
unused3 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x10);
|
||||
unused4 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x14);
|
||||
unused5 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x18);
|
||||
unused6 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x1C);
|
||||
unused7 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x20);
|
||||
unused8 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x24);
|
||||
unused9 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x28);
|
||||
unused10 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x2C);
|
||||
}
|
||||
|
||||
std::string CutsceneOoTSubCommandEntry_GenericCmd::GetBodySourceCode() const
|
||||
{
|
||||
EnumData* enumData = &Globals::Instance->cfg.enumData;
|
||||
const auto& element = csCommandsDesc.find(commandId);
|
||||
|
||||
if (element != csCommandsDesc.end())
|
||||
{
|
||||
bool isIndexInMisc = enumData->miscType.find(base) != enumData->miscType.end();
|
||||
bool isIndexInFade =
|
||||
enumData->fadeOutSeqPlayer.find(base) != enumData->fadeOutSeqPlayer.end();
|
||||
bool isIndexInSeqId = enumData->seqId.find(base - 1) != enumData->seqId.end();
|
||||
std::string entryFmt = element->second.cmdMacro;
|
||||
std::string firstArg;
|
||||
entryFmt += element->second.args;
|
||||
|
||||
if (commandId == CutsceneOoT_CommandType::CS_CMD_MISC && isIndexInMisc)
|
||||
firstArg = enumData->miscType[base];
|
||||
else if (commandId == CutsceneOoT_CommandType::CS_CMD_FADE_OUT_SEQ && isIndexInFade)
|
||||
firstArg = enumData->fadeOutSeqPlayer[base];
|
||||
else if (commandId == CutsceneOoT_CommandType::CS_CMD_START_SEQ && isIndexInSeqId)
|
||||
firstArg = enumData->seqId[base - 1];
|
||||
else if (commandId == CutsceneOoT_CommandType::CS_CMD_STOP_SEQ && isIndexInSeqId)
|
||||
firstArg = enumData->seqId[base - 1];
|
||||
else
|
||||
{
|
||||
return StringHelper::Sprintf(entryFmt.c_str(), base - 1, startFrame, endFrame, pad,
|
||||
unused1, unused2, unused3, unused4, unused5, unused6,
|
||||
unused7, unused8, unused9, unused10);
|
||||
}
|
||||
}
|
||||
return StringHelper::Sprintf("CS_UNK_DATA(0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, "
|
||||
"0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X)",
|
||||
word0, word1, unused1, unused2, unused3, unused4, unused5, unused6,
|
||||
unused7, unused8, unused9, unused10);
|
||||
}
|
||||
|
||||
size_t CutsceneOoTSubCommandEntry_GenericCmd::GetRawSize() const
|
||||
{
|
||||
return 0x30;
|
||||
}
|
||||
|
||||
CutsceneOoTCommand_GenericCmd::CutsceneOoTCommand_GenericCmd(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex,
|
||||
CutsceneOoT_CommandType cmdId)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
commandID = static_cast<uint32_t>(cmdId);
|
||||
entries.reserve(numEntries);
|
||||
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneOoTSubCommandEntry_GenericCmd(rawData, rawDataIndex, cmdId);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_GenericCmd::GetCommandMacro() const
|
||||
{
|
||||
const auto& element = csCommandsDesc.find(static_cast<CutsceneOoT_CommandType>(commandID));
|
||||
|
||||
if (element != csCommandsDesc.end())
|
||||
{
|
||||
return StringHelper::Sprintf("%s_LIST(%i)", element->second.cmdMacro, numEntries);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%X, %i)", commandID, numEntries);
|
||||
}
|
||||
|
||||
/**** CAMERA ****/
|
||||
|
||||
CutsceneOoTCommand_CameraPoint::CutsceneOoTCommand_CameraPoint(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
continueFlag = BitConverter::ToInt8BE(rawData, rawDataIndex + 0);
|
||||
cameraRoll = BitConverter::ToInt8BE(rawData, rawDataIndex + 1);
|
||||
nextPointFrame = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
|
||||
viewAngle = BitConverter::ToFloatBE(rawData, rawDataIndex + 4);
|
||||
|
||||
posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 8);
|
||||
posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 10);
|
||||
posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 12);
|
||||
|
||||
unused = BitConverter::ToInt16BE(rawData, rawDataIndex + 14);
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_CameraPoint::GetBodySourceCode() const
|
||||
{
|
||||
std::string continueMacro = "CS_CAM_CONTINUE";
|
||||
if (continueFlag != 0)
|
||||
continueMacro = "CS_CAM_STOP";
|
||||
|
||||
return StringHelper::Sprintf("CS_CAM_POINT(%s, 0x%02X, %i, %ff, %i, %i, %i, 0x%04X)",
|
||||
continueMacro.c_str(), cameraRoll, nextPointFrame, viewAngle, posX,
|
||||
posY, posZ, unused);
|
||||
}
|
||||
|
||||
size_t CutsceneOoTCommand_CameraPoint::GetRawSize() const
|
||||
{
|
||||
return 0x10;
|
||||
}
|
||||
|
||||
CutsceneOoTCommand_GenericCameraCmd::CutsceneOoTCommand_GenericCameraCmd(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
unused = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
|
||||
|
||||
bool shouldContinue = true;
|
||||
|
||||
uint32_t currentPtr = rawDataIndex + 8;
|
||||
|
||||
while (shouldContinue)
|
||||
{
|
||||
CutsceneOoTCommand_CameraPoint* camPoint =
|
||||
new CutsceneOoTCommand_CameraPoint(rawData, currentPtr);
|
||||
entries.push_back(camPoint);
|
||||
|
||||
if (camPoint->continueFlag == -1)
|
||||
shouldContinue = false;
|
||||
|
||||
currentPtr += camPoint->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_GenericCameraCmd::GetCommandMacro() const
|
||||
{
|
||||
std::string result;
|
||||
const char* listStr;
|
||||
|
||||
if (commandID == (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_AT_SPLINE)
|
||||
{
|
||||
listStr = "CS_CAM_AT_SPLINE";
|
||||
}
|
||||
else if (commandID == (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_AT_SPLINE_REL_TO_PLAYER)
|
||||
{
|
||||
listStr = "CS_CAM_AT_SPLINE_REL_TO_PLAYER";
|
||||
}
|
||||
else if (commandID == (uint32_t)CutsceneOoT_CommandType::CS_CMD_CAM_EYE_SPLINE_REL_TO_PLAYER)
|
||||
{
|
||||
listStr = "CS_CAM_EYE_SPLINE_REL_TO_PLAYER";
|
||||
}
|
||||
else
|
||||
{
|
||||
listStr = "CS_CAM_EYE_SPLINE";
|
||||
}
|
||||
|
||||
result += StringHelper::Sprintf("%s(%i, %i)", listStr, startFrame, endFrame);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t CutsceneOoTCommand_GenericCameraCmd::GetCommandSize() const
|
||||
{
|
||||
return 0x0C + entries.at(0)->GetRawSize() * entries.size();
|
||||
}
|
||||
|
||||
/**** RUMBLE ****/
|
||||
|
||||
CutsceneOoTSubCommandEntry_Rumble::CutsceneOoTSubCommandEntry_Rumble(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
sourceStrength = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x06);
|
||||
duration = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x07);
|
||||
decreaseRate = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08);
|
||||
unk_09 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x09);
|
||||
unk_0A = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0A);
|
||||
}
|
||||
|
||||
std::string CutsceneOoTSubCommandEntry_Rumble::GetBodySourceCode() const
|
||||
{
|
||||
// Note: the first argument is unused
|
||||
return StringHelper::Sprintf("CS_RUMBLE_CONTROLLER(%i, %i, %i, %i, %i, %i, 0x%02X, 0x%02X)",
|
||||
base, startFrame, endFrame, sourceStrength, duration, decreaseRate,
|
||||
unk_09, unk_0A);
|
||||
}
|
||||
|
||||
size_t CutsceneOoTSubCommandEntry_Rumble::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneOoTCommand_Rumble::CutsceneOoTCommand_Rumble(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneOoTSubCommandEntry_Rumble(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_Rumble::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_RUMBLE_CONTROLLER_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
/**** TEXT ****/
|
||||
|
||||
CutsceneOoTSubCommandEntry_Text::CutsceneOoTSubCommandEntry_Text(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
type = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6);
|
||||
textId1 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8);
|
||||
textId2 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA);
|
||||
}
|
||||
|
||||
std::string CutsceneOoTSubCommandEntry_Text::GetBodySourceCode() const
|
||||
{
|
||||
EnumData* enumData = &Globals::Instance->cfg.enumData;
|
||||
|
||||
if (type == 0xFFFF)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TEXT_NONE(%i, %i)", startFrame, endFrame);
|
||||
}
|
||||
if (type == 2 &&
|
||||
enumData->ocarinaSongActionId.find(base) != enumData->ocarinaSongActionId.end())
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TEXT_OCARINA_ACTION(%s, %i, %i, 0x%X)",
|
||||
enumData->ocarinaSongActionId[base].c_str(), startFrame,
|
||||
endFrame, textId1);
|
||||
}
|
||||
|
||||
if (enumData->textType.find(type) != enumData->textType.end())
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TEXT(0x%X, %i, %i, %s, 0x%X, 0x%X)", base, startFrame,
|
||||
endFrame, enumData->textType[type].c_str(), textId1, textId2);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_TEXT(0x%X, %i, %i, %i, 0x%X, 0x%X)", base, startFrame,
|
||||
endFrame, type, textId1, textId2);
|
||||
}
|
||||
|
||||
size_t CutsceneOoTSubCommandEntry_Text::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneOoTCommand_Text::CutsceneOoTCommand_Text(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneOoTSubCommandEntry_Text(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_Text::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TEXT_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
/**** ACTOR CUE ****/
|
||||
|
||||
CutsceneOoTSubCommandEntry_ActorCue::CutsceneOoTSubCommandEntry_ActorCue(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6);
|
||||
rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8);
|
||||
rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA);
|
||||
startPosX = BitConverter::ToInt32BE(rawData, rawDataIndex + 0xC);
|
||||
startPosY = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x10);
|
||||
startPosZ = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x14);
|
||||
endPosX = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x18);
|
||||
endPosY = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x1C);
|
||||
endPosZ = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x20);
|
||||
normalX = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x24);
|
||||
normalY = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x28);
|
||||
normalZ = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x2C);
|
||||
}
|
||||
|
||||
std::string CutsceneOoTSubCommandEntry_ActorCue::GetBodySourceCode() const
|
||||
{
|
||||
EnumData* enumData = &Globals::Instance->cfg.enumData;
|
||||
|
||||
if (static_cast<CutsceneOoT_CommandType>(commandID) ==
|
||||
CutsceneOoT_CommandType::CS_CMD_PLAYER_CUE)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_PLAYER_CUE(%s, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, "
|
||||
"%i, %i, %i, %i, %.8ef, %.8ef, %.8ef)",
|
||||
enumData->playerCueId[base].c_str(), startFrame, endFrame,
|
||||
rotX, rotY, rotZ, startPosX, startPosY, startPosZ, endPosX,
|
||||
endPosY, endPosZ, normalX, normalY, normalZ);
|
||||
}
|
||||
else
|
||||
{
|
||||
return StringHelper::Sprintf("CS_ACTOR_CUE(%i, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, "
|
||||
"%i, %i, %i, %i, %.8ef, %.8ef, %.8ef)",
|
||||
base, startFrame, endFrame, rotX, rotY, rotZ, startPosX,
|
||||
startPosY, startPosZ, endPosX, endPosY, endPosZ, normalX,
|
||||
normalY, normalZ);
|
||||
}
|
||||
}
|
||||
|
||||
size_t CutsceneOoTSubCommandEntry_ActorCue::GetRawSize() const
|
||||
{
|
||||
return 0x30;
|
||||
}
|
||||
|
||||
CutsceneOoTCommand_ActorCue::CutsceneOoTCommand_ActorCue(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneOoTSubCommandEntry_ActorCue(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_ActorCue::GetCommandMacro() const
|
||||
{
|
||||
EnumData* enumData = &Globals::Instance->cfg.enumData;
|
||||
|
||||
if (static_cast<CutsceneOoT_CommandType>(commandID) ==
|
||||
CutsceneOoT_CommandType::CS_CMD_PLAYER_CUE)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_PLAYER_CUE_LIST(%i)", entries.size());
|
||||
}
|
||||
|
||||
if (enumData->cutsceneCmd.find(commandID) != enumData->cutsceneCmd.end())
|
||||
{
|
||||
return StringHelper::Sprintf("CS_ACTOR_CUE_LIST(%s, %i)",
|
||||
enumData->cutsceneCmd[commandID].c_str(), entries.size());
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_ACTOR_CUE_LIST(0x%04X, %i)", commandID, entries.size());
|
||||
}
|
||||
|
||||
/**** DESTINATION ****/
|
||||
|
||||
CutsceneOoTCommand_Destination::CutsceneOoTCommand_Destination(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
unknown = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); // endFrame duplicate
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_Destination::GenerateSourceCode() const
|
||||
{
|
||||
EnumData* enumData = &Globals::Instance->cfg.enumData;
|
||||
|
||||
if (enumData->destination.find(base) != enumData->destination.end())
|
||||
{
|
||||
return StringHelper::Sprintf("CS_DESTINATION(%s, %i, %i),\n",
|
||||
enumData->destination[base].c_str(), startFrame, endFrame);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_DESTINATION(%i, %i, %i),\n", base, startFrame, endFrame);
|
||||
}
|
||||
|
||||
size_t CutsceneOoTCommand_Destination::GetCommandSize() const
|
||||
{
|
||||
return 0x10;
|
||||
}
|
||||
|
||||
/**** TRANSITION ****/
|
||||
|
||||
CutsceneOoTCommand_Transition::CutsceneOoTCommand_Transition(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
}
|
||||
|
||||
std::string CutsceneOoTCommand_Transition::GenerateSourceCode() const
|
||||
{
|
||||
EnumData* enumData = &Globals::Instance->cfg.enumData;
|
||||
|
||||
if (enumData->transitionType.find(base) != enumData->transitionType.end())
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TRANSITION(%s, %i, %i),\n",
|
||||
enumData->transitionType[base].c_str(), startFrame, endFrame);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_TRANSITION(%i, %i, %i),\n", base, startFrame, endFrame);
|
||||
}
|
||||
|
||||
size_t CutsceneOoTCommand_Transition::GetCommandSize() const
|
||||
{
|
||||
return 0x10;
|
||||
}
|
||||
314
ZAPDTR/ZAPD/OtherStructs/CutsceneOoT_Commands.h
Normal file
314
ZAPDTR/ZAPD/OtherStructs/CutsceneOoT_Commands.h
Normal file
@@ -0,0 +1,314 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cutscene_Common.h"
|
||||
|
||||
// https://github.com/zeldaret/oot/blob/7235af2249843fb68740111b70089bad827a4730/include/z64cutscene.h#L35-L165
|
||||
enum class CutsceneOoT_CommandType
|
||||
{
|
||||
CS_CMD_CAM_EYE_SPLINE = 0x01,
|
||||
CS_CMD_CAM_AT_SPLINE,
|
||||
CS_CMD_MISC,
|
||||
CS_CMD_LIGHT_SETTING,
|
||||
CS_CMD_CAM_EYE_SPLINE_REL_TO_PLAYER,
|
||||
CS_CMD_CAM_AT_SPLINE_REL_TO_PLAYER,
|
||||
CS_CMD_CAM_EYE,
|
||||
CS_CMD_CAM_AT,
|
||||
CS_CMD_RUMBLE_CONTROLLER,
|
||||
CS_CMD_PLAYER_CUE,
|
||||
CS_CMD_UNIMPLEMENTED_B,
|
||||
CS_CMD_UNIMPLEMENTED_D = 0x0D,
|
||||
CS_CMD_ACTOR_CUE_1_0,
|
||||
CS_CMD_ACTOR_CUE_0_0,
|
||||
CS_CMD_ACTOR_CUE_1_1,
|
||||
CS_CMD_ACTOR_CUE_0_1,
|
||||
CS_CMD_ACTOR_CUE_0_2,
|
||||
CS_CMD_TEXT,
|
||||
CS_CMD_UNIMPLEMENTED_15 = 0x15,
|
||||
CS_CMD_UNIMPLEMENTED_16,
|
||||
CS_CMD_ACTOR_CUE_0_3,
|
||||
CS_CMD_ACTOR_CUE_1_2,
|
||||
CS_CMD_ACTOR_CUE_2_0,
|
||||
CS_CMD_UNIMPLEMENTED_1B = 0x1B,
|
||||
CS_CMD_UNIMPLEMENTED_1C,
|
||||
CS_CMD_ACTOR_CUE_3_0,
|
||||
CS_CMD_ACTOR_CUE_4_0,
|
||||
CS_CMD_ACTOR_CUE_6_0,
|
||||
CS_CMD_UNIMPLEMENTED_20,
|
||||
CS_CMD_UNIMPLEMENTED_21,
|
||||
CS_CMD_ACTOR_CUE_0_4,
|
||||
CS_CMD_ACTOR_CUE_1_3,
|
||||
CS_CMD_ACTOR_CUE_2_1,
|
||||
CS_CMD_ACTOR_CUE_3_1,
|
||||
CS_CMD_ACTOR_CUE_4_1,
|
||||
CS_CMD_ACTOR_CUE_0_5,
|
||||
CS_CMD_ACTOR_CUE_1_4,
|
||||
CS_CMD_ACTOR_CUE_2_2,
|
||||
CS_CMD_ACTOR_CUE_3_2,
|
||||
CS_CMD_ACTOR_CUE_4_2,
|
||||
CS_CMD_ACTOR_CUE_5_0,
|
||||
CS_CMD_TRANSITION,
|
||||
CS_CMD_ACTOR_CUE_0_6,
|
||||
CS_CMD_ACTOR_CUE_4_3,
|
||||
CS_CMD_ACTOR_CUE_1_5,
|
||||
CS_CMD_ACTOR_CUE_7_0,
|
||||
CS_CMD_ACTOR_CUE_2_3,
|
||||
CS_CMD_ACTOR_CUE_3_3,
|
||||
CS_CMD_ACTOR_CUE_6_1,
|
||||
CS_CMD_ACTOR_CUE_3_4,
|
||||
CS_CMD_ACTOR_CUE_4_4,
|
||||
CS_CMD_ACTOR_CUE_5_1,
|
||||
CS_CMD_ACTOR_CUE_6_2 = 0x39,
|
||||
CS_CMD_ACTOR_CUE_6_3,
|
||||
CS_CMD_UNIMPLEMENTED_3B,
|
||||
CS_CMD_ACTOR_CUE_7_1,
|
||||
CS_CMD_UNIMPLEMENTED_3D,
|
||||
CS_CMD_ACTOR_CUE_8_0,
|
||||
CS_CMD_ACTOR_CUE_3_5,
|
||||
CS_CMD_ACTOR_CUE_1_6,
|
||||
CS_CMD_ACTOR_CUE_3_6,
|
||||
CS_CMD_ACTOR_CUE_3_7,
|
||||
CS_CMD_ACTOR_CUE_2_4,
|
||||
CS_CMD_ACTOR_CUE_1_7,
|
||||
CS_CMD_ACTOR_CUE_2_5,
|
||||
CS_CMD_ACTOR_CUE_1_8,
|
||||
CS_CMD_UNIMPLEMENTED_47,
|
||||
CS_CMD_ACTOR_CUE_2_6,
|
||||
CS_CMD_UNIMPLEMENTED_49,
|
||||
CS_CMD_ACTOR_CUE_2_7,
|
||||
CS_CMD_ACTOR_CUE_3_8,
|
||||
CS_CMD_ACTOR_CUE_0_7,
|
||||
CS_CMD_ACTOR_CUE_5_2,
|
||||
CS_CMD_ACTOR_CUE_1_9,
|
||||
CS_CMD_ACTOR_CUE_4_5,
|
||||
CS_CMD_ACTOR_CUE_1_10,
|
||||
CS_CMD_ACTOR_CUE_2_8,
|
||||
CS_CMD_ACTOR_CUE_3_9,
|
||||
CS_CMD_ACTOR_CUE_4_6,
|
||||
CS_CMD_ACTOR_CUE_5_3,
|
||||
CS_CMD_ACTOR_CUE_0_8,
|
||||
CS_CMD_START_SEQ,
|
||||
CS_CMD_STOP_SEQ,
|
||||
CS_CMD_ACTOR_CUE_6_4,
|
||||
CS_CMD_ACTOR_CUE_7_2,
|
||||
CS_CMD_ACTOR_CUE_5_4,
|
||||
CS_CMD_ACTOR_CUE_0_9 = 0x5D,
|
||||
CS_CMD_ACTOR_CUE_1_11,
|
||||
CS_CMD_ACTOR_CUE_0_10 = 0x69,
|
||||
CS_CMD_ACTOR_CUE_2_9,
|
||||
CS_CMD_ACTOR_CUE_0_11,
|
||||
CS_CMD_ACTOR_CUE_3_10,
|
||||
CS_CMD_UNIMPLEMENTED_6D,
|
||||
CS_CMD_ACTOR_CUE_0_12,
|
||||
CS_CMD_ACTOR_CUE_7_3,
|
||||
CS_CMD_UNIMPLEMENTED_70,
|
||||
CS_CMD_UNIMPLEMENTED_71,
|
||||
CS_CMD_ACTOR_CUE_7_4,
|
||||
CS_CMD_ACTOR_CUE_6_5,
|
||||
CS_CMD_ACTOR_CUE_1_12,
|
||||
CS_CMD_ACTOR_CUE_2_10,
|
||||
CS_CMD_ACTOR_CUE_1_13,
|
||||
CS_CMD_ACTOR_CUE_0_13,
|
||||
CS_CMD_ACTOR_CUE_1_14,
|
||||
CS_CMD_ACTOR_CUE_2_11,
|
||||
CS_CMD_ACTOR_CUE_0_14 = 0x7B,
|
||||
CS_CMD_FADE_OUT_SEQ,
|
||||
CS_CMD_ACTOR_CUE_1_15,
|
||||
CS_CMD_ACTOR_CUE_2_12,
|
||||
CS_CMD_ACTOR_CUE_3_11,
|
||||
CS_CMD_ACTOR_CUE_4_7,
|
||||
CS_CMD_ACTOR_CUE_5_5,
|
||||
CS_CMD_ACTOR_CUE_6_6,
|
||||
CS_CMD_ACTOR_CUE_1_16,
|
||||
CS_CMD_ACTOR_CUE_2_13,
|
||||
CS_CMD_ACTOR_CUE_3_12,
|
||||
CS_CMD_ACTOR_CUE_7_5,
|
||||
CS_CMD_ACTOR_CUE_4_8,
|
||||
CS_CMD_ACTOR_CUE_5_6,
|
||||
CS_CMD_ACTOR_CUE_6_7,
|
||||
CS_CMD_ACTOR_CUE_0_15,
|
||||
CS_CMD_ACTOR_CUE_0_16,
|
||||
CS_CMD_TIME,
|
||||
CS_CMD_ACTOR_CUE_1_17,
|
||||
CS_CMD_ACTOR_CUE_7_6,
|
||||
CS_CMD_ACTOR_CUE_9_0,
|
||||
CS_CMD_ACTOR_CUE_0_17,
|
||||
CS_CMD_DESTINATION = 0x03E8,
|
||||
CS_CMD_END = 0xFFFF
|
||||
};
|
||||
|
||||
/**** GENERIC ****/
|
||||
|
||||
class CutsceneOoTSubCommandEntry_GenericCmd : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
CutsceneOoT_CommandType commandId;
|
||||
|
||||
uint32_t word0 = 0;
|
||||
uint32_t word1 = 0;
|
||||
|
||||
uint32_t unused1 = 0;
|
||||
uint32_t unused2 = 0;
|
||||
uint32_t unused3 = 0;
|
||||
uint32_t unused4 = 0;
|
||||
uint32_t unused5 = 0;
|
||||
uint32_t unused6 = 0;
|
||||
uint32_t unused7 = 0;
|
||||
uint32_t unused8 = 0;
|
||||
uint32_t unused9 = 0;
|
||||
uint32_t unused10 = 0;
|
||||
|
||||
CutsceneOoTSubCommandEntry_GenericCmd(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex, CutsceneOoT_CommandType cmdId);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneOoTCommand_GenericCmd : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneOoTCommand_GenericCmd(const std::vector<uint8_t>& rawData, offset_t rawDataIndex,
|
||||
CutsceneOoT_CommandType cmdId);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
/**** CAMERA ****/
|
||||
|
||||
class CutsceneOoTCommand_CameraPoint : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
int8_t continueFlag;
|
||||
int8_t cameraRoll;
|
||||
int16_t nextPointFrame;
|
||||
float viewAngle;
|
||||
int16_t posX, posY, posZ;
|
||||
int16_t unused;
|
||||
|
||||
CutsceneOoTCommand_CameraPoint(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneOoTCommand_GenericCameraCmd : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
uint16_t unused;
|
||||
|
||||
CutsceneOoTCommand_GenericCameraCmd(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
|
||||
size_t GetCommandSize() const override;
|
||||
};
|
||||
|
||||
/**** TRANSITION ****/
|
||||
|
||||
class CutsceneOoTCommand_Transition : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
|
||||
CutsceneOoTCommand_Transition(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GenerateSourceCode() const override;
|
||||
size_t GetCommandSize() const override;
|
||||
};
|
||||
|
||||
/**** RUMBLE ****/
|
||||
|
||||
class CutsceneOoTSubCommandEntry_Rumble : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint8_t sourceStrength;
|
||||
uint8_t duration;
|
||||
uint8_t decreaseRate;
|
||||
uint8_t unk_09;
|
||||
uint8_t unk_0A;
|
||||
|
||||
CutsceneOoTSubCommandEntry_Rumble(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneOoTCommand_Rumble : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneOoTCommand_Rumble(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
/**** TEXT ****/
|
||||
|
||||
class CutsceneOoTSubCommandEntry_Text : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint16_t type;
|
||||
uint16_t textId1;
|
||||
uint16_t textId2;
|
||||
|
||||
CutsceneOoTSubCommandEntry_Text(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneOoTCommand_Text : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneOoTCommand_Text(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
/**** ACTOR CUE ****/
|
||||
|
||||
class CutsceneOoTSubCommandEntry_ActorCue : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint16_t rotX, rotY, rotZ;
|
||||
int32_t startPosX, startPosY, startPosZ;
|
||||
int32_t endPosX, endPosY, endPosZ;
|
||||
float normalX, normalY, normalZ;
|
||||
|
||||
CutsceneOoTSubCommandEntry_ActorCue(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneOoTCommand_ActorCue : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneOoTCommand_ActorCue(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
/**** DESTINATION ****/
|
||||
|
||||
class CutsceneOoTCommand_Destination : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
uint16_t unknown;
|
||||
|
||||
CutsceneOoTCommand_Destination(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GenerateSourceCode() const override;
|
||||
size_t GetCommandSize() const override;
|
||||
};
|
||||
596
ZAPDTR/ZAPD/OtherStructs/Cutscene_Commands.cpp
Normal file
596
ZAPDTR/ZAPD/OtherStructs/Cutscene_Commands.cpp
Normal file
@@ -0,0 +1,596 @@
|
||||
#include "Cutscene_Commands.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "CutsceneMM_Commands.h"
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
/* CutsceneSubCommandEntry */
|
||||
|
||||
CutsceneSubCommandEntry::CutsceneSubCommandEntry(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
{
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
pad = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry::GetBodySourceCode() const
|
||||
{
|
||||
return StringHelper::Sprintf("CMD_HH(0x%04X, 0x%04X), CMD_HH(0x%04X, 0x%04X)", base, startFrame,
|
||||
endFrame, pad);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry::GetRawSize() const
|
||||
{
|
||||
return 0x08;
|
||||
}
|
||||
|
||||
/* CutsceneCommand */
|
||||
|
||||
CutsceneCommand::CutsceneCommand(const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
{
|
||||
numEntries = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0);
|
||||
}
|
||||
|
||||
CutsceneCommand::~CutsceneCommand()
|
||||
{
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CMD_W(0x%08X), CMD_W(0x%08X)", commandID, numEntries);
|
||||
}
|
||||
|
||||
std::string CutsceneCommand::GenerateSourceCode() const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
result += GetCommandMacro();
|
||||
result += ",\n";
|
||||
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
result += " ";
|
||||
result += entry->GetBodySourceCode();
|
||||
result += ",\n";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t CutsceneCommand::GetCommandSize() const
|
||||
{
|
||||
size_t size = 0;
|
||||
if (entries.size() > 0)
|
||||
{
|
||||
size = entries.at(0)->GetRawSize() * entries.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 0x08 * numEntries;
|
||||
}
|
||||
return 0x08 + size;
|
||||
}
|
||||
|
||||
void CutsceneCommand::SetCommandID(uint32_t nCommandID)
|
||||
{
|
||||
commandID = nCommandID;
|
||||
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
entry->commandID = commandID;
|
||||
}
|
||||
}
|
||||
|
||||
// Specific for command lists where each entry has size 0x30 bytes
|
||||
const std::unordered_map<CutsceneCommands, CsCommandListDescriptor> csCommandsDesc = {
|
||||
{CutsceneCommands::Misc,
|
||||
{"CS_MISC", "(0x%04X, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneCommands::SetLighting,
|
||||
{"CS_LIGHTING", "(0x%02X, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneCommands::PlayBGM, {"CS_PLAY_BGM", "(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneCommands::StopBGM, {"CS_STOP_BGM", "(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
{CutsceneCommands::FadeBGM, {"CS_FADE_BGM", "(%i, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i)"}},
|
||||
};
|
||||
|
||||
CutsceneSubCommandEntry_GenericCmd::CutsceneSubCommandEntry_GenericCmd(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex, CutsceneCommands cmdId)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex), commandId(cmdId)
|
||||
{
|
||||
word0 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0);
|
||||
word1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x4);
|
||||
|
||||
unused1 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x8);
|
||||
unused2 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0xC);
|
||||
unused3 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x10);
|
||||
unused4 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x14);
|
||||
unused5 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x18);
|
||||
unused6 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x1C);
|
||||
unused7 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x20);
|
||||
unused8 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x24);
|
||||
unused9 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x28);
|
||||
unused10 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x2C);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_GenericCmd::GetBodySourceCode() const
|
||||
{
|
||||
const auto& element = csCommandsDesc.find(commandId);
|
||||
|
||||
if (element != csCommandsDesc.end())
|
||||
{
|
||||
std::string entryFmt = element->second.cmdMacro;
|
||||
entryFmt += element->second.args;
|
||||
|
||||
return StringHelper::Sprintf(entryFmt.c_str(), base, startFrame, endFrame, pad, unused1,
|
||||
unused2, unused3, unused4, unused5, unused6, unused7, unused8,
|
||||
unused9, unused10);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_UNK_DATA(0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, "
|
||||
"0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X, 0x%08X)",
|
||||
word0, word1, unused1, unused2, unused3, unused4, unused5, unused6,
|
||||
unused7, unused8, unused9, unused10);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_GenericCmd::GetRawSize() const
|
||||
{
|
||||
return 0x30;
|
||||
}
|
||||
|
||||
CutsceneCommand_GenericCmd::CutsceneCommand_GenericCmd(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex,
|
||||
CutsceneCommands cmdId)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
commandID = static_cast<uint32_t>(cmdId);
|
||||
entries.reserve(numEntries);
|
||||
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_GenericCmd(rawData, rawDataIndex, cmdId);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand_GenericCmd::GetCommandMacro() const
|
||||
{
|
||||
const auto& element = csCommandsDesc.find(static_cast<CutsceneCommands>(commandID));
|
||||
|
||||
if (element != csCommandsDesc.end())
|
||||
{
|
||||
return StringHelper::Sprintf("%s_LIST(%i)", element->second.cmdMacro, numEntries);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%X, %i)", commandID, numEntries);
|
||||
}
|
||||
|
||||
CutsceneCameraPoint::CutsceneCameraPoint(const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
continueFlag = BitConverter::ToInt8BE(rawData, rawDataIndex + 0);
|
||||
cameraRoll = BitConverter::ToInt8BE(rawData, rawDataIndex + 1);
|
||||
nextPointFrame = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
|
||||
viewAngle = BitConverter::ToFloatBE(rawData, rawDataIndex + 4);
|
||||
|
||||
posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 8);
|
||||
posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 10);
|
||||
posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 12);
|
||||
|
||||
unused = BitConverter::ToInt16BE(rawData, rawDataIndex + 14);
|
||||
}
|
||||
|
||||
std::string CutsceneCameraPoint::GetBodySourceCode() const
|
||||
{
|
||||
std::string result = "";
|
||||
|
||||
if (commandID == (int32_t)CutsceneCommands::SetCameraFocus)
|
||||
{
|
||||
result += "CS_CAM_FOCUS_POINT";
|
||||
}
|
||||
else if (commandID == (int32_t)CutsceneCommands::SetCameraFocusLink)
|
||||
{
|
||||
result += "CS_CAM_FOCUS_POINT_PLAYER";
|
||||
}
|
||||
else if (commandID == (int32_t)CutsceneCommands::SetCameraPosLink)
|
||||
{
|
||||
result += "CS_CAM_POS_PLAYER";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += "CS_CAM_POS";
|
||||
}
|
||||
|
||||
std::string continueMacro = "CS_CMD_CONTINUE";
|
||||
if (continueFlag != 0)
|
||||
continueMacro = "CS_CMD_STOP";
|
||||
|
||||
result +=
|
||||
StringHelper::Sprintf("(%s, 0x%02X, %i, %ff, %i, %i, %i, 0x%04X)", continueMacro.c_str(),
|
||||
cameraRoll, nextPointFrame, viewAngle, posX, posY, posZ, unused);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t CutsceneCameraPoint::GetRawSize() const
|
||||
{
|
||||
return 0x10;
|
||||
}
|
||||
|
||||
CutsceneCommandSetCameraPos::CutsceneCommandSetCameraPos(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
unused = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
|
||||
|
||||
bool shouldContinue = true;
|
||||
|
||||
uint32_t currentPtr = rawDataIndex + 8;
|
||||
|
||||
while (shouldContinue)
|
||||
{
|
||||
CutsceneCameraPoint* camPoint = new CutsceneCameraPoint(rawData, currentPtr);
|
||||
entries.push_back(camPoint);
|
||||
|
||||
if (camPoint->continueFlag == -1)
|
||||
shouldContinue = false;
|
||||
|
||||
currentPtr += camPoint->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommandSetCameraPos::GetCommandMacro() const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
std::string listStr;
|
||||
|
||||
if (commandID == (int32_t)CutsceneCommands::SetCameraFocus)
|
||||
{
|
||||
listStr = "CS_CAM_FOCUS_POINT_LIST";
|
||||
}
|
||||
else if (commandID == (int32_t)CutsceneCommands::SetCameraFocusLink)
|
||||
{
|
||||
listStr = "CS_CAM_FOCUS_POINT_PLAYER_LIST";
|
||||
}
|
||||
else if (commandID == (int32_t)CutsceneCommands::SetCameraPosLink)
|
||||
{
|
||||
listStr = "CS_CAM_POS_PLAYER_LIST";
|
||||
}
|
||||
else
|
||||
{
|
||||
listStr = "CS_CAM_POS_LIST";
|
||||
}
|
||||
|
||||
result += StringHelper::Sprintf("%s(%i, %i)", listStr.c_str(), startFrame, endFrame);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t CutsceneCommandSetCameraPos::GetCommandSize() const
|
||||
{
|
||||
return 0x0C + entries.at(0)->GetRawSize() * entries.size();
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_Rumble::CutsceneSubCommandEntry_Rumble(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
unk_06 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x06);
|
||||
unk_07 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x07);
|
||||
unk_08 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08);
|
||||
unk_09 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x09);
|
||||
unk_0A = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0A);
|
||||
unk_0B = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x0B);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_Rumble::GetBodySourceCode() const
|
||||
{
|
||||
if (Globals::Instance->game == ZGame::MM_RETAIL)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_RUMBLE(%i, %i, %i, 0x%02X, 0x%02X, 0x%02X)", base,
|
||||
startFrame, endFrame, unk_06, unk_07, unk_08);
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_CMD_09(%i, %i, %i, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X)",
|
||||
base, startFrame, endFrame, unk_06, unk_07, unk_08, unk_09, unk_0A,
|
||||
unk_0B);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_Rumble::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneCommand_Rumble::CutsceneCommand_Rumble(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_Rumble(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand_Rumble::GetCommandMacro() const
|
||||
{
|
||||
if (Globals::Instance->game == ZGame::MM_RETAIL)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_RUMBLE_LIST(%i)", numEntries);
|
||||
}
|
||||
return StringHelper::Sprintf("CS_CMD_09_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_SetTime::CutsceneSubCommandEntry_SetTime(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
hour = BitConverter::ToUInt8BE(rawData, rawDataIndex + 6);
|
||||
minute = BitConverter::ToUInt8BE(rawData, rawDataIndex + 7);
|
||||
unk_08 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_SetTime::GetBodySourceCode() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TIME(%i, %i, %i, %i, %i, %i)", base, startFrame, endFrame,
|
||||
hour, minute, unk_08);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_SetTime::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneCommand_SetTime::CutsceneCommand_SetTime(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_SetTime(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand_SetTime::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TIME_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_TextBox::CutsceneSubCommandEntry_TextBox(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
type = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6);
|
||||
textId1 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8);
|
||||
textId2 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_TextBox::GetBodySourceCode() const
|
||||
{
|
||||
if (type == 0xFFFF)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TEXT_NONE(%i, %i)", startFrame, endFrame);
|
||||
}
|
||||
if (type == 2)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TEXT_LEARN_SONG(%i, %i, %i, 0x%X)", base, startFrame,
|
||||
endFrame, textId1);
|
||||
}
|
||||
|
||||
if (Globals::Instance->game == ZGame::MM_RETAIL)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 0:
|
||||
return StringHelper::Sprintf("CS_TEXT_DEFAULT(0x%X, %i, %i, 0x%X, 0x%X)", base,
|
||||
startFrame, endFrame, textId1, textId2);
|
||||
|
||||
case 1:
|
||||
return StringHelper::Sprintf("CS_TEXT_TYPE_1(0x%X, %i, %i, 0x%X, 0x%X)", base,
|
||||
startFrame, endFrame, textId1, textId2);
|
||||
|
||||
case 3:
|
||||
return StringHelper::Sprintf("CS_TEXT_TYPE_3(0x%X, %i, %i, 0x%X, 0x%X)", base,
|
||||
startFrame, endFrame, textId1, textId2);
|
||||
|
||||
case 4:
|
||||
return StringHelper::Sprintf("CS_TEXT_BOSSES_REMAINS(0x%X, %i, %i, 0x%X)", base,
|
||||
startFrame, endFrame, textId1);
|
||||
|
||||
case 5:
|
||||
return StringHelper::Sprintf("CS_TEXT_ALL_NORMAL_MASKS(0x%X, %i, %i, 0x%X)", base,
|
||||
startFrame, endFrame, textId1);
|
||||
}
|
||||
}
|
||||
|
||||
return StringHelper::Sprintf("CS_TEXT_DISPLAY_TEXTBOX(0x%X, %i, %i, %i, 0x%X, 0x%X)", base,
|
||||
startFrame, endFrame, type, textId1, textId2);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_TextBox::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneCommand_TextBox::CutsceneCommand_TextBox(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_TextBox(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand_TextBox::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TEXT_LIST(%i)", numEntries);
|
||||
}
|
||||
|
||||
CutsceneSubCommandEntry_ActorAction::CutsceneSubCommandEntry_ActorAction(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6);
|
||||
rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8);
|
||||
rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA);
|
||||
startPosX = BitConverter::ToInt32BE(rawData, rawDataIndex + 0xC);
|
||||
startPosY = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x10);
|
||||
startPosZ = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x14);
|
||||
endPosX = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x18);
|
||||
endPosY = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x1C);
|
||||
endPosZ = BitConverter::ToInt32BE(rawData, rawDataIndex + 0x20);
|
||||
normalX = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x24);
|
||||
normalY = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x28);
|
||||
normalZ = BitConverter::ToFloatBE(rawData, rawDataIndex + 0x2C);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_ActorAction::GetBodySourceCode() const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
if (Globals::Instance->game == ZGame::MM_RETAIL)
|
||||
{
|
||||
if (static_cast<CutsceneMMCommands>(commandID) ==
|
||||
CutsceneMMCommands::CS_CMD_SET_PLAYER_ACTION)
|
||||
{
|
||||
result = "CS_PLAYER_ACTION";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "CS_ACTOR_ACTION";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (static_cast<CutsceneCommands>(commandID) == CutsceneCommands::SetPlayerAction)
|
||||
{
|
||||
result = "CS_PLAYER_ACTION";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "CS_NPC_ACTION";
|
||||
}
|
||||
}
|
||||
|
||||
result +=
|
||||
StringHelper::Sprintf("(%i, %i, %i, 0x%04X, 0x%04X, 0x%04X, %i, %i, "
|
||||
"%i, %i, %i, %i, %.11ef, %.11ef, %.11ef)",
|
||||
base, startFrame, endFrame, rotX, rotY, rotZ, startPosX, startPosY,
|
||||
startPosZ, endPosX, endPosY, endPosZ, normalX, normalY, normalZ);
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_ActorAction::GetRawSize() const
|
||||
{
|
||||
return 0x30;
|
||||
}
|
||||
|
||||
CutsceneCommand_ActorAction::CutsceneCommand_ActorAction(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_ActorAction(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand_ActorAction::GetCommandMacro() const
|
||||
{
|
||||
if (Globals::Instance->game == ZGame::MM_RETAIL)
|
||||
{
|
||||
if (static_cast<CutsceneMMCommands>(commandID) ==
|
||||
CutsceneMMCommands::CS_CMD_SET_PLAYER_ACTION)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_PLAYER_ACTION_LIST(%i)", numEntries);
|
||||
}
|
||||
return StringHelper::Sprintf("CS_ACTOR_ACTION_LIST(0x%03X, %i)", commandID, numEntries);
|
||||
}
|
||||
|
||||
if (static_cast<CutsceneCommands>(commandID) == CutsceneCommands::SetPlayerAction)
|
||||
{
|
||||
return StringHelper::Sprintf("CS_PLAYER_ACTION_LIST(%i)", entries.size());
|
||||
}
|
||||
return StringHelper::Sprintf("CS_NPC_ACTION_LIST(0x%03X, %i)", commandID, entries.size());
|
||||
}
|
||||
|
||||
CutsceneCommand_Terminator::CutsceneCommand_Terminator(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
unknown = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6); // endFrame duplicate
|
||||
}
|
||||
|
||||
std::string CutsceneCommand_Terminator::GenerateSourceCode() const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
result += StringHelper::Sprintf("CS_TERMINATOR(%i, %i, %i),\n", base, startFrame, endFrame);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t CutsceneCommand_Terminator::GetCommandSize() const
|
||||
{
|
||||
return 0x10;
|
||||
}
|
||||
|
||||
CutsceneCommandSceneTransFX::CutsceneCommandSceneTransFX(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
}
|
||||
|
||||
std::string CutsceneCommandSceneTransFX::GenerateSourceCode() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_SCENE_TRANS_FX(%i, %i, %i),\n", base, startFrame, endFrame);
|
||||
}
|
||||
|
||||
size_t CutsceneCommandSceneTransFX::GetCommandSize() const
|
||||
{
|
||||
return 0x10;
|
||||
}
|
||||
267
ZAPDTR/ZAPD/OtherStructs/Cutscene_Commands.h
Normal file
267
ZAPDTR/ZAPD/OtherStructs/Cutscene_Commands.h
Normal file
@@ -0,0 +1,267 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Declaration.h"
|
||||
|
||||
enum class CutsceneCommands
|
||||
{
|
||||
SetCameraPos = 0x0001,
|
||||
SetCameraFocus = 0x0002,
|
||||
Misc = 0x0003,
|
||||
SetLighting = 0x0004,
|
||||
SetCameraPosLink = 0x0005,
|
||||
SetCameraFocusLink = 0x0006,
|
||||
Cmd07 = 0x0007,
|
||||
Cmd08 = 0x0008,
|
||||
Cmd09 = 0x0009, // Rumble
|
||||
Textbox = 0x0013,
|
||||
SetPlayerAction = 0x000A,
|
||||
SetActorAction1 = 0x000F,
|
||||
SetActorAction2 = 0x000E,
|
||||
SetActorAction3 = 0x0019,
|
||||
SetActorAction4 = 0x001D,
|
||||
SetActorAction5 = 0x001E,
|
||||
SetActorAction6 = 0x002C,
|
||||
SetActorAction7 = 0x001F,
|
||||
SetActorAction8 = 0x0031,
|
||||
SetActorAction9 = 0x003E,
|
||||
SetActorAction10 = 0x008F,
|
||||
SetSceneTransFX = 0x002D,
|
||||
PlayBGM = 0x0056,
|
||||
StopBGM = 0x0057,
|
||||
FadeBGM = 0x007C,
|
||||
SetTime = 0x008C,
|
||||
Terminator = 0x03E8,
|
||||
};
|
||||
|
||||
typedef struct CsCommandListDescriptor
|
||||
{
|
||||
const char* cmdMacro;
|
||||
const char* args;
|
||||
} CsCommandListDescriptor;
|
||||
|
||||
class CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
uint16_t pad;
|
||||
|
||||
uint32_t commandID;
|
||||
|
||||
CutsceneSubCommandEntry(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
virtual ~CutsceneSubCommandEntry() = default;
|
||||
|
||||
virtual std::string GetBodySourceCode() const;
|
||||
|
||||
virtual size_t GetRawSize() const;
|
||||
};
|
||||
|
||||
class CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint32_t commandID;
|
||||
uint32_t commandIndex;
|
||||
|
||||
uint32_t numEntries;
|
||||
std::vector<CutsceneSubCommandEntry*> entries;
|
||||
|
||||
CutsceneCommand(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
virtual ~CutsceneCommand();
|
||||
|
||||
virtual std::string GetCommandMacro() const;
|
||||
virtual std::string GenerateSourceCode() const;
|
||||
virtual size_t GetCommandSize() const;
|
||||
|
||||
virtual void SetCommandID(uint32_t nCommandID);
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_GenericCmd : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
CutsceneCommands commandId;
|
||||
|
||||
uint32_t word0 = 0;
|
||||
uint32_t word1 = 0;
|
||||
|
||||
uint32_t unused1 = 0;
|
||||
uint32_t unused2 = 0;
|
||||
uint32_t unused3 = 0;
|
||||
uint32_t unused4 = 0;
|
||||
uint32_t unused5 = 0;
|
||||
uint32_t unused6 = 0;
|
||||
uint32_t unused7 = 0;
|
||||
uint32_t unused8 = 0;
|
||||
uint32_t unused9 = 0;
|
||||
uint32_t unused10 = 0;
|
||||
|
||||
CutsceneSubCommandEntry_GenericCmd(const std::vector<uint8_t>& rawData, offset_t rawDataIndex,
|
||||
CutsceneCommands cmdId);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommand_GenericCmd : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneCommand_GenericCmd(const std::vector<uint8_t>& rawData, offset_t rawDataIndex,
|
||||
CutsceneCommands cmdId);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneCameraPoint : public CutsceneSubCommandEntry
|
||||
{
|
||||
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, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommandSetCameraPos : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
uint16_t unused;
|
||||
|
||||
CutsceneCommandSetCameraPos(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
|
||||
size_t GetCommandSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommandSceneTransFX : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
|
||||
CutsceneCommandSceneTransFX(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GenerateSourceCode() const override;
|
||||
size_t GetCommandSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_Rumble : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint8_t unk_06;
|
||||
uint8_t unk_07;
|
||||
uint8_t unk_08;
|
||||
uint8_t unk_09;
|
||||
uint8_t unk_0A;
|
||||
uint8_t unk_0B;
|
||||
|
||||
CutsceneSubCommandEntry_Rumble(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommand_Rumble : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneCommand_Rumble(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_SetTime : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
uint32_t unk_08;
|
||||
|
||||
CutsceneSubCommandEntry_SetTime(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommand_SetTime : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneCommand_SetTime(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_TextBox : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint16_t type;
|
||||
uint16_t textId1;
|
||||
uint16_t textId2;
|
||||
|
||||
CutsceneSubCommandEntry_TextBox(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommand_TextBox : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneCommand_TextBox(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneSubCommandEntry_ActorAction : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint16_t rotX, rotY, rotZ;
|
||||
int32_t startPosX, startPosY, startPosZ;
|
||||
int32_t endPosX, endPosY, endPosZ;
|
||||
float normalX, normalY, normalZ;
|
||||
|
||||
CutsceneSubCommandEntry_ActorAction(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommand_ActorAction : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneCommand_ActorAction(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommand_Terminator : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
uint16_t unknown;
|
||||
|
||||
CutsceneCommand_Terminator(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GenerateSourceCode() const override;
|
||||
size_t GetCommandSize() const override;
|
||||
};
|
||||
128
ZAPDTR/ZAPD/OtherStructs/Cutscene_Common.cpp
Normal file
128
ZAPDTR/ZAPD/OtherStructs/Cutscene_Common.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include "Cutscene_Common.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
/* CutsceneSubCommandEntry */
|
||||
|
||||
CutsceneSubCommandEntry::CutsceneSubCommandEntry(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
{
|
||||
base = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
startFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
endFrame = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
pad = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry::GetBodySourceCode() const
|
||||
{
|
||||
return StringHelper::Sprintf("CMD_HH(0x%04X, 0x%04X), CMD_HH(0x%04X, 0x%04X)", base, startFrame,
|
||||
endFrame, pad);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry::GetRawSize() const
|
||||
{
|
||||
return 0x08;
|
||||
}
|
||||
|
||||
/* CutsceneCommand */
|
||||
|
||||
CutsceneCommand::CutsceneCommand(const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
{
|
||||
numEntries = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0);
|
||||
}
|
||||
|
||||
CutsceneCommand::~CutsceneCommand()
|
||||
{
|
||||
for (auto entry : entries)
|
||||
{
|
||||
delete entry;
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CMD_W(0x%08X), CMD_W(0x%08X)", commandID, numEntries);
|
||||
}
|
||||
|
||||
std::string CutsceneCommand::GenerateSourceCode() const
|
||||
{
|
||||
std::string result;
|
||||
|
||||
result += GetCommandMacro();
|
||||
result += ",\n";
|
||||
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
result += " ";
|
||||
result += entry->GetBodySourceCode();
|
||||
result += ",\n";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
size_t CutsceneCommand::GetCommandSize() const
|
||||
{
|
||||
size_t size = 0;
|
||||
if (entries.size() > 0)
|
||||
{
|
||||
size = entries.at(0)->GetRawSize() * entries.size();
|
||||
}
|
||||
else
|
||||
{
|
||||
size = 0x08 * numEntries;
|
||||
}
|
||||
return 0x08 + size;
|
||||
}
|
||||
|
||||
void CutsceneCommand::SetCommandID(uint32_t nCommandID)
|
||||
{
|
||||
commandID = nCommandID;
|
||||
|
||||
for (auto& entry : entries)
|
||||
{
|
||||
entry->commandID = commandID;
|
||||
}
|
||||
}
|
||||
|
||||
/*** TIME ****/
|
||||
|
||||
CutsceneSubCommandEntry_SetTime::CutsceneSubCommandEntry_SetTime(
|
||||
const std::vector<uint8_t>& rawData, offset_t rawDataIndex)
|
||||
: CutsceneSubCommandEntry(rawData, rawDataIndex)
|
||||
{
|
||||
hour = BitConverter::ToUInt8BE(rawData, rawDataIndex + 6);
|
||||
minute = BitConverter::ToUInt8BE(rawData, rawDataIndex + 7);
|
||||
}
|
||||
|
||||
std::string CutsceneSubCommandEntry_SetTime::GetBodySourceCode() const
|
||||
{
|
||||
// Note: Both OoT and MM have the first argument unused
|
||||
return StringHelper::Sprintf("CS_TIME(%i, %i, %i, %i, %i)", base, startFrame, endFrame, hour,
|
||||
minute);
|
||||
}
|
||||
|
||||
size_t CutsceneSubCommandEntry_SetTime::GetRawSize() const
|
||||
{
|
||||
return 0x0C;
|
||||
}
|
||||
|
||||
CutsceneCommand_Time::CutsceneCommand_Time(const std::vector<uint8_t>& rawData,
|
||||
offset_t rawDataIndex)
|
||||
: CutsceneCommand(rawData, rawDataIndex)
|
||||
{
|
||||
rawDataIndex += 4;
|
||||
|
||||
entries.reserve(numEntries);
|
||||
for (size_t i = 0; i < numEntries; i++)
|
||||
{
|
||||
auto* entry = new CutsceneSubCommandEntry_SetTime(rawData, rawDataIndex);
|
||||
entries.push_back(entry);
|
||||
rawDataIndex += entry->GetRawSize();
|
||||
}
|
||||
}
|
||||
|
||||
std::string CutsceneCommand_Time::GetCommandMacro() const
|
||||
{
|
||||
return StringHelper::Sprintf("CS_TIME_LIST(%i)", numEntries);
|
||||
}
|
||||
72
ZAPDTR/ZAPD/OtherStructs/Cutscene_Common.h
Normal file
72
ZAPDTR/ZAPD/OtherStructs/Cutscene_Common.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Declaration.h"
|
||||
|
||||
typedef struct CsCommandListDescriptor
|
||||
{
|
||||
const char* cmdMacro;
|
||||
const char* args;
|
||||
} CsCommandListDescriptor;
|
||||
|
||||
class CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint16_t base;
|
||||
uint16_t startFrame;
|
||||
uint16_t endFrame;
|
||||
uint16_t pad;
|
||||
|
||||
uint32_t commandID;
|
||||
|
||||
CutsceneSubCommandEntry(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
virtual ~CutsceneSubCommandEntry() = default;
|
||||
|
||||
virtual std::string GetBodySourceCode() const;
|
||||
|
||||
virtual size_t GetRawSize() const;
|
||||
};
|
||||
|
||||
class CutsceneCommand
|
||||
{
|
||||
public:
|
||||
uint32_t commandID;
|
||||
uint32_t commandIndex;
|
||||
|
||||
uint32_t numEntries;
|
||||
std::vector<CutsceneSubCommandEntry*> entries;
|
||||
|
||||
CutsceneCommand(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
virtual ~CutsceneCommand();
|
||||
|
||||
virtual std::string GetCommandMacro() const;
|
||||
virtual std::string GenerateSourceCode() const;
|
||||
virtual size_t GetCommandSize() const;
|
||||
|
||||
virtual void SetCommandID(uint32_t nCommandID);
|
||||
};
|
||||
|
||||
/**** TIME ****/
|
||||
|
||||
class CutsceneSubCommandEntry_SetTime : public CutsceneSubCommandEntry
|
||||
{
|
||||
public:
|
||||
uint8_t hour;
|
||||
uint8_t minute;
|
||||
|
||||
CutsceneSubCommandEntry_SetTime(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
size_t GetRawSize() const override;
|
||||
};
|
||||
|
||||
class CutsceneCommand_Time : public CutsceneCommand
|
||||
{
|
||||
public:
|
||||
CutsceneCommand_Time(const std::vector<uint8_t>& rawData, offset_t rawDataIndex);
|
||||
|
||||
std::string GetCommandMacro() const override;
|
||||
};
|
||||
352
ZAPDTR/ZAPD/OtherStructs/SkinLimbStructs.cpp
Normal file
352
ZAPDTR/ZAPD/OtherStructs/SkinLimbStructs.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
#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);
|
||||
|
||||
unk_8_arr.reserve(unk_0);
|
||||
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);
|
||||
|
||||
unk_C_arr.reserve(unk_2);
|
||||
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,
|
||||
parent->workerID);
|
||||
Globals::Instance->GetSegmentedPtrName(unk_C, parent, "Struct_800A598C_2", unk_C_Str,
|
||||
parent->workerID);
|
||||
|
||||
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);
|
||||
|
||||
unk_4_arr.reserve(unk_2);
|
||||
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,
|
||||
parent->workerID);
|
||||
Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Gfx", unk_8_Str, parent->workerID);
|
||||
|
||||
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;
|
||||
}
|
||||
114
ZAPDTR/ZAPD/OtherStructs/SkinLimbStructs.h
Normal file
114
ZAPDTR/ZAPD/OtherStructs/SkinLimbStructs.h
Normal 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;
|
||||
};
|
||||
123
ZAPDTR/ZAPD/OutputFormatter.cpp
Normal file
123
ZAPDTR/ZAPD/OutputFormatter.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#include "OutputFormatter.h"
|
||||
#include <Globals.h>
|
||||
|
||||
void OutputFormatter::Flush()
|
||||
{
|
||||
//if (!Globals::Instance->otrMode) // OTRTODO: MULTITHREADING
|
||||
{
|
||||
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)
|
||||
{
|
||||
// OTRTODO
|
||||
//if (!Globals::Instance->singleThreaded)
|
||||
//return 0;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
thread_local 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);
|
||||
}
|
||||
41
ZAPDTR/ZAPD/OutputFormatter.h
Normal file
41
ZAPDTR/ZAPD/OutputFormatter.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
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 thread_local 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();
|
||||
};
|
||||
354
ZAPDTR/ZAPD/Overlays/ZOverlay.cpp
Normal file
354
ZAPDTR/ZAPD/Overlays/ZOverlay.cpp
Normal file
@@ -0,0 +1,354 @@
|
||||
#if 0
|
||||
#include "ZOverlay.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <unordered_set>
|
||||
#include "Globals.h"
|
||||
#include "Utils/Directory.h"
|
||||
#include <Utils/DiskFile.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 = DiskFile::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;
|
||||
}
|
||||
#endif
|
||||
78
ZAPDTR/ZAPD/Overlays/ZOverlay.h
Normal file
78
ZAPDTR/ZAPD/Overlays/ZOverlay.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#pragma once
|
||||
|
||||
#if 0
|
||||
|
||||
#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);
|
||||
};
|
||||
#endif
|
||||
178
ZAPDTR/ZAPD/Utils/BinaryReader.cpp
Normal file
178
ZAPDTR/ZAPD/Utils/BinaryReader.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "BinaryReader.h"
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include "Stream.h"
|
||||
|
||||
BinaryReader::BinaryReader(Stream* nStream)
|
||||
{
|
||||
stream.reset(nStream);
|
||||
}
|
||||
|
||||
BinaryReader::BinaryReader(std::shared_ptr<Stream> nStream)
|
||||
{
|
||||
stream = nStream;
|
||||
}
|
||||
|
||||
void BinaryReader::Close()
|
||||
{
|
||||
stream->Close();
|
||||
}
|
||||
|
||||
void BinaryReader::SetEndianness(Endianness endianness)
|
||||
{
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
Endianness BinaryReader::GetEndianness() const
|
||||
{
|
||||
return endianness;
|
||||
}
|
||||
|
||||
void BinaryReader::Seek(uint32_t offset, SeekOffsetType seekType)
|
||||
{
|
||||
stream->Seek(offset, seekType);
|
||||
}
|
||||
|
||||
uint32_t BinaryReader::GetBaseAddress()
|
||||
{
|
||||
return stream->GetBaseAddress();
|
||||
}
|
||||
|
||||
void BinaryReader::Read(int32_t length)
|
||||
{
|
||||
stream->Read(length);
|
||||
}
|
||||
|
||||
void BinaryReader::Read(char* buffer, int32_t length)
|
||||
{
|
||||
stream->Read(buffer, length);
|
||||
}
|
||||
|
||||
char BinaryReader::ReadChar()
|
||||
{
|
||||
return (char)stream->ReadByte();
|
||||
}
|
||||
|
||||
int8_t BinaryReader::ReadByte()
|
||||
{
|
||||
return stream->ReadByte();
|
||||
}
|
||||
|
||||
uint8_t BinaryReader::ReadUByte()
|
||||
{
|
||||
return (uint8_t)stream->ReadByte();
|
||||
}
|
||||
|
||||
int16_t BinaryReader::ReadInt16()
|
||||
{
|
||||
int16_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(int16_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP16(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t BinaryReader::ReadInt32()
|
||||
{
|
||||
int32_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(int32_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP32(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint16_t BinaryReader::ReadUInt16()
|
||||
{
|
||||
uint16_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint16_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP16(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t BinaryReader::ReadUInt32()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint32_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP32(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t BinaryReader::ReadUInt64()
|
||||
{
|
||||
uint64_t result = 0;
|
||||
|
||||
stream->Read((char*)&result, sizeof(uint64_t));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
result = BSWAP64(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float BinaryReader::ReadSingle()
|
||||
{
|
||||
float result = NAN;
|
||||
|
||||
stream->Read((char*)&result, sizeof(float));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
float tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&result;
|
||||
dst[3] = src[0]; dst[2] = src[1]; dst[1] = src[2]; dst[0] = src[3];
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
if (std::isnan(result))
|
||||
throw std::runtime_error("BinaryReader::ReadSingle(): Error reading stream");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
double BinaryReader::ReadDouble()
|
||||
{
|
||||
double result = NAN;
|
||||
|
||||
stream->Read((char*)&result, sizeof(double));
|
||||
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
double tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&result;
|
||||
dst[7] = src[0]; dst[6] = src[1]; dst[5] = src[2]; dst[4] = src[3];
|
||||
dst[3] = src[4]; dst[2] = src[5]; dst[1] = src[6]; dst[0] = src[7];
|
||||
result = tmp;
|
||||
}
|
||||
|
||||
if (std::isnan(result))
|
||||
throw std::runtime_error("BinaryReader::ReadDouble(): Error reading stream");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string BinaryReader::ReadString()
|
||||
{
|
||||
std::string res;
|
||||
int numChars = ReadInt32();
|
||||
|
||||
for (int i = 0; i < numChars; i++)
|
||||
res += ReadChar();
|
||||
|
||||
return res;
|
||||
}
|
||||
41
ZAPDTR/ZAPD/Utils/BinaryReader.h
Normal file
41
ZAPDTR/ZAPD/Utils/BinaryReader.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "BitConverter.h"
|
||||
#include "Stream.h"
|
||||
|
||||
class BinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryReader(Stream* nStream);
|
||||
BinaryReader(std::shared_ptr<Stream> nStream);
|
||||
|
||||
void Close();
|
||||
|
||||
void SetEndianness(Endianness endianness);
|
||||
Endianness GetEndianness() const;
|
||||
|
||||
void Seek(uint32_t offset, SeekOffsetType seekType);
|
||||
uint32_t GetBaseAddress();
|
||||
|
||||
void Read(int32_t length);
|
||||
void Read(char* buffer, int32_t length);
|
||||
char ReadChar();
|
||||
int8_t ReadByte();
|
||||
int16_t ReadInt16();
|
||||
int32_t ReadInt32();
|
||||
uint8_t ReadUByte();
|
||||
uint16_t ReadUInt16();
|
||||
uint32_t ReadUInt32();
|
||||
uint64_t ReadUInt64();
|
||||
float ReadSingle();
|
||||
double ReadDouble();
|
||||
std::string ReadString();
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Stream> stream;
|
||||
Endianness endianness = Endianness::Native;
|
||||
};
|
||||
148
ZAPDTR/ZAPD/Utils/BinaryWriter.cpp
Normal file
148
ZAPDTR/ZAPD/Utils/BinaryWriter.cpp
Normal file
@@ -0,0 +1,148 @@
|
||||
#include "BinaryWriter.h"
|
||||
|
||||
BinaryWriter::BinaryWriter(Stream* nStream)
|
||||
{
|
||||
stream.reset(nStream);
|
||||
}
|
||||
|
||||
BinaryWriter::BinaryWriter(std::shared_ptr<Stream> nStream)
|
||||
{
|
||||
stream = nStream;
|
||||
}
|
||||
|
||||
void BinaryWriter::SetEndianness(Endianness endianness)
|
||||
{
|
||||
this->endianness = endianness;
|
||||
}
|
||||
|
||||
void BinaryWriter::Close()
|
||||
{
|
||||
stream->Close();
|
||||
}
|
||||
|
||||
std::shared_ptr<Stream> BinaryWriter::GetStream()
|
||||
{
|
||||
return stream;
|
||||
}
|
||||
|
||||
uint64_t BinaryWriter::GetBaseAddress()
|
||||
{
|
||||
return stream->GetBaseAddress();
|
||||
}
|
||||
|
||||
uint64_t BinaryWriter::GetLength()
|
||||
{
|
||||
return stream->GetLength();
|
||||
}
|
||||
|
||||
void BinaryWriter::Seek(int32_t offset, SeekOffsetType seekType)
|
||||
{
|
||||
stream->Seek(offset, seekType);
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int8_t value)
|
||||
{
|
||||
stream->Write((char*)&value, sizeof(int8_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint8_t value)
|
||||
{
|
||||
stream->Write((char*)&value, sizeof(uint8_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int16_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP16(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint16_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP16(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int32_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP32(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int32_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int32_t valueA, int32_t valueB)
|
||||
{
|
||||
Write(valueA);
|
||||
Write(valueB);
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint32_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP32(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(int64_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP64(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(int64_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(uint64_t value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
value = BSWAP64(value);
|
||||
|
||||
stream->Write((char*)&value, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(float value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
float tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&value;
|
||||
dst[3] = src[0]; dst[2] = src[1]; dst[1] = src[2]; dst[0] = src[3];
|
||||
value = tmp;
|
||||
}
|
||||
|
||||
stream->Write((char*)&value, sizeof(float));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(double value)
|
||||
{
|
||||
if (endianness != Endianness::Native)
|
||||
{
|
||||
double tmp;
|
||||
char* dst = (char*)&tmp;
|
||||
char* src = (char*)&value;
|
||||
dst[7] = src[0]; dst[6] = src[1]; dst[5] = src[2]; dst[4] = src[3];
|
||||
dst[3] = src[4]; dst[2] = src[5]; dst[1] = src[6]; dst[0] = src[7];
|
||||
value = tmp;
|
||||
}
|
||||
|
||||
stream->Write((char*)&value, sizeof(double));
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(const std::string& str)
|
||||
{
|
||||
int strLen = str.size();
|
||||
Write(strLen);
|
||||
|
||||
for (char c : str)
|
||||
stream->WriteByte(c);
|
||||
}
|
||||
|
||||
void BinaryWriter::Write(char* srcBuffer, size_t length)
|
||||
{
|
||||
stream->Write(srcBuffer, length);
|
||||
}
|
||||
41
ZAPDTR/ZAPD/Utils/BinaryWriter.h
Normal file
41
ZAPDTR/ZAPD/Utils/BinaryWriter.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "BitConverter.h"
|
||||
#include "Stream.h"
|
||||
|
||||
class BinaryWriter
|
||||
{
|
||||
public:
|
||||
BinaryWriter(Stream* nStream);
|
||||
BinaryWriter(std::shared_ptr<Stream> nStream);
|
||||
|
||||
void SetEndianness(Endianness endianness);
|
||||
|
||||
std::shared_ptr<Stream> GetStream();
|
||||
uint64_t GetBaseAddress();
|
||||
uint64_t GetLength();
|
||||
void Seek(int32_t offset, SeekOffsetType seekType);
|
||||
void Close();
|
||||
|
||||
void Write(int8_t value);
|
||||
void Write(uint8_t value);
|
||||
void Write(int16_t value);
|
||||
void Write(uint16_t value);
|
||||
void Write(int32_t value);
|
||||
void Write(int32_t valueA, int32_t valueB);
|
||||
void Write(uint32_t value);
|
||||
void Write(int64_t value);
|
||||
void Write(uint64_t value);
|
||||
void Write(float value);
|
||||
void Write(double value);
|
||||
void Write(const std::string& str);
|
||||
void Write(char* srcBuffer, size_t length);
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Stream> stream;
|
||||
Endianness endianness = Endianness::Native;
|
||||
};
|
||||
209
ZAPDTR/ZAPD/Utils/BitConverter.h
Normal file
209
ZAPDTR/ZAPD/Utils/BitConverter.h
Normal file
@@ -0,0 +1,209 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define BSWAP16 _byteswap_ushort
|
||||
#define BSWAP32 _byteswap_ulong
|
||||
#define BSWAP64 _byteswap_uint64
|
||||
#else
|
||||
#define BSWAP16 __builtin_bswap16
|
||||
#define BSWAP32 __builtin_bswap32
|
||||
#define BSWAP64 __builtin_bswap64
|
||||
#endif
|
||||
|
||||
enum class Endianness
|
||||
{
|
||||
Little = 0,
|
||||
Big = 1,
|
||||
|
||||
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || defined(__BIG_ENDIAN__)
|
||||
Native = Big,
|
||||
#else
|
||||
Native = Little,
|
||||
#endif
|
||||
};
|
||||
|
||||
class BitConverter
|
||||
{
|
||||
public:
|
||||
static inline int8_t ToInt8BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return (uint8_t)data[offset + 0];
|
||||
}
|
||||
|
||||
static inline int8_t ToInt8BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return (uint8_t)data[offset + 0];
|
||||
}
|
||||
|
||||
static inline uint8_t ToUInt8BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return (uint8_t)data[offset + 0];
|
||||
}
|
||||
|
||||
static inline uint8_t ToUInt8BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return (uint8_t)data[offset + 0];
|
||||
}
|
||||
|
||||
static inline int16_t ToInt16BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
|
||||
}
|
||||
|
||||
static inline int16_t ToInt16BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
|
||||
}
|
||||
|
||||
static inline uint16_t ToUInt16BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
|
||||
}
|
||||
|
||||
static inline uint16_t ToUInt16BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return ((uint16_t)data[offset + 0] << 8) + (uint16_t)data[offset + 1];
|
||||
}
|
||||
|
||||
static inline int32_t ToInt32BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
|
||||
((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
|
||||
}
|
||||
|
||||
static inline int32_t ToInt32BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
|
||||
((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
|
||||
}
|
||||
|
||||
static inline uint32_t ToUInt32BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
|
||||
((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
|
||||
}
|
||||
|
||||
static inline uint32_t ToUInt32BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return ((uint32_t)data[offset + 0] << 24) + ((uint32_t)data[offset + 1] << 16) +
|
||||
((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
|
||||
}
|
||||
|
||||
static inline int64_t ToInt64BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
|
||||
((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
|
||||
((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
|
||||
((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
|
||||
}
|
||||
|
||||
static inline int64_t ToInt64BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
|
||||
((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
|
||||
((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
|
||||
((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
|
||||
}
|
||||
|
||||
static inline uint64_t ToUInt64BE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
|
||||
((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
|
||||
((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
|
||||
((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
|
||||
}
|
||||
|
||||
static inline uint64_t ToUInt64BE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
return ((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
|
||||
((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
|
||||
((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
|
||||
((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
|
||||
}
|
||||
|
||||
static inline float ToFloatBE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
float value;
|
||||
uint32_t floatData = ((uint32_t)data[offset + 0] << 24) +
|
||||
((uint32_t)data[offset + 1] << 16) +
|
||||
((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
|
||||
static_assert(sizeof(uint32_t) == sizeof(float), "expected 32-bit float");
|
||||
std::memcpy(&value, &floatData, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline float ToFloatBE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
float value;
|
||||
uint32_t floatData = ((uint32_t)data[offset + 0] << 24) +
|
||||
((uint32_t)data[offset + 1] << 16) +
|
||||
((uint32_t)data[offset + 2] << 8) + (uint32_t)data[offset + 3];
|
||||
static_assert(sizeof(uint32_t) == sizeof(float), "expected 32-bit float");
|
||||
std::memcpy(&value, &floatData, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline double ToDoubleBE(const uint8_t* data, int32_t offset)
|
||||
{
|
||||
double value;
|
||||
uint64_t floatData =
|
||||
((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
|
||||
((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
|
||||
((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
|
||||
((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
|
||||
static_assert(sizeof(uint64_t) == sizeof(double), "expected 64-bit double");
|
||||
// Checks if the float format on the platform the ZAPD binary is running on supports the
|
||||
// same float format as the object file.
|
||||
static_assert(std::numeric_limits<float>::is_iec559,
|
||||
"expected IEC559 floats on host machine");
|
||||
std::memcpy(&value, &floatData, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline double ToDoubleBE(const std::vector<uint8_t>& data, int32_t offset)
|
||||
{
|
||||
double value;
|
||||
uint64_t floatData =
|
||||
((uint64_t)data[offset + 0] << 56) + ((uint64_t)data[offset + 1] << 48) +
|
||||
((uint64_t)data[offset + 2] << 40) + ((uint64_t)data[offset + 3] << 32) +
|
||||
((uint64_t)data[offset + 4] << 24) + ((uint64_t)data[offset + 5] << 16) +
|
||||
((uint64_t)data[offset + 6] << 8) + ((uint64_t)data[offset + 7]);
|
||||
static_assert(sizeof(uint64_t) == sizeof(double), "expected 64-bit double");
|
||||
// Checks if the float format on the platform the ZAPD binary is running on supports the
|
||||
// same float format as the object file.
|
||||
static_assert(std::numeric_limits<double>::is_iec559,
|
||||
"expected IEC559 doubles on host machine");
|
||||
std::memcpy(&value, &floatData, sizeof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
// Rewrites the rom data in-place to be in BigEndian/z64 format
|
||||
static inline void RomToBigEndian(uint8_t* rom, size_t romSize) {
|
||||
if (romSize <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the first byte to determine byte order
|
||||
uint8_t firstByte = rom[0];
|
||||
|
||||
switch (firstByte) {
|
||||
case 0x37: // v64
|
||||
for (size_t pos = 0; pos < (romSize / 2); pos++) {
|
||||
((uint16_t*)rom)[pos] = ToUInt16BE(rom, pos * 2);
|
||||
}
|
||||
break;
|
||||
case 0x40: // n64
|
||||
for (size_t pos = 0; pos < (romSize / 4); pos++) {
|
||||
((uint32_t*)rom)[pos] = ToUInt32BE(rom, pos * 4);
|
||||
}
|
||||
break;
|
||||
case 0x80: // z64
|
||||
break; // Already BE, no need to swap
|
||||
}
|
||||
}
|
||||
};
|
||||
60
ZAPDTR/ZAPD/Utils/Directory.h
Normal file
60
ZAPDTR/ZAPD/Utils/Directory.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "StringHelper.h"
|
||||
#include <iostream>
|
||||
|
||||
#if __has_include(<filesystem>)
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
#undef GetCurrentDirectory
|
||||
#undef CreateDirectory
|
||||
|
||||
class Directory
|
||||
{
|
||||
public:
|
||||
#ifndef PATH_HACK
|
||||
static std::string GetCurrentDirectory() { return fs::current_path().string(); }
|
||||
#endif
|
||||
|
||||
static bool Exists(const fs::path& path) { return fs::exists(path); }
|
||||
|
||||
// Stupid hack because of Windows.h
|
||||
static void MakeDirectory(const std::string& path)
|
||||
{
|
||||
CreateDirectory(path);
|
||||
}
|
||||
|
||||
static void CreateDirectory(const std::string& path)
|
||||
{
|
||||
try
|
||||
{
|
||||
fs::create_directories(path);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
static std::vector<std::string> ListFiles(const std::string& dir)
|
||||
{
|
||||
std::vector<std::string> lst;
|
||||
|
||||
if (Exists(dir))
|
||||
{
|
||||
for (auto& p : fs::recursive_directory_iterator(dir))
|
||||
{
|
||||
if (!p.is_directory())
|
||||
lst.push_back(p.path().generic_string());
|
||||
}
|
||||
}
|
||||
|
||||
return lst;
|
||||
}
|
||||
};
|
||||
91
ZAPDTR/ZAPD/Utils/DiskFile.h
Normal file
91
ZAPDTR/ZAPD/Utils/DiskFile.h
Normal file
@@ -0,0 +1,91 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdio>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Path.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "Utils/Directory.h"
|
||||
|
||||
|
||||
class DiskFile
|
||||
{
|
||||
public:
|
||||
static bool Exists(const fs::path& filePath)
|
||||
{
|
||||
std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
return file.good();
|
||||
}
|
||||
|
||||
static std::vector<uint8_t> ReadAllBytes(const fs::path& filePath)
|
||||
{
|
||||
std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
|
||||
if (!file)
|
||||
return std::vector<uint8_t>();
|
||||
|
||||
int32_t fileSize = (int32_t)file.tellg();
|
||||
file.seekg(0);
|
||||
char* data = new char[fileSize];
|
||||
file.read(data, fileSize);
|
||||
std::vector<uint8_t> result = std::vector<uint8_t>(data, data + fileSize);
|
||||
delete[] data;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
static std::string ReadAllText(const fs::path& filePath)
|
||||
{
|
||||
std::ifstream file(filePath, std::ios::in | std::ios::binary | std::ios::ate);
|
||||
int32_t fileSize = (int32_t)file.tellg();
|
||||
file.seekg(0);
|
||||
char* data = new char[fileSize + 1];
|
||||
memset(data, 0, fileSize + 1);
|
||||
file.read(data, fileSize);
|
||||
std::string str = std::string((const char*)data);
|
||||
delete[] data;
|
||||
|
||||
return str;
|
||||
};
|
||||
|
||||
static std::vector<std::string> ReadAllLines(const fs::path& filePath)
|
||||
{
|
||||
std::string text = ReadAllText(filePath);
|
||||
std::vector<std::string> lines = StringHelper::Split(text, "\n");
|
||||
|
||||
return lines;
|
||||
};
|
||||
|
||||
static void WriteAllBytes(const fs::path& filePath, const std::vector<uint8_t>& data)
|
||||
{
|
||||
std::ofstream file(filePath, std::ios::binary);
|
||||
file.write((char*)data.data(), data.size());
|
||||
};
|
||||
|
||||
static void WriteAllBytes(const std::string& filePath, const std::vector<char>& data)
|
||||
{
|
||||
if (!Directory::Exists(Path::GetDirectoryName(filePath))) {
|
||||
Directory::MakeDirectory(Path::GetDirectoryName(filePath).string());
|
||||
}
|
||||
|
||||
std::ofstream file(filePath, std::ios::binary);
|
||||
file.write((char*)data.data(), data.size());
|
||||
};
|
||||
|
||||
static void WriteAllBytes(const std::string& filePath, const char* data, int dataSize)
|
||||
{
|
||||
std::ofstream file(filePath, std::ios::binary);
|
||||
file.write((char*)data, dataSize);
|
||||
};
|
||||
|
||||
static void WriteAllText(const fs::path& filePath, const std::string& text)
|
||||
{
|
||||
if (!Directory::Exists(Path::GetDirectoryName(filePath))) {
|
||||
Directory::MakeDirectory(Path::GetDirectoryName(filePath).string());
|
||||
}
|
||||
std::ofstream file(filePath, std::ios::out);
|
||||
file.write(text.c_str(), text.size());
|
||||
}
|
||||
};
|
||||
97
ZAPDTR/ZAPD/Utils/MemoryStream.cpp
Normal file
97
ZAPDTR/ZAPD/Utils/MemoryStream.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "MemoryStream.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define memcpy_s(dest, destSize, source, sourceSize) memcpy(dest, source, destSize)
|
||||
#endif
|
||||
|
||||
MemoryStream::MemoryStream()
|
||||
{
|
||||
buffer = std::vector<char>();
|
||||
//buffer.reserve(1024 * 16);
|
||||
bufferSize = 0;
|
||||
baseAddress = 0;
|
||||
}
|
||||
|
||||
MemoryStream::MemoryStream(char* nBuffer, size_t nBufferSize) : MemoryStream()
|
||||
{
|
||||
buffer = std::vector<char>(nBuffer, nBuffer + nBufferSize);
|
||||
bufferSize = nBufferSize;
|
||||
baseAddress = 0;
|
||||
}
|
||||
|
||||
MemoryStream::~MemoryStream()
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t MemoryStream::GetLength()
|
||||
{
|
||||
return buffer.size();
|
||||
}
|
||||
|
||||
void MemoryStream::Seek(int32_t offset, SeekOffsetType seekType)
|
||||
{
|
||||
if (seekType == SeekOffsetType::Start)
|
||||
baseAddress = offset;
|
||||
else if (seekType == SeekOffsetType::Current)
|
||||
baseAddress += offset;
|
||||
else if (seekType == SeekOffsetType::End)
|
||||
baseAddress = bufferSize - 1 - offset;
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> MemoryStream::Read(size_t length)
|
||||
{
|
||||
std::unique_ptr<char[]> result = std::make_unique<char[]>(length);
|
||||
|
||||
memcpy_s(result.get(), length, &buffer[baseAddress], length);
|
||||
baseAddress += length;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void MemoryStream::Read(const char* dest, size_t length)
|
||||
{
|
||||
memcpy_s((void*)dest, length, &buffer[baseAddress], length);
|
||||
baseAddress += length;
|
||||
}
|
||||
|
||||
int8_t MemoryStream::ReadByte()
|
||||
{
|
||||
return buffer[baseAddress++];
|
||||
}
|
||||
|
||||
void MemoryStream::Write(char* srcBuffer, size_t length)
|
||||
{
|
||||
if (baseAddress + length >= buffer.size())
|
||||
{
|
||||
buffer.resize(baseAddress + length);
|
||||
bufferSize += length;
|
||||
}
|
||||
|
||||
memcpy_s(&buffer[baseAddress], length, srcBuffer, length);
|
||||
baseAddress += length;
|
||||
}
|
||||
|
||||
void MemoryStream::WriteByte(int8_t value)
|
||||
{
|
||||
if (baseAddress >= buffer.size())
|
||||
{
|
||||
buffer.resize(baseAddress + 1);
|
||||
bufferSize = baseAddress;
|
||||
}
|
||||
|
||||
buffer[baseAddress++] = value;
|
||||
}
|
||||
|
||||
std::vector<char> MemoryStream::ToVector()
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void MemoryStream::Flush()
|
||||
{
|
||||
}
|
||||
|
||||
void MemoryStream::Close()
|
||||
{
|
||||
}
|
||||
33
ZAPDTR/ZAPD/Utils/MemoryStream.h
Normal file
33
ZAPDTR/ZAPD/Utils/MemoryStream.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "Stream.h"
|
||||
|
||||
class MemoryStream : public Stream
|
||||
{
|
||||
public:
|
||||
MemoryStream();
|
||||
MemoryStream(char* nBuffer, size_t nBufferSize);
|
||||
~MemoryStream();
|
||||
|
||||
uint64_t GetLength() override;
|
||||
|
||||
void Seek(int32_t offset, SeekOffsetType seekType) override;
|
||||
|
||||
std::unique_ptr<char[]> Read(size_t length) override;
|
||||
void Read(const char* dest, size_t length) override;
|
||||
int8_t ReadByte() override;
|
||||
|
||||
void Write(char* srcBuffer, size_t length) override;
|
||||
void WriteByte(int8_t value) override;
|
||||
|
||||
std::vector<char> ToVector();
|
||||
|
||||
void Flush() override;
|
||||
void Close() override;
|
||||
|
||||
protected:
|
||||
std::vector<char> buffer;
|
||||
std::size_t bufferSize;
|
||||
};
|
||||
50
ZAPDTR/ZAPD/Utils/Path.h
Normal file
50
ZAPDTR/ZAPD/Utils/Path.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
#if __has_include(<filesystem>)
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
#else
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
|
||||
class Path
|
||||
{
|
||||
public:
|
||||
static std::string GetFileName(const fs::path& input)
|
||||
{
|
||||
// https://en.cppreference.com/w/cpp/filesystem/path/filename
|
||||
return input.filename().string();
|
||||
};
|
||||
|
||||
static std::string GetFileNameWithoutExtension(const fs::path& input)
|
||||
{
|
||||
// https://en.cppreference.com/w/cpp/filesystem/path/stem
|
||||
return input.stem().string();
|
||||
};
|
||||
|
||||
static std::string GetFileNameExtension(const std::string& input)
|
||||
{
|
||||
return input.substr(input.find_last_of("."), input.length());
|
||||
};
|
||||
|
||||
static fs::path GetPath(const std::string& input)
|
||||
{
|
||||
std::vector<std::string> split = StringHelper::Split(input, "/");
|
||||
fs::path output;
|
||||
|
||||
for (std::string str : split)
|
||||
{
|
||||
if (str.find_last_of(".") == std::string::npos)
|
||||
output /= str;
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
static fs::path GetDirectoryName(const fs::path& path) { return path.parent_path(); };
|
||||
};
|
||||
34
ZAPDTR/ZAPD/Utils/Stream.h
Normal file
34
ZAPDTR/ZAPD/Utils/Stream.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
enum class SeekOffsetType
|
||||
{
|
||||
Start,
|
||||
Current,
|
||||
End
|
||||
};
|
||||
|
||||
class Stream
|
||||
{
|
||||
public:
|
||||
virtual ~Stream() = default;
|
||||
virtual uint64_t GetLength() = 0;
|
||||
uint64_t GetBaseAddress() { return baseAddress; }
|
||||
|
||||
virtual void Seek(int32_t offset, SeekOffsetType seekType) = 0;
|
||||
|
||||
virtual std::unique_ptr<char[]> Read(size_t length) = 0;
|
||||
virtual void Read(const char* dest, size_t length) = 0;
|
||||
virtual int8_t ReadByte() = 0;
|
||||
|
||||
virtual void Write(char* destBuffer, size_t length) = 0;
|
||||
virtual void WriteByte(int8_t value) = 0;
|
||||
|
||||
virtual void Flush() = 0;
|
||||
virtual void Close() = 0;
|
||||
|
||||
protected:
|
||||
uint64_t baseAddress;
|
||||
};
|
||||
191
ZAPDTR/ZAPD/Utils/StringHelper.cpp
Normal file
191
ZAPDTR/ZAPD/Utils/StringHelper.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
#include "StringHelper.h"
|
||||
|
||||
#if (_MSC_VER)
|
||||
#pragma optimize("2", on)
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define vsprintf_s vsprintf
|
||||
#endif
|
||||
|
||||
std::vector<std::string> StringHelper::Split(std::string s, const std::string& delimiter)
|
||||
{
|
||||
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
|
||||
std::string token;
|
||||
std::vector<std::string> res;
|
||||
|
||||
while ((pos_end = s.find(delimiter, pos_start)) != std::string::npos) {
|
||||
token = s.substr(pos_start, pos_end - pos_start);
|
||||
pos_start = pos_end + delim_len;
|
||||
res.push_back(token);
|
||||
}
|
||||
|
||||
res.push_back(s.substr(pos_start));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::string_view> StringHelper::Split(std::string_view s, const std::string& delimiter)
|
||||
{
|
||||
size_t pos_start = 0, pos_end, delim_len = delimiter.length();
|
||||
std::string_view token;
|
||||
std::vector<std::string_view> res;
|
||||
|
||||
while ((pos_end = s.find(delimiter, pos_start)) != std::string_view::npos)
|
||||
{
|
||||
token = s.substr(pos_start, pos_end - pos_start);
|
||||
pos_start = pos_end + delim_len;
|
||||
res.push_back(token);
|
||||
}
|
||||
|
||||
res.push_back(s.substr(pos_start));
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string StringHelper::Strip(std::string s, const std::string& delimiter)
|
||||
{
|
||||
size_t pos = 0;
|
||||
std::string token;
|
||||
|
||||
while ((pos = s.find(delimiter)) != std::string::npos)
|
||||
{
|
||||
token = s.substr(0, pos);
|
||||
s.erase(pos, pos + delimiter.length());
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string StringHelper::Replace(std::string str, const std::string& from,
|
||||
const std::string& to)
|
||||
{
|
||||
size_t start_pos = str.find(from);
|
||||
|
||||
while (start_pos != std::string::npos)
|
||||
{
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos = str.find(from);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void StringHelper::ReplaceOriginal(std::string& str, const std::string& from, const std::string& to)
|
||||
{
|
||||
size_t start_pos = str.find(from);
|
||||
|
||||
while (start_pos != std::string::npos)
|
||||
{
|
||||
str.replace(start_pos, from.length(), to);
|
||||
start_pos = str.find(from);
|
||||
}
|
||||
}
|
||||
|
||||
bool StringHelper::StartsWith(const std::string& s, const std::string& input)
|
||||
{
|
||||
#if __cplusplus >= 202002L
|
||||
return s.starts_with(input.c_str());
|
||||
#else
|
||||
return s.rfind(input, 0) == 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool StringHelper::Contains(const std::string& s, const std::string& input)
|
||||
{
|
||||
return s.find(input) != std::string::npos;
|
||||
}
|
||||
|
||||
bool StringHelper::EndsWith(const std::string& s, const std::string& input)
|
||||
{
|
||||
size_t inputLen = strlen(input.c_str());
|
||||
return s.rfind(input) == (s.size() - inputLen);
|
||||
}
|
||||
|
||||
std::string StringHelper::Sprintf(const char* format, ...)
|
||||
{
|
||||
char buffer[32768];
|
||||
// char buffer[2048];
|
||||
std::string output;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
vsprintf_s(buffer, format, va);
|
||||
va_end(va);
|
||||
|
||||
output = buffer;
|
||||
return output;
|
||||
}
|
||||
|
||||
std::string StringHelper::Implode(std::vector<std::string>& elements,
|
||||
const char* const separator)
|
||||
{
|
||||
return "";
|
||||
|
||||
// return std::accumulate(std::begin(elements), std::end(elements), std::string(),
|
||||
//[separator](std::string& ss, std::string& s) {
|
||||
// return ss.empty() ? s : ss + separator + s;
|
||||
//});
|
||||
}
|
||||
|
||||
int64_t StringHelper::StrToL(const std::string& str, int32_t base)
|
||||
{
|
||||
return std::strtoull(str.c_str(), nullptr, base);
|
||||
}
|
||||
|
||||
std::string StringHelper::BoolStr(bool b)
|
||||
{
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
bool StringHelper::HasOnlyDigits(const std::string& str)
|
||||
{
|
||||
return std::all_of(str.begin(), str.end(), ::isdigit);
|
||||
}
|
||||
|
||||
// Validate a hex string based on the c89 standard
|
||||
// https://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Integer-Constants
|
||||
bool StringHelper::IsValidHex(std::string_view str)
|
||||
{
|
||||
if (str.length() < 3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
|
||||
{
|
||||
return std::all_of(str.begin() + 2, str.end(), ::isxdigit);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool StringHelper::IsValidHex(const std::string& str)
|
||||
{
|
||||
return IsValidHex(std::string_view(str.c_str()));
|
||||
}
|
||||
|
||||
bool StringHelper::IsValidOffset(std::string_view str)
|
||||
{
|
||||
if (str.length() == 1)
|
||||
{
|
||||
// 0 is a valid offset
|
||||
return isdigit(str[0]);
|
||||
}
|
||||
return IsValidHex(str);
|
||||
}
|
||||
|
||||
bool StringHelper::IsValidOffset(const std::string& str)
|
||||
{
|
||||
if (str.length() == 1)
|
||||
{
|
||||
// 0 is a valid offset
|
||||
return isdigit(str[0]);
|
||||
}
|
||||
return IsValidHex(str);
|
||||
}
|
||||
|
||||
|
||||
bool StringHelper::IEquals(const std::string& a, const std::string& b)
|
||||
{
|
||||
return std::equal(a.begin(), a.end(), b.begin(), b.end(),
|
||||
[](char a, char b) { return tolower(a) == tolower(b); });
|
||||
}
|
||||
33
ZAPDTR/ZAPD/Utils/StringHelper.h
Normal file
33
ZAPDTR/ZAPD/Utils/StringHelper.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
class StringHelper
|
||||
{
|
||||
public:
|
||||
static std::vector<std::string> Split(std::string s, const std::string& delimiter);
|
||||
static std::vector<std::string_view> Split(std::string_view s, const std::string& delimiter);
|
||||
static std::string Strip(std::string s, const std::string& delimiter);
|
||||
static std::string Replace(std::string str, const std::string& from, const std::string& to);
|
||||
static void ReplaceOriginal(std::string& str, const std::string& from, const std::string& to);
|
||||
static bool StartsWith(const std::string& s, const std::string& input);
|
||||
static bool Contains(const std::string& s, const std::string& input);
|
||||
static bool EndsWith(const std::string& s, const std::string& input);
|
||||
static std::string Sprintf(const char* format, ...);
|
||||
static std::string Implode(std::vector<std::string>& elements, const char* const separator);
|
||||
static int64_t StrToL(const std::string& str, int32_t base = 10);
|
||||
static std::string BoolStr(bool b);
|
||||
static bool HasOnlyDigits(const std::string& str);
|
||||
static bool IsValidHex(std::string_view str);
|
||||
static bool IsValidHex(const std::string& str);
|
||||
static bool IsValidOffset(std::string_view str);
|
||||
static bool IsValidOffset(const std::string& str);
|
||||
static bool IEquals(const std::string& a, const std::string& b);
|
||||
};
|
||||
45
ZAPDTR/ZAPD/Utils/vt.h
Normal file
45
ZAPDTR/ZAPD/Utils/vt.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef VT_H
|
||||
#define VT_H
|
||||
|
||||
// clang-format off
|
||||
#define VT_COLOR_BLACK 0
|
||||
#define VT_COLOR_RED 1
|
||||
#define VT_COLOR_GREEN 2
|
||||
#define VT_COLOR_YELLOW 3
|
||||
#define VT_COLOR_BLUE 4
|
||||
#define VT_COLOR_PURPLE 5
|
||||
#define VT_COLOR_CYAN 6
|
||||
#define VT_COLOR_WHITE 7
|
||||
#define VT_COLOR_LIGHTGRAY 8
|
||||
#define VT_COLOR_DARKGRAY 9
|
||||
|
||||
#define VT_COLOR_FOREGROUND 3
|
||||
#define VT_COLOR_BACKGROUND 4
|
||||
// clang-format on
|
||||
|
||||
#define VT_COLOR_EXPAND0(type, color) #type #color
|
||||
#define VT_COLOR_EXPAND1(type, color) VT_COLOR_EXPAND0(type, color)
|
||||
#define VT_COLOR(type, color) VT_COLOR_EXPAND1(VT_COLOR_##type, VT_COLOR_##color)
|
||||
|
||||
#define VT_ESC "\x1b"
|
||||
#define VT_CSI "["
|
||||
#define VT_CUP(x, y) VT_ESC VT_CSI y ";" x "H"
|
||||
#define VT_ED(n) VT_ESC VT_CSI #n "J"
|
||||
#define VT_SGR(n) VT_ESC VT_CSI n "m"
|
||||
|
||||
// Add more macros if necessary
|
||||
#define VT_COL(back, fore) VT_SGR(VT_COLOR(BACKGROUND, back) ";" VT_COLOR(FOREGROUND, fore))
|
||||
#define VT_FGCOL(color) VT_SGR(VT_COLOR(FOREGROUND, color))
|
||||
#define VT_BGCOL(color) VT_SGR(VT_COLOR(BACKGROUND, color))
|
||||
|
||||
// Bold
|
||||
#define VT_BOLD "1"
|
||||
|
||||
// Bold color support
|
||||
#define VT_BOLD_FGCOL(color) VT_SGR(VT_BOLD ";" VT_COLOR(FOREGROUND, color))
|
||||
#define VT_BOLD_BGCOL(color) VT_SGR(VT_BOLD ";" VT_COLOR(BACKGROUND, color))
|
||||
|
||||
#define VT_RST VT_SGR("")
|
||||
#define VT_CLS VT_ED(2)
|
||||
|
||||
#endif
|
||||
451
ZAPDTR/ZAPD/WarningHandler.cpp
Normal file
451
ZAPDTR/ZAPD/WarningHandler.cpp
Normal file
@@ -0,0 +1,451 @@
|
||||
/**
|
||||
* 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) {
|
||||
bool forcePrint = false;
|
||||
|
||||
#ifdef DEVELOPMENT
|
||||
forcePrint = true;
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
if (forcePrint || 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");
|
||||
}
|
||||
145
ZAPDTR/ZAPD/WarningHandler.h
Normal file
145
ZAPDTR/ZAPD/WarningHandler.h
Normal 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();
|
||||
};
|
||||
372
ZAPDTR/ZAPD/ZAPD.vcxproj
Normal file
372
ZAPDTR/ZAPD/ZAPD.vcxproj
Normal file
@@ -0,0 +1,372 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props" Condition="Exists('..\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)..\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(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>$(IncludePath)</IncludePath>
|
||||
</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>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<Profile>true</Profile>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd ..
|
||||
mkdir build\ZAPD
|
||||
python ZAPD/genbuildinfo.py</Command>
|
||||
</PreBuildEvent>
|
||||
</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>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<Profile>true</Profile>
|
||||
<AdditionalDependencies>ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||
<SubSystem>Console</SubSystem>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd ..
|
||||
mkdir build\ZAPD
|
||||
python ZAPD/genbuildinfo.py</Command>
|
||||
</PreBuildEvent>
|
||||
</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>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd ..
|
||||
mkdir build\ZAPD
|
||||
python ZAPD/genbuildinfo.py</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpplatest</LanguageStandard>
|
||||
<PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<PreBuildEvent>
|
||||
<Command>cd ..
|
||||
mkdir build\ZAPD
|
||||
python ZAPD/genbuildinfo.py</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\build\ZAPD\BuildInfo.cpp" />
|
||||
<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="CrashHandler.cpp" />
|
||||
<ClCompile Include="Declaration.cpp" />
|
||||
<ClCompile Include="GameConfig.cpp" />
|
||||
<ClCompile Include="Globals.cpp" />
|
||||
<ClCompile Include="ImageBackend.cpp" />
|
||||
<ClCompile Include="Main.cpp" />
|
||||
<ClCompile Include="OtherStructs\CutsceneMM_Commands.cpp" />
|
||||
<ClCompile Include="OtherStructs\Cutscene_Commands.cpp" />
|
||||
<ClCompile Include="OtherStructs\SkinLimbStructs.cpp" />
|
||||
<ClCompile Include="OutputFormatter.cpp" />
|
||||
<ClCompile Include="WarningHandler.cpp" />
|
||||
<ClCompile Include="ZActorList.cpp" />
|
||||
<ClCompile Include="ZArray.cpp" />
|
||||
<ClCompile Include="ZBackground.cpp" />
|
||||
<ClCompile Include="ZCollisionPoly.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="ZSurfaceType.cpp" />
|
||||
<ClCompile Include="ZSymbol.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="CrashHandler.h" />
|
||||
<ClInclude Include="CRC32.h" />
|
||||
<ClInclude Include="Declaration.h" />
|
||||
<ClInclude Include="GameConfig.h" />
|
||||
<ClInclude Include="Globals.h" />
|
||||
<ClInclude Include="ImageBackend.h" />
|
||||
<ClInclude Include="OtherStructs\CutsceneMM_Commands.h" />
|
||||
<ClInclude Include="OtherStructs\Cutscene_Commands.h" />
|
||||
<ClInclude Include="OtherStructs\SkinLimbStructs.h" />
|
||||
<ClInclude Include="OutputFormatter.h" />
|
||||
<ClInclude Include="WarningHandler.h" />
|
||||
<ClInclude Include="ZActorList.h" />
|
||||
<ClInclude Include="ZAnimation.h" />
|
||||
<ClInclude Include="ZArray.h" />
|
||||
<ClInclude Include="ZBackground.h" />
|
||||
<ClInclude Include="ZBlob.h" />
|
||||
<ClInclude Include="ZCollision.h" />
|
||||
<ClInclude Include="ZCollisionPoly.h" />
|
||||
<ClInclude Include="ZCutscene.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="ZSurfaceType.h" />
|
||||
<ClInclude Include="ZSymbol.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="..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v120.windesktop.msvcstl.dyn.rt-dyn.targets')" />
|
||||
<Import Project="..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets" Condition="Exists('..\packages\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.1.2.8.8\build\native\zlib.v140.windesktop.msvcstl.dyn.rt-dyn.targets')" />
|
||||
<Import Project="..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets" Condition="Exists('..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets')" />
|
||||
<Import Project="..\packages\zlib.static.1.2.5\build\native\zlib.static.targets" Condition="Exists('..\packages\zlib.static.1.2.5\build\native\zlib.static.targets')" />
|
||||
<Import Project="..\packages\libpng.static.1.6.37\build\native\libpng.static.targets" Condition="Exists('..\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('..\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)', '..\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('..\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)', '..\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('..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.props'))" />
|
||||
<Error Condition="!Exists('..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\YY.NuGet.Import.Helper.1.0.0.4\build\native\YY.NuGet.Import.Helper.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\zlib.static.1.2.5\build\native\zlib.static.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\zlib.static.1.2.5\build\native\zlib.static.targets'))" />
|
||||
<Error Condition="!Exists('..\packages\libpng.static.1.6.37\build\native\libpng.static.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\libpng.static.1.6.37\build\native\libpng.static.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
572
ZAPDTR/ZAPD/ZAPD.vcxproj.filters
Normal file
572
ZAPDTR/ZAPD/ZAPD.vcxproj.filters
Normal file
@@ -0,0 +1,572 @@
|
||||
<?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="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="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="..\build\ZAPD\BuildInfo.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ZPlayerAnimationData.cpp">
|
||||
<Filter>Source Files\Z64</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="WarningHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ZCollisionPoly.cpp">
|
||||
<Filter>Source Files\Z64</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OtherStructs\Cutscene_Commands.cpp">
|
||||
<Filter>Source Files\Z64</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="OtherStructs\CutsceneMM_Commands.cpp">
|
||||
<Filter>Source Files\Z64</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CrashHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ZSurfaceType.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="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="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="ZCollisionPoly.h">
|
||||
<Filter>Header Files\Z64</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="OtherStructs\Cutscene_Commands.h">
|
||||
<Filter>Header Files\Z64</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="OtherStructs\CutsceneMM_Commands.h">
|
||||
<Filter>Header Files\Z64</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CrashHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ZSurfaceType.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>
|
||||
194
ZAPDTR/ZAPD/ZActorList.cpp
Normal file
194
ZAPDTR/ZAPD/ZActorList.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
#include "ZActorList.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "WarningHandler.h"
|
||||
#include "ZFile.h"
|
||||
#include "ZRoom/ZNames.h"
|
||||
|
||||
REGISTER_ZFILENODE(ActorList, ZActorList);
|
||||
|
||||
ZActorList::ZActorList(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
RegisterRequiredAttribute("Count");
|
||||
}
|
||||
|
||||
void ZActorList::ExtractFromBinary(uint32_t nRawDataIndex, uint8_t nNumActors)
|
||||
{
|
||||
rawDataIndex = nRawDataIndex;
|
||||
numActors = nNumActors;
|
||||
|
||||
// Don't parse raw data of external files
|
||||
if (parent->GetMode() == ZFileMode::ExternalFile)
|
||||
return;
|
||||
|
||||
ParseRawData();
|
||||
}
|
||||
|
||||
void ZActorList::ParseXML(tinyxml2::XMLElement* reader)
|
||||
{
|
||||
ZResource::ParseXML(reader);
|
||||
|
||||
numActors = StringHelper::StrToL(registeredAttributes.at("Count").value);
|
||||
|
||||
if (numActors < 1)
|
||||
{
|
||||
HANDLE_ERROR_RESOURCE(
|
||||
WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
|
||||
StringHelper::Sprintf("invalid value '%d' found for 'NumPaths' attribute", numActors),
|
||||
"Should be at least '1'");
|
||||
}
|
||||
}
|
||||
|
||||
void ZActorList::ParseRawData()
|
||||
{
|
||||
ZResource::ParseRawData();
|
||||
|
||||
offset_t currentPtr = rawDataIndex;
|
||||
size_t largestlength = 0;
|
||||
|
||||
for (size_t i = 0; i < numActors; i++)
|
||||
{
|
||||
ActorSpawnEntry entry(parent->GetRawData(), currentPtr);
|
||||
|
||||
currentPtr += entry.GetRawDataSize();
|
||||
actors.push_back(entry);
|
||||
|
||||
size_t actorNameLength = ZNames::GetActorName(entry.GetActorId()).size();
|
||||
if (actorNameLength > largestlength)
|
||||
largestlength = actorNameLength;
|
||||
}
|
||||
|
||||
for (auto& entry : actors)
|
||||
{
|
||||
entry.SetLargestActorName(largestlength);
|
||||
}
|
||||
}
|
||||
|
||||
Declaration* ZActorList::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, GetActorListArraySize(), bodyStr);
|
||||
decl->staticConf = staticConf;
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
std::string ZActorList::GetBodySourceCode() const
|
||||
{
|
||||
std::string declaration;
|
||||
|
||||
size_t index = 0;
|
||||
for (auto& entry : actors)
|
||||
{
|
||||
declaration += StringHelper::Sprintf("\t{ %s },", entry.GetBodySourceCode().c_str());
|
||||
|
||||
if (index < actors.size() - 1)
|
||||
declaration += "\n";
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
return declaration;
|
||||
}
|
||||
|
||||
std::string ZActorList::GetSourceTypeName() const
|
||||
{
|
||||
return actors.front().GetSourceTypeName();
|
||||
}
|
||||
|
||||
ZResourceType ZActorList::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::ActorList;
|
||||
}
|
||||
|
||||
size_t ZActorList::GetRawDataSize() const
|
||||
{
|
||||
return actors.size() * actors.front().GetRawDataSize();
|
||||
}
|
||||
|
||||
size_t ZActorList::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;
|
||||
}
|
||||
|
||||
/* ActorSpawnEntry */
|
||||
|
||||
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);
|
||||
params = 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", params);
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
std::string ActorSpawnEntry::GetSourceTypeName() const
|
||||
{
|
||||
return "ActorEntry";
|
||||
}
|
||||
|
||||
size_t ActorSpawnEntry::GetRawDataSize() const
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
uint16_t ActorSpawnEntry::GetActorId() const
|
||||
{
|
||||
return actorNum;
|
||||
}
|
||||
|
||||
void ActorSpawnEntry::SetLargestActorName(size_t nameSize)
|
||||
{
|
||||
largestActorName = nameSize;
|
||||
}
|
||||
52
ZAPDTR/ZAPD/ZActorList.h
Normal file
52
ZAPDTR/ZAPD/ZActorList.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZResource.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 params;
|
||||
size_t largestActorName = 16;
|
||||
|
||||
ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
|
||||
|
||||
std::string GetBodySourceCode() const;
|
||||
|
||||
std::string GetSourceTypeName() const;
|
||||
size_t GetRawDataSize() const;
|
||||
|
||||
uint16_t GetActorId() const;
|
||||
void SetLargestActorName(size_t nameSize);
|
||||
};
|
||||
|
||||
class ZActorList : public ZResource
|
||||
{
|
||||
public:
|
||||
std::vector<ActorSpawnEntry> actors;
|
||||
uint32_t numActors = 0;
|
||||
|
||||
ZActorList(ZFile* nParent);
|
||||
|
||||
void ExtractFromBinary(offset_t nRawDataIndex, uint8_t nNumActors);
|
||||
|
||||
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 GetSourceTypeName() const override;
|
||||
ZResourceType GetResourceType() const override;
|
||||
|
||||
size_t GetRawDataSize() const override;
|
||||
|
||||
protected:
|
||||
size_t GetActorListArraySize() const;
|
||||
};
|
||||
580
ZAPDTR/ZAPD/ZAnimation.cpp
Normal file
580
ZAPDTR/ZAPD/ZAnimation.cpp
Normal file
@@ -0,0 +1,580 @@
|
||||
#include "ZAnimation.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include <Utils/DiskFile.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();
|
||||
|
||||
auto& data = parent->GetRawData();
|
||||
|
||||
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;
|
||||
|
||||
if (!Globals::Instance->otrMode)
|
||||
{
|
||||
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);
|
||||
|
||||
if (!Globals::Instance->otrMode)
|
||||
{
|
||||
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,
|
||||
parent->workerID);
|
||||
std::string jointIndicesName;
|
||||
Globals::Instance->GetSegmentedPtrName(rotationIndicesSeg, parent, "JointIndex",
|
||||
jointIndicesName, parent->workerID);
|
||||
|
||||
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, parent->workerID);
|
||||
|
||||
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, parent->workerID);
|
||||
std::string transformDataStr;
|
||||
Globals::Instance->GetSegmentedPtrName(transformData, parent, "TransformData",
|
||||
transformDataStr, parent->workerID);
|
||||
std::string copyValuesStr;
|
||||
Globals::Instance->GetSegmentedPtrName(copyValues, parent, "s16", copyValuesStr,
|
||||
parent->workerID);
|
||||
|
||||
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,
|
||||
parent->workerID);
|
||||
Globals::Instance->GetSegmentedPtrName(jointKey, parent, "JointKey", jointKeyName,
|
||||
parent->workerID);
|
||||
|
||||
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;
|
||||
}
|
||||
179
ZAPDTR/ZAPD/ZAnimation.h
Normal file
179
ZAPDTR/ZAPD/ZAnimation.h
Normal file
@@ -0,0 +1,179 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#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;
|
||||
};
|
||||
153
ZAPDTR/ZAPD/ZArray.cpp
Normal file
153
ZAPDTR/ZAPD/ZArray.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#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;
|
||||
resList.reserve(arrayCnt);
|
||||
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";
|
||||
|
||||
switch (res->GetResourceType())
|
||||
{
|
||||
case ZResourceType::Pointer:
|
||||
case ZResourceType::Scalar:
|
||||
case ZResourceType::Vertex:
|
||||
case ZResourceType::CollisionPoly:
|
||||
case ZResourceType::SurfaceType:
|
||||
output += resList.at(i)->GetBodySourceCode();
|
||||
break;
|
||||
|
||||
default:
|
||||
output += StringHelper::Sprintf("{ %s }", resList.at(i)->GetBodySourceCode().c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < arrayCnt - 1 || res->IsExternalResource())
|
||||
output += ",\n";
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
size_t ZArray::GetRawDataSize() const
|
||||
{
|
||||
size_t size = 0;
|
||||
for (const 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
31
ZAPDTR/ZAPD/ZArray.h
Normal 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;
|
||||
};
|
||||
415
ZAPDTR/ZAPD/ZAudio.cpp
Normal file
415
ZAPDTR/ZAPD/ZAudio.cpp
Normal file
@@ -0,0 +1,415 @@
|
||||
#include "ZAudio.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include <Utils/DiskFile.h>
|
||||
#include "Utils/Path.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "ZFile.h"
|
||||
|
||||
REGISTER_ZFILENODE(Audio, ZAudio);
|
||||
|
||||
ZAudio::ZAudio(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
RegisterRequiredAttribute("SoundFontTableOffset");
|
||||
RegisterRequiredAttribute("SequenceTableOffset");
|
||||
RegisterRequiredAttribute("SampleBankTableOffset");
|
||||
RegisterRequiredAttribute("SequenceFontTableOffset");
|
||||
}
|
||||
|
||||
void ZAudio::ParseXML(tinyxml2::XMLElement* reader)
|
||||
{
|
||||
ZResource::ParseXML(reader);
|
||||
|
||||
auto t = reader->Name();
|
||||
|
||||
auto child = reader->FirstChildElement();
|
||||
|
||||
while (child != nullptr)
|
||||
{
|
||||
if (std::string(child->Value()) == "Sequences")
|
||||
{
|
||||
auto seqChild = child->FirstChildElement();
|
||||
|
||||
while (seqChild != nullptr)
|
||||
{
|
||||
if (std::string(seqChild->Value()) == "Sequence")
|
||||
{
|
||||
seqNames.push_back(seqChild->Attribute("Name"));
|
||||
}
|
||||
|
||||
seqChild = seqChild->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (std::string(child->Value()) == "Samples")
|
||||
{
|
||||
int bankId = child->IntAttribute("Bank", 0);
|
||||
auto sampChild = child->FirstChildElement();
|
||||
|
||||
while (sampChild != nullptr)
|
||||
{
|
||||
if (std::string(sampChild->Value()) == "Sample")
|
||||
{
|
||||
auto atStr = sampChild->FirstChildElement()->Attribute("At");
|
||||
auto loopStr = sampChild->FirstChildElement()->Attribute("LoopOffset");
|
||||
uint32_t loopOffset = 0xFFFFFFFF;
|
||||
uint32_t atOffset = StringHelper::StrToL(atStr, 16);
|
||||
|
||||
if (loopStr != NULL)
|
||||
{
|
||||
loopOffset = StringHelper::StrToL(loopStr, 16);
|
||||
specialLoopSamples[loopOffset] = atOffset;
|
||||
}
|
||||
|
||||
sampleOffsets[bankId][loopOffset][atOffset] = sampChild->Attribute("Name");
|
||||
}
|
||||
|
||||
sampChild = sampChild->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (std::string(child->Value()) == "Soundfont")
|
||||
{
|
||||
auto name = child->Attribute("Name");
|
||||
auto index = child->IntAttribute("Index", 0);
|
||||
soundFontNames[index] = name;
|
||||
}
|
||||
|
||||
child = child->NextSiblingElement();
|
||||
}
|
||||
}
|
||||
|
||||
void ZAudio::DecodeADPCMSample(SampleEntry* sample)
|
||||
{
|
||||
int16_t buffer[1024 * 128];
|
||||
|
||||
int16_t* out = &buffer[0];
|
||||
}
|
||||
|
||||
std::vector<AdsrEnvelope*> ZAudio::ParseEnvelopeData(std::vector<uint8_t> audioBank, std::vector<uint8_t> audioTable, int envelopeOffset, int baseOffset)
|
||||
{
|
||||
std::vector<AdsrEnvelope*> result;
|
||||
|
||||
while (true)
|
||||
{
|
||||
AdsrEnvelope* env = new AdsrEnvelope();
|
||||
|
||||
env->delay = BitConverter::ToInt16BE(audioBank, envelopeOffset + 0);
|
||||
env->arg = BitConverter::ToInt16BE(audioBank, envelopeOffset + 2);
|
||||
|
||||
envelopeOffset += 4;
|
||||
|
||||
result.push_back(env);
|
||||
|
||||
if (env->delay < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SoundFontEntry* ZAudio::ParseSoundFontEntry(std::vector<uint8_t> audioBank,
|
||||
std::vector<uint8_t> audioTable,
|
||||
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||
int soundFontOffset,
|
||||
int baseOffset)
|
||||
{
|
||||
SoundFontEntry* soundFont = new SoundFontEntry();
|
||||
soundFont->sampleEntry = ParseSampleEntry(
|
||||
audioBank, audioTable, audioSampleBankEntry, bankIndex,
|
||||
BitConverter::ToInt32BE(audioBank, soundFontOffset + 0) + baseOffset, baseOffset);
|
||||
soundFont->tuning = BitConverter::ToFloatBE(audioBank, soundFontOffset + 4);
|
||||
|
||||
return soundFont;
|
||||
}
|
||||
|
||||
SampleEntry* ZAudio::ParseSampleEntry(std::vector<uint8_t> audioBank,
|
||||
std::vector<uint8_t> audioTable,
|
||||
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||
int sampleOffset,
|
||||
int baseOffset)
|
||||
{
|
||||
int sampleDataOffset = BitConverter::ToInt32BE(audioBank, sampleOffset + 4) + audioSampleBankEntry.ptr;
|
||||
|
||||
if (samples.find(sampleOffset) == samples.end())
|
||||
{
|
||||
SampleEntry* sample = new SampleEntry();
|
||||
|
||||
sample->bankId = bankIndex;
|
||||
|
||||
int sampleSize = BitConverter::ToInt32BE(audioBank, sampleOffset + 0) & 0x00FFFFFF;
|
||||
int loopOffset = BitConverter::ToInt32BE(audioBank, sampleOffset + 8) + baseOffset;
|
||||
int bookOffset = BitConverter::ToInt32BE(audioBank, sampleOffset + 12) + baseOffset;
|
||||
|
||||
char* sampleData = (char*)malloc(sampleSize);
|
||||
memcpy(sampleData, audioTable.data() + sampleDataOffset, sampleSize);
|
||||
sample->data = std::vector<uint8_t>(sampleSize);
|
||||
memcpy(sample->data.data(), sampleData, sampleSize);
|
||||
|
||||
uint32_t origField = (BitConverter::ToUInt32BE(audioBank, sampleOffset + 0));
|
||||
sample->codec = (origField >> 28) & 0x0F;
|
||||
sample->medium = (origField >> 24) & 0x03;
|
||||
sample->unk_bit26 = (origField >> 22) & 0x01;
|
||||
sample->unk_bit25 = (origField >> 21) & 0x01;
|
||||
|
||||
sample->loop.start = BitConverter::ToInt32BE(audioBank, loopOffset + 0);
|
||||
sample->loop.end = BitConverter::ToInt32BE(audioBank, loopOffset + 4);
|
||||
sample->loop.count = BitConverter::ToInt32BE(audioBank, loopOffset + 8);
|
||||
|
||||
if (sample->loop.count != 0)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
int16_t state = BitConverter::ToInt16BE(audioBank, loopOffset + 16 + (i * 2));
|
||||
sample->loop.states.push_back(state);
|
||||
}
|
||||
}
|
||||
|
||||
sample->book.order = BitConverter::ToInt32BE(audioBank, bookOffset + 0);
|
||||
sample->book.npredictors = BitConverter::ToInt32BE(audioBank, bookOffset + 4);
|
||||
|
||||
for (int i = 0; i < sample->book.npredictors * sample->book.order * 8; i++)
|
||||
{
|
||||
sample->book.books.push_back(
|
||||
BitConverter::ToInt16BE(audioBank, bookOffset + 8 + (i * 2)));
|
||||
}
|
||||
|
||||
sample->sampleDataOffset = sampleDataOffset;
|
||||
|
||||
if (specialLoopSamples.find(loopOffset) != specialLoopSamples.end())
|
||||
sample->sampleLoopOffset = loopOffset;
|
||||
|
||||
sample->fileName = StringHelper::Sprintf("audio/samples/sample_%08X", sampleOffset);
|
||||
|
||||
samples[sampleOffset] = sample;
|
||||
|
||||
return sample;
|
||||
}
|
||||
else
|
||||
{
|
||||
return samples[sampleOffset];
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<AudioTableEntry> ZAudio::ParseAudioTable(std::vector<uint8_t> codeData, int baseOffset)
|
||||
{
|
||||
std::vector<AudioTableEntry> entries;
|
||||
|
||||
int numEntries = BitConverter::ToInt16BE(codeData, baseOffset + 0);
|
||||
int romAddr = BitConverter::ToInt16BE(codeData, baseOffset + 4);
|
||||
|
||||
int currentOffset = baseOffset + 16;
|
||||
|
||||
for (int i = 0; i < numEntries; i++)
|
||||
{
|
||||
AudioTableEntry entry;
|
||||
|
||||
entry.ptr = BitConverter::ToInt32BE(codeData, currentOffset + 0);
|
||||
entry.size = BitConverter::ToInt32BE(codeData, currentOffset + 4);
|
||||
entry.medium = codeData[currentOffset + 8];
|
||||
entry.cachePolicy = codeData[currentOffset + 9];
|
||||
entry.data1 = BitConverter::ToInt16BE(codeData, currentOffset + 10);
|
||||
entry.data2 = BitConverter::ToInt16BE(codeData, currentOffset + 12);
|
||||
entry.data3 = BitConverter::ToInt16BE(codeData, currentOffset + 14);
|
||||
|
||||
entries.push_back(entry);
|
||||
|
||||
currentOffset += 16;
|
||||
}
|
||||
|
||||
return entries;
|
||||
}
|
||||
|
||||
void ZAudio::ParseSoundFont(std::vector<uint8_t> codeData, std::vector<uint8_t> audioTable,
|
||||
std::vector<AudioTableEntry> audioSampleBank,
|
||||
AudioTableEntry& entry)
|
||||
{
|
||||
int ptr = entry.ptr;
|
||||
int size = entry.size;
|
||||
int sampleBankId1 = (entry.data1 >> 8) & 0xFF;
|
||||
int sampleBankId2 = (entry.data1) & 0xFF;
|
||||
int numInstruments = (entry.data2 >> 8) & 0xFF;
|
||||
int numDrums = entry.data2 & 0xFF;
|
||||
int numSfx = entry.data3;
|
||||
|
||||
int currentOffset = BitConverter::ToInt32BE(codeData, ptr) + ptr;
|
||||
for (int i = 0; i < numDrums; i++)
|
||||
{
|
||||
DrumEntry drum;
|
||||
|
||||
int samplePtr = BitConverter::ToInt32BE(codeData, currentOffset);
|
||||
|
||||
if (samplePtr != 0)
|
||||
{
|
||||
samplePtr += ptr;
|
||||
|
||||
drum.sample = ParseSampleEntry(codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1,
|
||||
BitConverter::ToInt32BE(codeData, samplePtr + 4) + ptr, ptr);
|
||||
|
||||
drum.releaseRate = codeData[samplePtr + 0];
|
||||
drum.pan = codeData[samplePtr + 1];
|
||||
drum.loaded = codeData[samplePtr + 2];
|
||||
drum.tuning = BitConverter::ToFloatBE(codeData, samplePtr + 8);
|
||||
drum.env = ParseEnvelopeData(codeData, audioTable, BitConverter::ToInt32BE(codeData, samplePtr + 12) + ptr, ptr);
|
||||
}
|
||||
|
||||
entry.drums.push_back(drum);
|
||||
|
||||
currentOffset += 4;
|
||||
}
|
||||
|
||||
currentOffset = BitConverter::ToInt32BE(codeData, ptr + 4) + ptr;
|
||||
for (int i = 0; i < numSfx; i++)
|
||||
{
|
||||
SoundFontEntry* sfx;
|
||||
sfx = ParseSoundFontEntry(codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1,
|
||||
currentOffset, ptr);
|
||||
entry.soundEffects.push_back(sfx);
|
||||
|
||||
currentOffset += 8;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numInstruments; i++)
|
||||
{
|
||||
InstrumentEntry instrument;
|
||||
|
||||
currentOffset = BitConverter::ToInt32BE(codeData, ptr + 8 + (i * 4));
|
||||
|
||||
instrument.isValidInstrument = currentOffset != 0;
|
||||
|
||||
if (currentOffset != 0)
|
||||
{
|
||||
currentOffset += ptr;
|
||||
|
||||
instrument.loaded = codeData[currentOffset + 0];
|
||||
instrument.normalRangeLo = codeData[currentOffset + 1];
|
||||
instrument.normalRangeHi = codeData[currentOffset + 2];
|
||||
instrument.releaseRate = codeData[currentOffset + 3];
|
||||
instrument.env = ParseEnvelopeData(codeData, audioTable, BitConverter::ToInt32BE(codeData, currentOffset + 4) + ptr, ptr);
|
||||
|
||||
if (BitConverter::ToInt32BE(codeData, currentOffset + 8) != 0)
|
||||
instrument.lowNotesSound = ParseSoundFontEntry(
|
||||
codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1, currentOffset + 8, ptr);
|
||||
|
||||
if (BitConverter::ToInt32BE(codeData, currentOffset + 16) != 0)
|
||||
instrument.normalNotesSound = ParseSoundFontEntry(
|
||||
codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1, currentOffset + 16, ptr);
|
||||
|
||||
if (BitConverter::ToInt32BE(codeData, currentOffset + 24) != 0 &&
|
||||
instrument.normalRangeHi != 0x7F)
|
||||
instrument.highNotesSound = ParseSoundFontEntry(
|
||||
codeData, audioTable, audioSampleBank[sampleBankId1], sampleBankId1, currentOffset + 24, ptr);
|
||||
}
|
||||
|
||||
entry.instruments.push_back(instrument);
|
||||
}
|
||||
}
|
||||
|
||||
void ZAudio::ParseRawData()
|
||||
{
|
||||
ZResource::ParseRawData();
|
||||
|
||||
std::vector<uint8_t> codeData;
|
||||
std::vector<uint8_t> audioTableData;
|
||||
std::vector<uint8_t> audioBankData;
|
||||
std::vector<uint8_t> audioSeqData;
|
||||
|
||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||
codeData = Globals::Instance->GetBaseromFile("code");
|
||||
else
|
||||
codeData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "code");
|
||||
|
||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||
audioTableData = Globals::Instance->GetBaseromFile("Audiotable");
|
||||
else
|
||||
audioTableData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "Audiotable");
|
||||
|
||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||
audioBankData = Globals::Instance->GetBaseromFile("Audiobank");
|
||||
else
|
||||
audioBankData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() + "Audiobank");
|
||||
|
||||
|
||||
if (Globals::Instance->fileMode == ZFileMode::ExtractDirectory)
|
||||
audioSeqData = Globals::Instance->GetBaseromFile("Audioseq");
|
||||
else
|
||||
audioSeqData = Globals::Instance->GetBaseromFile(Globals::Instance->baseRomPath.string() +
|
||||
"Audioseq");
|
||||
|
||||
// TABLE PARSING
|
||||
|
||||
// MQ DBG ROM
|
||||
//int gSoundFontTableOffset = 0x138270;
|
||||
//int gSequenceTableOffset = 0x1386A0;
|
||||
//int gSampleBankTableOffset = 0x138D90;
|
||||
//int gSequenceFontTableOffset = 0x1384E0;
|
||||
|
||||
// NTSC 1.0
|
||||
//int gSoundFontTableOffset = 0x1026A0;
|
||||
//int gSequenceTableOffset = 0x102AD0;
|
||||
//int gSampleBankTableOffset = 0x1031C0;
|
||||
//int gSequenceFontTableOffset = 0x102910;
|
||||
|
||||
int gSoundFontTableOffset = StringHelper::StrToL(registeredAttributes.at("SoundFontTableOffset").value, 16);
|
||||
int gSequenceTableOffset = StringHelper::StrToL(registeredAttributes.at("SequenceTableOffset").value, 16);
|
||||
int gSampleBankTableOffset = StringHelper::StrToL(registeredAttributes.at("SampleBankTableOffset").value, 16);
|
||||
int gSequenceFontTableOffset = StringHelper::StrToL(registeredAttributes.at("SequenceFontTableOffset").value, 16);
|
||||
|
||||
soundFontTable = ParseAudioTable(codeData, gSoundFontTableOffset);
|
||||
sequenceTable = ParseAudioTable(codeData, gSequenceTableOffset);
|
||||
sampleBankTable = ParseAudioTable(codeData, gSampleBankTableOffset);
|
||||
|
||||
// SEQEUNCE FONT TABLE PARSING
|
||||
for (int i = 0; i < sequenceTable.size(); i++)
|
||||
{
|
||||
uint16_t idx = BitConverter::ToUInt16BE(codeData, gSequenceFontTableOffset + (i * 2));
|
||||
uint8_t numFonts = codeData[gSequenceFontTableOffset + (idx++)];
|
||||
std::vector<uint32_t> fontIds;
|
||||
|
||||
for (int j = 0; j < numFonts; j++)
|
||||
{
|
||||
uint8_t fontId = codeData[gSequenceFontTableOffset + (idx++)];
|
||||
fontIds.push_back(fontId);
|
||||
}
|
||||
|
||||
fontIndices.push_back(fontIds);
|
||||
}
|
||||
|
||||
|
||||
// SAMPLE/FONT PARSING
|
||||
for (int i = 0; i < soundFontTable.size(); i++)
|
||||
{
|
||||
ParseSoundFont(audioBankData, audioTableData, sampleBankTable, soundFontTable[i]);
|
||||
}
|
||||
|
||||
// SEQUENCE PARSING
|
||||
for (int i = 0; i < sequenceTable.size(); i++)
|
||||
{
|
||||
int seqDestIdx = i;
|
||||
|
||||
if (sequenceTable[i].size == 0)
|
||||
seqDestIdx = sequenceTable[i].ptr;
|
||||
|
||||
std::vector<char> seqVec = std::vector<char>(sequenceTable[seqDestIdx].size);
|
||||
memcpy(seqVec.data(), audioSeqData.data() + sequenceTable[seqDestIdx].ptr,
|
||||
sequenceTable[seqDestIdx].size);
|
||||
|
||||
sequences.push_back(seqVec);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ZAudio::GetSourceTypeName() const
|
||||
{
|
||||
return "u8";
|
||||
}
|
||||
|
||||
size_t ZAudio::GetRawDataSize() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
ZResourceType ZAudio::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::Audio;
|
||||
}
|
||||
134
ZAPDTR/ZAPD/ZAudio.h
Normal file
134
ZAPDTR/ZAPD/ZAudio.h
Normal file
@@ -0,0 +1,134 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZResource.h"
|
||||
#include "tinyxml2.h"
|
||||
|
||||
struct AdsrEnvelope
|
||||
{
|
||||
int16_t delay;
|
||||
int16_t arg;
|
||||
};
|
||||
|
||||
struct AdpcmBook
|
||||
{
|
||||
/* 0x00 */ int32_t order;
|
||||
/* 0x04 */ int32_t npredictors;
|
||||
/* 0x08 */ std::vector<int16_t> books; // size 8 * order * npredictors. 8-byte aligned
|
||||
};
|
||||
|
||||
struct AdpcmLoop
|
||||
{
|
||||
/* 0x00 */ uint32_t start;
|
||||
/* 0x04 */ uint32_t end;
|
||||
/* 0x08 */ uint32_t count;
|
||||
/* 0x10 */ std::vector<int16_t> states;
|
||||
};
|
||||
|
||||
struct SampleEntry
|
||||
{
|
||||
std::string fileName;
|
||||
uint8_t bankId;
|
||||
uint32_t sampleDataOffset;
|
||||
uint32_t sampleLoopOffset = 0xFFFFFFFF;
|
||||
uint8_t codec;
|
||||
uint8_t medium;
|
||||
uint8_t unk_bit26;
|
||||
uint8_t unk_bit25;
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
AdpcmLoop loop;
|
||||
AdpcmBook book;
|
||||
};
|
||||
|
||||
struct SoundFontEntry
|
||||
{
|
||||
SampleEntry* sampleEntry = nullptr;
|
||||
float tuning;
|
||||
};
|
||||
|
||||
struct DrumEntry
|
||||
{
|
||||
uint8_t releaseRate;
|
||||
uint8_t pan;
|
||||
uint8_t loaded;
|
||||
uint32_t offset;
|
||||
float tuning;
|
||||
std::vector<AdsrEnvelope*> env;
|
||||
SampleEntry* sample = nullptr;
|
||||
};
|
||||
|
||||
struct InstrumentEntry
|
||||
{
|
||||
bool isValidInstrument;
|
||||
uint8_t loaded;
|
||||
uint8_t normalRangeLo;
|
||||
uint8_t normalRangeHi;
|
||||
uint8_t releaseRate;
|
||||
std::vector<AdsrEnvelope*> env;
|
||||
SoundFontEntry* lowNotesSound = nullptr;
|
||||
SoundFontEntry* normalNotesSound = nullptr;
|
||||
SoundFontEntry* highNotesSound = nullptr;
|
||||
};
|
||||
|
||||
struct AudioTableEntry
|
||||
{
|
||||
uint32_t ptr;
|
||||
uint32_t size;
|
||||
uint8_t medium;
|
||||
uint8_t cachePolicy;
|
||||
uint16_t data1;
|
||||
uint16_t data2;
|
||||
uint16_t data3;
|
||||
|
||||
std::vector<DrumEntry> drums;
|
||||
std::vector<SoundFontEntry*> soundEffects;
|
||||
std::vector<InstrumentEntry> instruments;
|
||||
};
|
||||
|
||||
class ZAudio : public ZResource
|
||||
{
|
||||
public:
|
||||
std::vector<AudioTableEntry> soundFontTable;
|
||||
std::vector<AudioTableEntry> sequenceTable;
|
||||
std::vector<AudioTableEntry> sampleBankTable;
|
||||
std::vector<std::vector<char>> sequences;
|
||||
std::map<uint32_t, SampleEntry*> samples;
|
||||
std::vector<std::vector<uint32_t>> fontIndices;
|
||||
std::vector<std::string> seqNames;
|
||||
std::map<uint32_t, std::string> soundFontNames;
|
||||
|
||||
// First Key = Bank ID, Sec Key = LoopDataOffset, Third Key = Sample Data Offset
|
||||
std::map<uint32_t, std::map<uint32_t, std::map<uint32_t, std::string>>> sampleOffsets;
|
||||
|
||||
// Key = Loop Offset, Value = Sample Offset
|
||||
std::map<uint32_t, uint32_t> specialLoopSamples;
|
||||
|
||||
ZAudio(ZFile* nParent);
|
||||
|
||||
void ParseXML(tinyxml2::XMLElement* reader) override;
|
||||
|
||||
void DecodeADPCMSample(SampleEntry* sample);
|
||||
std::vector<AdsrEnvelope*> ParseEnvelopeData(std::vector<uint8_t> audioBank, std::vector<uint8_t> audioTable,
|
||||
int envelopeOffset, int baseOffset);
|
||||
|
||||
SoundFontEntry* ParseSoundFontEntry(std::vector<uint8_t> audioBank,
|
||||
std::vector<uint8_t> audioTable,
|
||||
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||
int soundFontOffset,
|
||||
int baseOffset);
|
||||
|
||||
SampleEntry* ParseSampleEntry(std::vector<uint8_t> audioBank, std::vector<uint8_t> audioTable,
|
||||
AudioTableEntry audioSampleBankEntry, int bankIndex,
|
||||
int sampleOffset, int baseOffset);
|
||||
|
||||
std::vector<AudioTableEntry> ParseAudioTable(std::vector<uint8_t> codeData, int baseOffset);
|
||||
void ParseSoundFont(std::vector<uint8_t> codeData, std::vector<uint8_t> audioTable,
|
||||
std::vector<AudioTableEntry> audioSampleBank, AudioTableEntry& entry);
|
||||
|
||||
void ParseRawData() override;
|
||||
|
||||
std::string GetSourceTypeName() const override;
|
||||
ZResourceType GetResourceType() const override;
|
||||
|
||||
size_t GetRawDataSize() const override;
|
||||
};
|
||||
669
ZAPDTR/ZAPD/ZAudioDecode.cpp
Normal file
669
ZAPDTR/ZAPD/ZAudioDecode.cpp
Normal file
@@ -0,0 +1,669 @@
|
||||
/**
|
||||
* Bruteforcing decoder for converting ADPCM-encoded AIFC into AIFF, in a way
|
||||
* that roundtrips with vadpcm_enc.
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <unistd.h>
|
||||
|
||||
typedef signed char s8;
|
||||
typedef short s16;
|
||||
typedef int s32;
|
||||
typedef long long s64;
|
||||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define __builtin_bswap16 _byteswap_ushort
|
||||
#define __builtin_bswap32 _byteswap_ulong
|
||||
#endif
|
||||
|
||||
#define bswap16(x) __builtin_bswap16(x)
|
||||
#define bswap32(x) __builtin_bswap32(x)
|
||||
#define BSWAP16(x) x = __builtin_bswap16(x)
|
||||
#define BSWAP32(x) x = __builtin_bswap32(x)
|
||||
#define BSWAP16_MANY(x, n) \
|
||||
for (s32 _i = 0; _i < n; _i++) \
|
||||
BSWAP16((x)[_i])
|
||||
|
||||
#define NORETURN __attribute__((noreturn))
|
||||
#define UNUSED __attribute__((unused))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 ckID;
|
||||
u32 ckSize;
|
||||
} ChunkHeader;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 ckID;
|
||||
u32 ckSize;
|
||||
u32 formType;
|
||||
} Chunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s16 numChannels;
|
||||
u16 numFramesH;
|
||||
u16 numFramesL;
|
||||
s16 sampleSize;
|
||||
s16 sampleRate[5]; // 80-bit float
|
||||
u16 compressionTypeH;
|
||||
u16 compressionTypeL;
|
||||
} CommonChunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s16 MarkerID;
|
||||
u16 positionH;
|
||||
u16 positionL;
|
||||
} Marker;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s16 playMode;
|
||||
s16 beginLoop;
|
||||
s16 endLoop;
|
||||
} Loop;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s8 baseNote;
|
||||
s8 detune;
|
||||
s8 lowNote;
|
||||
s8 highNote;
|
||||
s8 lowVelocity;
|
||||
s8 highVelocity;
|
||||
s16 gain;
|
||||
Loop sustainLoop;
|
||||
Loop releaseLoop;
|
||||
} InstrumentChunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s32 offset;
|
||||
s32 blockSize;
|
||||
} SoundDataChunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
s16 version;
|
||||
s16 order;
|
||||
s16 nEntries;
|
||||
} CodeChunk;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 start;
|
||||
u32 end;
|
||||
u32 count;
|
||||
s16 state[16];
|
||||
} ALADPCMloop;
|
||||
|
||||
static char usage[] = "input.aifc output.aiff";
|
||||
static const char *progname, *infilename;
|
||||
static int framesize = 9;
|
||||
|
||||
void fail_parse(const char* fmt, ...)
|
||||
{
|
||||
char* formatted = NULL;
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int size = vsnprintf(NULL, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
if (size >= 0)
|
||||
{
|
||||
size++;
|
||||
formatted = (char*)malloc(size);
|
||||
if (formatted != NULL)
|
||||
{
|
||||
va_start(ap, fmt);
|
||||
size = vsnprintf(formatted, size, fmt, ap);
|
||||
va_end(ap);
|
||||
if (size < 0)
|
||||
{
|
||||
free(formatted);
|
||||
formatted = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (formatted != NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: %s [%s]\n", progname, formatted, infilename);
|
||||
free(formatted);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
s32 myrand()
|
||||
{
|
||||
static u64 state = 1619236481962341ULL;
|
||||
state *= 3123692312237ULL;
|
||||
state += 1;
|
||||
return state >> 33;
|
||||
}
|
||||
|
||||
s16 qsample(f32 x, s32 scale)
|
||||
{
|
||||
if (x > 0.0f)
|
||||
{
|
||||
return (s16)((x / scale) + 0.4999999);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (s16)((x / scale) - 0.4999999);
|
||||
}
|
||||
}
|
||||
|
||||
void clamp_to_s16(f32* in, s32* out)
|
||||
{
|
||||
f32 llevel = -0x8000;
|
||||
f32 ulevel = 0x7fff;
|
||||
|
||||
for (s32 i = 0; i < 16; i++)
|
||||
{
|
||||
if (in[i] > ulevel)
|
||||
in[i] = ulevel;
|
||||
if (in[i] < llevel)
|
||||
in[i] = llevel;
|
||||
|
||||
if (in[i] > 0.0f)
|
||||
{
|
||||
out[i] = (s32)(in[i] + 0.5);
|
||||
}
|
||||
else
|
||||
{
|
||||
out[i] = (s32)(in[i] - 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s16 clamp_bits(s32 x, s32 bits)
|
||||
{
|
||||
s32 lim = 1 << (bits - 1);
|
||||
if (x < -lim)
|
||||
return -lim;
|
||||
if (x > lim - 1)
|
||||
return lim - 1;
|
||||
return x;
|
||||
}
|
||||
|
||||
s32 readaifccodebook(FILE* fhandle, s32**** table, s16* order, s16* npredictors)
|
||||
{
|
||||
BSWAP16(*order);
|
||||
BSWAP16(*npredictors);
|
||||
*table = (s32***)malloc(*npredictors * sizeof(s32**));
|
||||
for (s32 i = 0; i < *npredictors; i++)
|
||||
{
|
||||
(*table)[i] = (s32**)malloc(8 * sizeof(s32*));
|
||||
for (s32 j = 0; j < 8; j++)
|
||||
{
|
||||
(*table)[i][j] = (s32*)malloc((*order + 8) * sizeof(s32));
|
||||
}
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < *npredictors; i++)
|
||||
{
|
||||
s32** table_entry = (*table)[i];
|
||||
for (s32 j = 0; j < *order; j++)
|
||||
{
|
||||
for (s32 k = 0; k < 8; k++)
|
||||
{
|
||||
s16 ts = 0;
|
||||
BSWAP16(ts);
|
||||
table_entry[k][j] = ts;
|
||||
}
|
||||
}
|
||||
|
||||
for (s32 k = 1; k < 8; k++)
|
||||
{
|
||||
table_entry[k][*order] = table_entry[k - 1][*order - 1];
|
||||
}
|
||||
|
||||
table_entry[0][*order] = 1 << 11;
|
||||
|
||||
for (s32 k = 1; k < 8; k++)
|
||||
{
|
||||
s32 j = 0;
|
||||
for (; j < k; j++)
|
||||
{
|
||||
table_entry[j][k + *order] = 0;
|
||||
}
|
||||
|
||||
for (; j < 8; j++)
|
||||
{
|
||||
table_entry[j][k + *order] = table_entry[j - k][*order];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ALADPCMloop* readlooppoints(FILE* ifile, s16* nloops)
|
||||
{
|
||||
BSWAP16(*nloops);
|
||||
ALADPCMloop* al = (ALADPCMloop*)malloc(*nloops * sizeof(ALADPCMloop));
|
||||
for (s32 i = 0; i < *nloops; i++)
|
||||
{
|
||||
BSWAP32(al[i].start);
|
||||
BSWAP32(al[i].end);
|
||||
BSWAP32(al[i].count);
|
||||
BSWAP16_MANY(al[i].state, 16);
|
||||
}
|
||||
return al;
|
||||
}
|
||||
|
||||
s32 inner_product(s32 length, s32* v1, s32* v2)
|
||||
{
|
||||
s32 out = 0;
|
||||
for (s32 i = 0; i < length; i++)
|
||||
{
|
||||
out += v1[i] * v2[i];
|
||||
}
|
||||
|
||||
// Compute "out / 2^11", rounded down.
|
||||
s32 dout = out / (1 << 11);
|
||||
s32 fiout = dout * (1 << 11);
|
||||
return dout - (out - fiout < 0);
|
||||
}
|
||||
|
||||
void my_decodeframe(u8* frame, s32* decompressed, s32* state, s32 order, s32*** coefTable)
|
||||
{
|
||||
s32 ix[16];
|
||||
|
||||
u8 header = frame[0];
|
||||
s32 scale = 1 << (header >> 4);
|
||||
s32 optimalp = header & 0xf;
|
||||
|
||||
if (framesize == 5)
|
||||
{
|
||||
for (s32 i = 0; i < 16; i += 4)
|
||||
{
|
||||
u8 c = frame[1 + i / 4];
|
||||
ix[i] = c >> 6;
|
||||
ix[i + 1] = (c >> 4) & 0x3;
|
||||
ix[i + 2] = (c >> 2) & 0x3;
|
||||
ix[i + 3] = c & 0x3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s32 i = 0; i < 16; i += 2)
|
||||
{
|
||||
u8 c = frame[1 + i / 2];
|
||||
ix[i] = c >> 4;
|
||||
ix[i + 1] = c & 0xf;
|
||||
}
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < 16; i++)
|
||||
{
|
||||
if (framesize == 5)
|
||||
{
|
||||
if (ix[i] >= 2)
|
||||
ix[i] -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ix[i] >= 8)
|
||||
ix[i] -= 16;
|
||||
}
|
||||
decompressed[i] = ix[i];
|
||||
ix[i] *= scale;
|
||||
}
|
||||
|
||||
for (s32 j = 0; j < 2; j++)
|
||||
{
|
||||
s32 in_vec[16];
|
||||
if (j == 0)
|
||||
{
|
||||
for (s32 i = 0; i < order; i++)
|
||||
{
|
||||
in_vec[i] = state[16 - order + i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s32 i = 0; i < order; i++)
|
||||
{
|
||||
in_vec[i] = state[8 - order + i];
|
||||
}
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < 8; i++)
|
||||
{
|
||||
s32 ind = j * 8 + i;
|
||||
in_vec[order + i] = ix[ind];
|
||||
state[ind] = inner_product(order + i, coefTable[optimalp][i], in_vec) + ix[ind];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void get_bounds(s32* in, s32* decompressed, s32 scale, s32* minVals, s32* maxVals)
|
||||
{
|
||||
s32 minv, maxv;
|
||||
if (framesize == 9)
|
||||
{
|
||||
minv = -8;
|
||||
maxv = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
minv = -2;
|
||||
maxv = 1;
|
||||
}
|
||||
for (s32 i = 0; i < 16; i++)
|
||||
{
|
||||
s32 lo = in[i] - scale / 2;
|
||||
s32 hi = in[i] + scale / 2;
|
||||
lo -= scale;
|
||||
hi += scale;
|
||||
if (decompressed[i] == minv)
|
||||
lo -= scale;
|
||||
else if (decompressed[i] == maxv)
|
||||
hi += scale;
|
||||
minVals[i] = lo;
|
||||
maxVals[i] = hi;
|
||||
}
|
||||
}
|
||||
|
||||
void write_header(FILE* ofile, const char* id, s32 size)
|
||||
{
|
||||
fwrite(id, 4, 1, ofile);
|
||||
BSWAP32(size);
|
||||
fwrite(&size, sizeof(s32), 1, ofile);
|
||||
}
|
||||
|
||||
char* OldMain(char* infilename)
|
||||
{
|
||||
s16 order = -1;
|
||||
s16 nloops = 0;
|
||||
ALADPCMloop* aloops = NULL;
|
||||
s16 npredictors = -1;
|
||||
s32*** coefTable = NULL;
|
||||
s32 state[16];
|
||||
s32 decompressed[16];
|
||||
s32 soundPointer = -1;
|
||||
s32 currPos = 0;
|
||||
s32 nSamples = 0;
|
||||
Chunk FormChunk = Chunk();
|
||||
ChunkHeader Header = ChunkHeader();
|
||||
CommonChunk CommChunk = CommonChunk();
|
||||
InstrumentChunk InstChunk;
|
||||
SoundDataChunk SndDChunk = SoundDataChunk();
|
||||
FILE* ifile = NULL;
|
||||
FILE* ofile = NULL;
|
||||
|
||||
if ((ifile = fopen(infilename, "rb")) == NULL)
|
||||
{
|
||||
fail_parse("AIFF-C file could not be opened");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(&InstChunk, 0, sizeof(InstChunk));
|
||||
|
||||
BSWAP32(FormChunk.ckID);
|
||||
BSWAP32(FormChunk.formType);
|
||||
if ((FormChunk.ckID != 0x464f524d) || (FormChunk.formType != 0x41494643))
|
||||
{ // FORM, AIFC
|
||||
fail_parse("not an AIFF-C file");
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
s32 num = fread(&Header, sizeof(Header), 1, ifile);
|
||||
u32 ts = 0;
|
||||
|
||||
if (num <= 0)
|
||||
break;
|
||||
|
||||
BSWAP32(Header.ckID);
|
||||
BSWAP32(Header.ckSize);
|
||||
|
||||
Header.ckSize++;
|
||||
Header.ckSize &= ~1;
|
||||
s32 offset = ftell(ifile);
|
||||
|
||||
switch (Header.ckID)
|
||||
{
|
||||
case 0x434f4d4d: // COMM
|
||||
{
|
||||
BSWAP16(CommChunk.numChannels);
|
||||
BSWAP16(CommChunk.numFramesH);
|
||||
BSWAP16(CommChunk.numFramesL);
|
||||
BSWAP16(CommChunk.sampleSize);
|
||||
BSWAP16(CommChunk.compressionTypeH);
|
||||
BSWAP16(CommChunk.compressionTypeL);
|
||||
s32 cType = (CommChunk.compressionTypeH << 16) + CommChunk.compressionTypeL;
|
||||
if (cType == 0x56415043 || cType == 0x41445039)
|
||||
{ // VAPC or ADP9
|
||||
framesize = 9;
|
||||
}
|
||||
else if (cType == 0x41445035)
|
||||
{ // ADP5
|
||||
framesize = 5;
|
||||
}
|
||||
else if (cType == 0x4850434d)
|
||||
{ // HPCM
|
||||
framesize = 16;
|
||||
}
|
||||
else
|
||||
{
|
||||
char comprType[5] = {
|
||||
static_cast<char>(CommChunk.compressionTypeH >> 8), static_cast<char>(CommChunk.compressionTypeH & 0xFF),
|
||||
static_cast<char>(CommChunk.compressionTypeL >> 8), static_cast<char>(CommChunk.compressionTypeL & 0xFF), 0};
|
||||
fail_parse("file is of the wrong compression type [got %s (%08x)]", &comprType,
|
||||
cType);
|
||||
}
|
||||
if (CommChunk.numChannels != 1)
|
||||
{
|
||||
fail_parse("file contains %d channels, only 1 channel supported",
|
||||
CommChunk.numChannels);
|
||||
}
|
||||
if (CommChunk.sampleSize != 16)
|
||||
{
|
||||
fail_parse("file contains %d bit samples, only 16 bit samples supported",
|
||||
CommChunk.sampleSize);
|
||||
}
|
||||
|
||||
nSamples = (CommChunk.numFramesH << 16) + CommChunk.numFramesL;
|
||||
|
||||
// Allow broken input lengths
|
||||
if (nSamples % 16)
|
||||
{
|
||||
nSamples -= (nSamples % 16);
|
||||
}
|
||||
|
||||
if (nSamples % 16 != 0)
|
||||
{
|
||||
fail_parse("number of chunks must be a multiple of 16, found %d with remainder %d",
|
||||
nSamples, nSamples % 16);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x53534e44: // SSND
|
||||
BSWAP32(SndDChunk.offset);
|
||||
BSWAP32(SndDChunk.blockSize);
|
||||
assert(SndDChunk.offset == 0);
|
||||
assert(SndDChunk.blockSize == 0);
|
||||
soundPointer = ftell(ifile);
|
||||
break;
|
||||
|
||||
case 0x4150504c: // APPL
|
||||
BSWAP32(ts);
|
||||
if (ts == 0x73746f63)
|
||||
{ // stoc
|
||||
u8 len = 0;
|
||||
if (len == 11)
|
||||
{
|
||||
char ChunkName[12];
|
||||
s16 version;
|
||||
ChunkName[11] = '\0';
|
||||
if (strcmp("VADPCMCODES", ChunkName) == 0)
|
||||
{
|
||||
BSWAP16(version);
|
||||
if (version != 1)
|
||||
{
|
||||
fail_parse("Unknown codebook chunk version");
|
||||
}
|
||||
readaifccodebook(ifile, &coefTable, &order, &npredictors);
|
||||
}
|
||||
else if (strcmp("VADPCMLOOPS", ChunkName) == 0)
|
||||
{
|
||||
BSWAP16(version);
|
||||
if (version != 1)
|
||||
{
|
||||
fail_parse("Unknown loop chunk version");
|
||||
}
|
||||
aloops = readlooppoints(ifile, &nloops);
|
||||
if (nloops != 1)
|
||||
{
|
||||
fail_parse("Only a single loop supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
fseek(ifile, offset + Header.ckSize, SEEK_SET);
|
||||
}
|
||||
|
||||
if (coefTable == NULL)
|
||||
{
|
||||
fail_parse("Codebook missing from bitstream");
|
||||
}
|
||||
|
||||
for (s32 i = 0; i < order; i++)
|
||||
{
|
||||
state[15 - i] = 0;
|
||||
}
|
||||
|
||||
u32 outputBytes = nSamples * sizeof(s16);
|
||||
u8* outputBuf = (u8*)malloc(outputBytes);
|
||||
|
||||
fseek(ifile, soundPointer, SEEK_SET);
|
||||
s32 fails = 0;
|
||||
while (currPos < nSamples)
|
||||
{
|
||||
u8 input[9];
|
||||
u8 encoded[9];
|
||||
s32 lastState[16];
|
||||
s32 decoded[16];
|
||||
s16 guess[16];
|
||||
s16 origGuess[16];
|
||||
|
||||
memcpy(lastState, state, sizeof(state));
|
||||
|
||||
// Decode for real
|
||||
my_decodeframe(input, decompressed, state, order, coefTable);
|
||||
memcpy(decoded, state, sizeof(state));
|
||||
|
||||
// Create a guess from that, by clamping to 16 bits
|
||||
for (s32 i = 0; i < 16; i++)
|
||||
{
|
||||
origGuess[i] = clamp_bits(state[i], 16);
|
||||
}
|
||||
|
||||
memcpy(state, decoded, sizeof(state));
|
||||
memcpy(outputBuf + currPos * 2, decoded, sizeof(decoded));
|
||||
currPos += 16;
|
||||
}
|
||||
if (fails)
|
||||
{
|
||||
fprintf(stderr, "%s %d\n", infilename, fails);
|
||||
}
|
||||
|
||||
// Write an incomplete file header. We'll fill in the size later.
|
||||
fwrite("FORM\0\0\0\0AIFF", 12, 1, ofile);
|
||||
|
||||
// Subtract 4 from the COMM size to skip the compression field.
|
||||
write_header(ofile, "COMM", sizeof(CommonChunk) - 4);
|
||||
CommChunk.numFramesH = nSamples >> 16;
|
||||
CommChunk.numFramesL = nSamples & 0xffff;
|
||||
BSWAP16(CommChunk.numChannels);
|
||||
BSWAP16(CommChunk.numFramesH);
|
||||
BSWAP16(CommChunk.numFramesL);
|
||||
BSWAP16(CommChunk.sampleSize);
|
||||
fwrite(&CommChunk, sizeof(CommonChunk) - 4, 1, ofile);
|
||||
|
||||
if (nloops > 0)
|
||||
{
|
||||
s32 startPos = aloops[0].start, endPos = aloops[0].end;
|
||||
const char* markerNames[2] = {"start", "end"};
|
||||
Marker markers[2] = {{1, static_cast<u16>(startPos >> 16), static_cast<u16>(startPos & 0xffff)},
|
||||
{2, static_cast<u16>(endPos >> 16), static_cast<u16>(endPos & 0xffff)}};
|
||||
write_header(ofile, "MARK", 2 + 2 * sizeof(Marker) + 1 + 5 + 1 + 3);
|
||||
s16 numMarkers = bswap16(2);
|
||||
fwrite(&numMarkers, sizeof(s16), 1, ofile);
|
||||
for (s32 i = 0; i < 2; i++)
|
||||
{
|
||||
u8 len = (u8)strlen(markerNames[i]);
|
||||
BSWAP16(markers[i].MarkerID);
|
||||
BSWAP16(markers[i].positionH);
|
||||
BSWAP16(markers[i].positionL);
|
||||
fwrite(&markers[i], sizeof(Marker), 1, ofile);
|
||||
fwrite(&len, 1, 1, ofile);
|
||||
fwrite(markerNames[i], len, 1, ofile);
|
||||
}
|
||||
|
||||
write_header(ofile, "INST", sizeof(InstrumentChunk));
|
||||
InstChunk.sustainLoop.playMode = bswap16(1);
|
||||
InstChunk.sustainLoop.beginLoop = bswap16(1);
|
||||
InstChunk.sustainLoop.endLoop = bswap16(2);
|
||||
InstChunk.releaseLoop.playMode = 0;
|
||||
InstChunk.releaseLoop.beginLoop = 0;
|
||||
InstChunk.releaseLoop.endLoop = 0;
|
||||
fwrite(&InstChunk, sizeof(InstrumentChunk), 1, ofile);
|
||||
}
|
||||
|
||||
// Save the coefficient table for use when encoding. Ideally this wouldn't
|
||||
// be needed and "tabledesign -s 1" would generate the right table, but in
|
||||
// practice it's difficult to adjust samples to make that happen.
|
||||
write_header(ofile, "APPL", 4 + 12 + sizeof(CodeChunk) + npredictors * order * 8 * 2);
|
||||
fwrite("stoc", 4, 1, ofile);
|
||||
CodeChunk cChunk;
|
||||
cChunk.version = bswap16(1);
|
||||
cChunk.order = bswap16(order);
|
||||
cChunk.nEntries = bswap16(npredictors);
|
||||
fwrite("\x0bVADPCMCODES", 12, 1, ofile);
|
||||
fwrite(&cChunk, sizeof(CodeChunk), 1, ofile);
|
||||
for (s32 i = 0; i < npredictors; i++)
|
||||
{
|
||||
for (s32 j = 0; j < order; j++)
|
||||
{
|
||||
for (s32 k = 0; k < 8; k++)
|
||||
{
|
||||
s16 ts = bswap16(coefTable[i][k][j]);
|
||||
fwrite(&ts, sizeof(s16), 1, ofile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write_header(ofile, "SSND", outputBytes + 8);
|
||||
SndDChunk.offset = 0;
|
||||
SndDChunk.blockSize = 0;
|
||||
fwrite(&SndDChunk, sizeof(SoundDataChunk), 1, ofile);
|
||||
fwrite(outputBuf, outputBytes, 1, ofile);
|
||||
|
||||
// Fix the size in the header
|
||||
s32 fileSize = bswap32(ftell(ofile) - 8);
|
||||
fseek(ofile, 4, SEEK_SET);
|
||||
fwrite(&fileSize, 4, 1, ofile);
|
||||
|
||||
fclose(ifile);
|
||||
fclose(ofile);
|
||||
return 0;
|
||||
}
|
||||
195
ZAPDTR/ZAPD/ZBackground.cpp
Normal file
195
ZAPDTR/ZAPD/ZBackground.cpp
Normal file
@@ -0,0 +1,195 @@
|
||||
#include "ZBackground.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include <Utils/DiskFile.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 = DiskFile::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)
|
||||
{
|
||||
if (!Globals::Instance->otrMode)
|
||||
{
|
||||
fs::path filepath = outFolder / (outName + "." + GetExternalExtension());
|
||||
DiskFile::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
34
ZAPDTR/ZAPD/ZBackground.h
Normal 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
116
ZAPDTR/ZAPD/ZBlob.cpp
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "ZBlob.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include <Utils/DiskFile.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 = DiskFile::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)
|
||||
DiskFile::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
31
ZAPDTR/ZAPD/ZBlob.h
Normal 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;
|
||||
};
|
||||
307
ZAPDTR/ZAPD/ZCKeyFrame.cpp
Normal file
307
ZAPDTR/ZAPD/ZCKeyFrame.cpp
Normal file
@@ -0,0 +1,307 @@
|
||||
#include "ZCKeyFrame.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "WarningHandler.h"
|
||||
|
||||
REGISTER_ZFILENODE(KeyFrameSkel, ZKeyFrameSkel);
|
||||
REGISTER_ZFILENODE(KeyFrameLimbList, ZKeyFrameLimbList);
|
||||
|
||||
ZKeyFrameSkel::ZKeyFrameSkel(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
RegisterRequiredAttribute("LimbType");
|
||||
genOTRDef = true;
|
||||
}
|
||||
|
||||
ZKeyFrameSkel::~ZKeyFrameSkel()
|
||||
{
|
||||
}
|
||||
|
||||
ZKeyFrameLimb::ZKeyFrameLimb(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
}
|
||||
|
||||
ZKeyFrameStandardLimb::ZKeyFrameStandardLimb(ZFile* nParent) : ZKeyFrameLimb(nParent)
|
||||
{
|
||||
}
|
||||
|
||||
ZKeyFrameFlexLimb::ZKeyFrameFlexLimb(ZFile* nParent) : ZKeyFrameLimb(nParent)
|
||||
{
|
||||
}
|
||||
|
||||
ZKeyFrameLimbList::ZKeyFrameLimbList(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
RegisterRequiredAttribute("LimbType");
|
||||
RegisterRequiredAttribute("LimbCount");
|
||||
}
|
||||
|
||||
ZKeyFrameLimbList::ZKeyFrameLimbList(ZFile* nParent, uint32_t limbCount, ZKeyframeSkelType type)
|
||||
: ZResource(nParent)
|
||||
{
|
||||
numLimbs = limbCount;
|
||||
limbType = type;
|
||||
}
|
||||
|
||||
ZKeyFrameLimbList::~ZKeyFrameLimbList()
|
||||
{
|
||||
for (const auto l : limbs)
|
||||
delete l;
|
||||
}
|
||||
|
||||
void ZKeyFrameSkel::ParseXML(tinyxml2::XMLElement* reader)
|
||||
{
|
||||
ZResource::ParseXML(reader);
|
||||
|
||||
std::string limbTypeStr = registeredAttributes.at("LimbType").value;
|
||||
|
||||
limbType = ZKeyFrameLimbList::ParseLimbTypeStr(limbTypeStr);
|
||||
if (limbType == ZKeyframeSkelType::Error)
|
||||
HANDLE_ERROR_RESOURCE(
|
||||
WarningType::InvalidXML, parent, this, rawDataIndex, "Invalid limb type",
|
||||
StringHelper::Sprintf("Invalid limb type. Was expecting 'Flex' or 'Normal'. Got %s.",
|
||||
limbTypeStr.c_str()));
|
||||
}
|
||||
void ZKeyFrameLimbList::ParseXML(tinyxml2::XMLElement* reader)
|
||||
{
|
||||
ZResource::ParseXML(reader);
|
||||
|
||||
std::string limbTypeStr = registeredAttributes.at("LimbType").value;
|
||||
std::string numLimbStr = registeredAttributes.at("LimbCount").value;
|
||||
|
||||
limbType = ParseLimbTypeStr(limbTypeStr);
|
||||
|
||||
if (limbType == ZKeyframeSkelType::Error)
|
||||
HANDLE_ERROR_RESOURCE(
|
||||
WarningType::InvalidXML, parent, this, rawDataIndex, "Invalid limb type",
|
||||
StringHelper::Sprintf("Invalid limb type. Was expecting 'Flex' or 'Normal'. Got %s.",
|
||||
limbTypeStr.c_str()));
|
||||
|
||||
numLimbs = (uint8_t)StringHelper::StrToL(numLimbStr);
|
||||
}
|
||||
|
||||
void ZKeyFrameSkel::ParseRawData()
|
||||
{
|
||||
ZResource::ParseRawData();
|
||||
|
||||
const auto& rawData = parent->GetRawData();
|
||||
limbCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0);
|
||||
dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 1);
|
||||
limbsPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
|
||||
|
||||
limbList = std::make_unique<ZKeyFrameLimbList>(parent, limbCount, limbType);
|
||||
limbList->SetRawDataIndex(GETSEGOFFSET(limbsPtr));
|
||||
limbList->ParseRawData();
|
||||
}
|
||||
|
||||
void ZKeyFrameSkel::DeclareReferences(const std::string& prefix)
|
||||
{
|
||||
std::string defaultPrefix = name;
|
||||
std::string declaration;
|
||||
|
||||
if (defaultPrefix == "")
|
||||
defaultPrefix = prefix;
|
||||
|
||||
ZResource::DeclareReferences(defaultPrefix);
|
||||
declaration += limbList->GetBodySourceCode();
|
||||
parent->AddDeclarationArray(
|
||||
GETSEGOFFSET(limbsPtr), DeclarationAlignment::Align4, limbList->GetRawDataSize(),
|
||||
limbList->GetSourceTypeName(),
|
||||
StringHelper::Sprintf("%s_KeyFrameLimbs_%06X", prefix.c_str(), rawDataIndex),
|
||||
limbList->limbs.size(), declaration);
|
||||
}
|
||||
|
||||
std::string ZKeyFrameSkel::GetBodySourceCode() const
|
||||
{
|
||||
std::string limbStr;
|
||||
|
||||
if (limbType == ZKeyframeSkelType::Normal)
|
||||
Globals::Instance->GetSegmentedPtrName(limbsPtr, parent, "KeyFrameStandardLimb", limbStr,
|
||||
parent->workerID);
|
||||
else
|
||||
Globals::Instance->GetSegmentedPtrName(limbsPtr, parent, "KeyFrameFlexLimb", limbStr,
|
||||
parent->workerID);
|
||||
|
||||
return StringHelper::Sprintf("\n\t0x%02X, 0x%02X, %s\n", limbCount, dListCount,
|
||||
limbStr.c_str());
|
||||
}
|
||||
|
||||
size_t ZKeyFrameSkel::GetRawDataSize() const
|
||||
{
|
||||
return 0x8;
|
||||
}
|
||||
|
||||
std::string ZKeyFrameSkel::GetSourceTypeName() const
|
||||
{
|
||||
return "KeyFrameSkeleton";
|
||||
}
|
||||
|
||||
ZResourceType ZKeyFrameSkel::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::KeyFrameSkel;
|
||||
}
|
||||
|
||||
size_t ZKeyFrameStandardLimb::GetRawDataSize() const
|
||||
{
|
||||
return 0xC;
|
||||
}
|
||||
|
||||
size_t ZKeyFrameFlexLimb::GetRawDataSize() const
|
||||
{
|
||||
return 0x8;
|
||||
}
|
||||
|
||||
size_t ZKeyFrameLimbList::GetRawDataSize() const
|
||||
{
|
||||
size_t limbSize;
|
||||
if (limbType == ZKeyframeSkelType::Flex)
|
||||
limbSize = 0x8;
|
||||
else
|
||||
limbSize = 0xC;
|
||||
|
||||
return limbSize * numLimbs;
|
||||
}
|
||||
|
||||
ZKeyframeSkelType ZKeyFrameLimbList::ParseLimbTypeStr(const std::string& typeStr)
|
||||
{
|
||||
if (typeStr == "Flex")
|
||||
return ZKeyframeSkelType::Flex;
|
||||
else if (typeStr == "Normal")
|
||||
return ZKeyframeSkelType::Normal;
|
||||
else
|
||||
return ZKeyframeSkelType::Error;
|
||||
}
|
||||
|
||||
void ZKeyFrameLimb::ParseRawData()
|
||||
{
|
||||
const auto& rawData = parent->GetRawData();
|
||||
|
||||
dlist = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0);
|
||||
numChildren = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x4);
|
||||
flags = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x5);
|
||||
}
|
||||
|
||||
void ZKeyFrameStandardLimb::ParseRawData()
|
||||
{
|
||||
const auto& rawData = parent->GetRawData();
|
||||
|
||||
ZKeyFrameLimb::ParseRawData();
|
||||
translation.x = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x6);
|
||||
translation.y = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x8);
|
||||
translation.z = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0xA);
|
||||
}
|
||||
|
||||
void ZKeyFrameFlexLimb::ParseRawData()
|
||||
{
|
||||
const auto& rawData = parent->GetRawData();
|
||||
|
||||
ZKeyFrameLimb::ParseRawData();
|
||||
callbackIndex = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x6);
|
||||
}
|
||||
|
||||
void ZKeyFrameLimbList::ParseRawData()
|
||||
{
|
||||
limbs.reserve(numLimbs);
|
||||
rawDataIndex = GetRawDataIndex();
|
||||
|
||||
for (uint32_t i = 0; i < numLimbs; i++)
|
||||
{
|
||||
ZKeyFrameLimb* limb;
|
||||
if (limbType == ZKeyframeSkelType::Flex)
|
||||
limb = new ZKeyFrameFlexLimb(parent);
|
||||
else
|
||||
limb = new ZKeyFrameStandardLimb(parent);
|
||||
|
||||
limb->SetRawDataIndex(rawDataIndex + (offset_t)(i * limb->GetRawDataSize()));
|
||||
limb->ParseRawData();
|
||||
limbs.push_back(limb);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ZKeyFrameLimbList::GetBodySourceCode() const
|
||||
{
|
||||
std::string declaration;
|
||||
|
||||
for (const auto l : limbs)
|
||||
declaration += StringHelper::Sprintf("\t{ %s },\n", l->GetBodySourceCode().c_str());
|
||||
// Remove last newline
|
||||
return declaration.substr(0, declaration.length() - 1);
|
||||
}
|
||||
|
||||
std::string ZKeyFrameStandardLimb::GetBodySourceCode() const
|
||||
{
|
||||
std::string declaration;
|
||||
std::string dlString;
|
||||
|
||||
Globals::Instance->GetSegmentedArrayIndexedName(dlist, 8, parent, "Gfx", dlString,
|
||||
parent->workerID);
|
||||
|
||||
declaration +=
|
||||
StringHelper::Sprintf("%s, 0x%02X, 0x%02X, { 0x%04X, 0x%04X, 0x%04X},", dlString.c_str(),
|
||||
numChildren, flags, translation.x, translation.y, translation.z);
|
||||
return declaration;
|
||||
}
|
||||
|
||||
std::string ZKeyFrameFlexLimb::GetBodySourceCode() const
|
||||
{
|
||||
std::string declaration;
|
||||
|
||||
std::string dlString;
|
||||
|
||||
Globals::Instance->GetSegmentedArrayIndexedName(dlist, 8, parent, "Gfx", dlString,
|
||||
parent->workerID);
|
||||
|
||||
declaration += StringHelper::Sprintf("%s, 0x%02X, 0x%02X, 0x%02X", dlString.c_str(),
|
||||
numChildren, flags, callbackIndex);
|
||||
return declaration;
|
||||
}
|
||||
|
||||
std::string ZKeyFrameStandardLimb::GetSourceTypeName() const
|
||||
{
|
||||
return "KeyFrameStandardLimb";
|
||||
}
|
||||
|
||||
std::string ZKeyFrameFlexLimb::GetSourceTypeName() const
|
||||
{
|
||||
return "KeyFrameFlexLimb";
|
||||
}
|
||||
|
||||
std::string ZKeyFrameLimbList::GetSourceTypeName() const
|
||||
{
|
||||
switch (limbType)
|
||||
{
|
||||
case ZKeyframeSkelType::Flex:
|
||||
return "KeyFrameFlexLimb";
|
||||
case ZKeyframeSkelType::Normal:
|
||||
return "KeyFrameStandardLimb";
|
||||
default:
|
||||
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex,
|
||||
"Invalid limb type", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ZResourceType ZKeyFrameStandardLimb::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::KeyFrameStandardLimb;
|
||||
}
|
||||
|
||||
ZResourceType ZKeyFrameFlexLimb::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::KeyFrameFlexLimb;
|
||||
}
|
||||
|
||||
ZResourceType ZKeyFrameLimbList::GetResourceType() const
|
||||
{
|
||||
switch (limbType)
|
||||
{
|
||||
case ZKeyframeSkelType::Flex:
|
||||
return ZResourceType::KeyFrameFlexLimb;
|
||||
case ZKeyframeSkelType::Normal:
|
||||
return ZResourceType::KeyFrameStandardLimb;
|
||||
default:
|
||||
HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex,
|
||||
"Invalid limb type", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
121
ZAPDTR/ZAPD/ZCKeyFrame.h
Normal file
121
ZAPDTR/ZAPD/ZCKeyFrame.h
Normal file
@@ -0,0 +1,121 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "ZFile.h"
|
||||
|
||||
class ZKeyFrameLimb;
|
||||
|
||||
struct Vec3s
|
||||
{
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t z;
|
||||
};
|
||||
|
||||
enum class ZKeyframeSkelType
|
||||
{
|
||||
Normal,
|
||||
Flex,
|
||||
Error,
|
||||
};
|
||||
|
||||
class ZKeyFrameLimbList : public ZResource
|
||||
{
|
||||
public:
|
||||
ZKeyFrameLimbList();
|
||||
ZKeyFrameLimbList(ZFile* nParent);
|
||||
ZKeyFrameLimbList(ZFile* nParent, uint32_t limbCount, ZKeyframeSkelType type);
|
||||
|
||||
~ZKeyFrameLimbList();
|
||||
|
||||
void ParseRawData() override;
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
void ParseXML(tinyxml2::XMLElement* reader) override;
|
||||
|
||||
std::string GetSourceTypeName() const override;
|
||||
ZResourceType GetResourceType() const override;
|
||||
|
||||
size_t GetRawDataSize() const override;
|
||||
|
||||
static ZKeyframeSkelType ParseLimbTypeStr(const std::string& typeStr);
|
||||
|
||||
std::vector<ZKeyFrameLimb*> limbs;
|
||||
ZKeyframeSkelType limbType;
|
||||
uint8_t numLimbs;
|
||||
};
|
||||
|
||||
class ZKeyFrameLimb : public ZResource
|
||||
{
|
||||
public:
|
||||
segptr_t dlist;
|
||||
uint8_t numChildren;
|
||||
uint8_t flags;
|
||||
|
||||
ZKeyFrameLimb(ZFile* nParent);
|
||||
void ParseRawData() override;
|
||||
};
|
||||
|
||||
class ZKeyFrameStandardLimb : public ZKeyFrameLimb
|
||||
{
|
||||
public:
|
||||
Vec3s translation;
|
||||
|
||||
ZKeyFrameStandardLimb(ZFile* nParent);
|
||||
void ParseRawData() override;
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
|
||||
std::string GetSourceTypeName() const override;
|
||||
ZResourceType GetResourceType() const override;
|
||||
|
||||
size_t GetRawDataSize() const override;
|
||||
};
|
||||
|
||||
class ZKeyFrameFlexLimb : public ZKeyFrameLimb
|
||||
{
|
||||
public:
|
||||
uint8_t callbackIndex;
|
||||
|
||||
ZKeyFrameFlexLimb(ZFile* nParent);
|
||||
// void ParseXML(tinyxml2::XMLElement* reader) override;
|
||||
void ParseRawData() override;
|
||||
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
// std::string GetSourceOutputHeader(const std::string& prefix) override;
|
||||
|
||||
std::string GetSourceTypeName() const override;
|
||||
ZResourceType GetResourceType() const override;
|
||||
|
||||
size_t GetRawDataSize() const override;
|
||||
};
|
||||
|
||||
class ZKeyFrameSkel : public ZResource
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<ZKeyFrameLimbList> limbList;
|
||||
segptr_t limbsPtr;
|
||||
ZKeyframeSkelType limbType;
|
||||
uint8_t limbCount;
|
||||
uint8_t dListCount;
|
||||
|
||||
ZKeyFrameSkel(ZFile* nParent);
|
||||
~ZKeyFrameSkel();
|
||||
|
||||
void ParseXML(tinyxml2::XMLElement* reader) override;
|
||||
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;
|
||||
};
|
||||
221
ZAPDTR/ZAPD/ZCKeyFrameAnim.cpp
Normal file
221
ZAPDTR/ZAPD/ZCKeyFrameAnim.cpp
Normal file
@@ -0,0 +1,221 @@
|
||||
#include "ZCkeyFrameAnim.h"
|
||||
#include "ZCKeyFrame.h"
|
||||
#include "Globals.h"
|
||||
|
||||
#include "Utils/BitConverter.h"
|
||||
|
||||
REGISTER_ZFILENODE(KeyFrameAnimation, ZKeyFrameAnim);
|
||||
|
||||
ZKeyFrameAnim::ZKeyFrameAnim(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
RegisterRequiredAttribute("Skel");
|
||||
genOTRDef = true;
|
||||
}
|
||||
|
||||
ZKeyFrameAnim::~ZKeyFrameAnim()
|
||||
{
|
||||
}
|
||||
|
||||
void ZKeyFrameAnim::ParseXML(tinyxml2::XMLElement* reader)
|
||||
{
|
||||
ZResource::ParseXML(reader);
|
||||
|
||||
std::string skelAddrStr = registeredAttributes.at("Skel").value;
|
||||
skelOffset = (offset_t)StringHelper::StrToL(skelAddrStr, 16);
|
||||
}
|
||||
|
||||
void ZKeyFrameAnim::DeclareReferencesLate(const std::string& prefix)
|
||||
{
|
||||
std::string defaultPrefix = name;
|
||||
std::string declaration;
|
||||
|
||||
if (defaultPrefix == "")
|
||||
defaultPrefix = prefix;
|
||||
|
||||
ZResource::DeclareReferences(defaultPrefix);
|
||||
|
||||
declaration += "\t";
|
||||
|
||||
if (skel->limbType == ZKeyframeSkelType::Normal)
|
||||
{
|
||||
for (const auto b : bitFlags)
|
||||
{
|
||||
declaration += StringHelper::Sprintf("0x%02X, ", b);
|
||||
parent->AddDeclarationArray(
|
||||
GETSEGOFFSET(bitFlagsAddr), DeclarationAlignment::Align4, bitFlags.size(), "u8",
|
||||
StringHelper::Sprintf("%s_bitFlags_%06X", prefix.c_str(), rawDataIndex),
|
||||
bitFlags.size(), declaration);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (const auto b : bitFlagsFlex)
|
||||
{
|
||||
declaration += StringHelper::Sprintf("0x%04X, ", b);
|
||||
parent->AddDeclarationArray(
|
||||
GETSEGOFFSET(bitFlagsAddr), DeclarationAlignment::Align4, bitFlagsFlex.size() * 2,
|
||||
"u16", StringHelper::Sprintf("%s_flexBitFlags_%06X", prefix.c_str(), rawDataIndex),
|
||||
bitFlagsFlex.size(), declaration);
|
||||
}
|
||||
}
|
||||
declaration.clear();
|
||||
|
||||
for (const auto kf : keyFrames)
|
||||
{
|
||||
declaration +=
|
||||
StringHelper::Sprintf(" \t { %i, %i, %i, },\n", kf.frame, kf.value, kf.velocity);
|
||||
}
|
||||
// Remove last new line to prevent an extra line after the last element
|
||||
declaration = declaration.substr(0, declaration.length() - 1);
|
||||
parent->AddDeclarationArray(
|
||||
GETSEGOFFSET(keyFramesAddr), DeclarationAlignment::Align4, keyFrames.size() * 6, "KeyFrame",
|
||||
StringHelper::Sprintf("%s_KeyFrame_%06X", prefix.c_str(), rawDataIndex), keyFrames.size(),
|
||||
declaration);
|
||||
|
||||
declaration.clear();
|
||||
|
||||
declaration += "\t";
|
||||
|
||||
for (const auto kfNum : kfNums)
|
||||
{
|
||||
declaration += StringHelper::Sprintf("0x%04X, ", kfNum);
|
||||
}
|
||||
|
||||
parent->AddDeclarationArray(
|
||||
GETSEGOFFSET(kfNumsAddr), DeclarationAlignment::Align4, kfNums.size() * 2, "s16",
|
||||
StringHelper::Sprintf("%s_kfNums_%06X", prefix.c_str(), rawDataIndex), kfNums.size(),
|
||||
declaration);
|
||||
declaration += "\n";
|
||||
|
||||
declaration.clear();
|
||||
|
||||
declaration += "\t";
|
||||
|
||||
for (const auto pv : presetValues)
|
||||
{
|
||||
declaration += StringHelper::Sprintf("0x%04X, ", pv);
|
||||
}
|
||||
declaration += "\n";
|
||||
parent->AddDeclarationArray(
|
||||
GETSEGOFFSET(presentValuesAddr), DeclarationAlignment::Align4, presetValues.size() * 2,
|
||||
"s16", StringHelper::Sprintf("%s_presetValues_%06X", prefix.c_str(), rawDataIndex),
|
||||
presetValues.size(), declaration);
|
||||
|
||||
}
|
||||
|
||||
// ParseRawDataLate is used because we need to make sure the flex skel has been processed first.
|
||||
void ZKeyFrameAnim::ParseRawDataLate()
|
||||
{
|
||||
const auto& rawData = parent->GetRawData();
|
||||
|
||||
skel = static_cast<ZKeyFrameSkel*>(parent->FindResource(skelOffset));
|
||||
size_t numLimbs = skel->limbCount;
|
||||
|
||||
bitFlagsAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0);
|
||||
keyFramesAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x4);
|
||||
kfNumsAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x8);
|
||||
presentValuesAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0xC);
|
||||
|
||||
uint32_t kfNumsSize = 0;
|
||||
uint32_t presetValuesSize = 0;
|
||||
uint32_t keyFramesCount = 0;
|
||||
if (skel->limbType == ZKeyframeSkelType::Normal)
|
||||
{
|
||||
bitFlags.reserve(numLimbs);
|
||||
for (size_t i = 0; i < numLimbs; i++)
|
||||
{
|
||||
uint8_t e = BitConverter::ToUInt8BE(rawData, GETSEGOFFSET(bitFlagsAddr) + i);
|
||||
bitFlags.push_back(e);
|
||||
kfNumsSize += GetSetBits((uint8_t)(e & 0b111111));
|
||||
presetValuesSize += GetSetBits((uint8_t)((e ^ 0xFF) & 0b111111));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bitFlagsFlex.reserve(numLimbs);
|
||||
for (size_t i = 0; i < numLimbs; i++)
|
||||
{
|
||||
uint16_t e = BitConverter::ToUInt16BE(rawData, GETSEGOFFSET(bitFlagsAddr) + (i * 2));
|
||||
bitFlagsFlex.push_back(e);
|
||||
kfNumsSize += GetSetBits((uint16_t)(e & 0b111111111));
|
||||
presetValuesSize += GetSetBits((uint16_t)((e ^ 0xFFFF) & 0b111111111));
|
||||
}
|
||||
}
|
||||
|
||||
kfNums.reserve(kfNumsSize);
|
||||
for (uint32_t i = 0; i < kfNumsSize; i++)
|
||||
{
|
||||
int16_t kfNum = BitConverter::ToUInt16BE(rawData, GETSEGOFFSET(kfNumsAddr) + (i * 2));
|
||||
keyFramesCount += kfNum;
|
||||
kfNums.push_back(kfNum);
|
||||
}
|
||||
|
||||
keyFrames.reserve(keyFramesCount);
|
||||
for (uint32_t i = 0; i < keyFramesCount; i++)
|
||||
{
|
||||
KeyFrame kf;
|
||||
kf.frame = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 0) + (i * 6));
|
||||
kf.value = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 2) + (i * 6));
|
||||
kf.velocity = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 4) + (i * 6));
|
||||
keyFrames.push_back(kf);
|
||||
}
|
||||
|
||||
presetValues.reserve(presetValuesSize);
|
||||
for (uint32_t i = 0; i < presetValuesSize; i++)
|
||||
{
|
||||
presetValues.push_back(
|
||||
BitConverter::ToInt16BE(rawData, GETSEGOFFSET(presentValuesAddr) + (i * 2)));
|
||||
}
|
||||
|
||||
unk_10 = BitConverter::ToInt16BE(rawData, GETSEGOFFSET(rawDataIndex) + 0x10);
|
||||
duration = BitConverter::ToInt16BE(rawData, GETSEGOFFSET(rawDataIndex) + 0x12);
|
||||
}
|
||||
|
||||
std::string ZKeyFrameAnim::GetBodySourceCode() const
|
||||
{
|
||||
std::string declaration;
|
||||
|
||||
std::string bitFlagsStr;
|
||||
std::string keyFrameStr;
|
||||
std::string kfNumsStr;
|
||||
std::string presetValuesStr;
|
||||
|
||||
Globals::Instance->GetSegmentedPtrName(bitFlagsAddr, parent, "", bitFlagsStr, parent->workerID);
|
||||
Globals::Instance->GetSegmentedPtrName(keyFramesAddr, parent, "", keyFrameStr, parent->workerID);
|
||||
Globals::Instance->GetSegmentedPtrName(kfNumsAddr, parent, "", kfNumsStr, parent->workerID);
|
||||
Globals::Instance->GetSegmentedPtrName(presentValuesAddr, parent, "", presetValuesStr,
|
||||
parent->workerID);
|
||||
|
||||
return StringHelper::Sprintf("\n\t%s, %s, %s, %s, 0x%04X, 0x%04X\n", bitFlagsStr.c_str(),
|
||||
keyFrameStr.c_str(), kfNumsStr.c_str(), presetValuesStr.c_str(),
|
||||
unk_10, duration);
|
||||
}
|
||||
|
||||
std::string ZKeyFrameAnim::GetSourceTypeName() const
|
||||
{
|
||||
return "KeyFrameAnimation";
|
||||
}
|
||||
|
||||
ZResourceType ZKeyFrameAnim::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::KeyFrameAnimation;
|
||||
}
|
||||
|
||||
size_t ZKeyFrameAnim::GetRawDataSize() const
|
||||
{
|
||||
return 0x14;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
uint32_t ZKeyFrameAnim::GetSetBits(T data) const
|
||||
{
|
||||
uint32_t num = 0;
|
||||
|
||||
for (size_t i = 0; i < sizeof(T) * 8; i++)
|
||||
{
|
||||
if ((data >> i) & 1)
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
52
ZAPDTR/ZAPD/ZCkeyFrameAnim.h
Normal file
52
ZAPDTR/ZAPD/ZCkeyFrameAnim.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include "ZFile.h"
|
||||
|
||||
class ZKeyFrameSkel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t frame;
|
||||
int16_t value;
|
||||
int16_t velocity;
|
||||
} KeyFrame;
|
||||
|
||||
class ZKeyFrameAnim : public ZResource
|
||||
{
|
||||
public:
|
||||
ZKeyFrameSkel* skel;
|
||||
std::vector<uint8_t> bitFlags; // Standard only
|
||||
std::vector<uint16_t> bitFlagsFlex; // Flex only
|
||||
|
||||
std::vector<KeyFrame> keyFrames;
|
||||
std::vector<int16_t> kfNums;
|
||||
std::vector<int16_t> presetValues;
|
||||
|
||||
uint16_t unk_10;
|
||||
int16_t duration;
|
||||
|
||||
ZKeyFrameAnim(ZFile* nParent);
|
||||
~ZKeyFrameAnim();
|
||||
void ParseXML(tinyxml2::XMLElement* reader) override;
|
||||
void DeclareReferencesLate(const std::string& prefix) override;
|
||||
void ParseRawDataLate() override;
|
||||
std::string GetBodySourceCode() const override;
|
||||
|
||||
std::string GetSourceTypeName() const override;
|
||||
ZResourceType GetResourceType() const override;
|
||||
|
||||
size_t GetRawDataSize() const override;
|
||||
|
||||
private:
|
||||
offset_t skelOffset;
|
||||
segptr_t bitFlagsAddr;
|
||||
segptr_t keyFramesAddr;
|
||||
segptr_t kfNumsAddr;
|
||||
segptr_t presentValuesAddr;
|
||||
template <typename T>
|
||||
uint32_t GetSetBits(T data) const;
|
||||
};
|
||||
400
ZAPDTR/ZAPD/ZCollision.cpp
Normal file
400
ZAPDTR/ZAPD/ZCollision.cpp
Normal file
@@ -0,0 +1,400 @@
|
||||
#include "ZCollision.h"
|
||||
|
||||
#include <cassert>
|
||||
#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);
|
||||
|
||||
offset_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++)
|
||||
{
|
||||
ZCollisionPoly poly(parent);
|
||||
poly.SetRawDataIndex(polySegmentOffset + (i * 16));
|
||||
poly.ParseRawData();
|
||||
polygons.push_back(poly);
|
||||
}
|
||||
|
||||
uint16_t highestPolyType = 0;
|
||||
|
||||
for (const ZCollisionPoly& poly : polygons)
|
||||
{
|
||||
if (poly.type > highestPolyType)
|
||||
highestPolyType = poly.type;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < highestPolyType + 1; i++)
|
||||
{
|
||||
ZSurfaceType surfaceType(parent);
|
||||
surfaceType.SetRawDataIndex(polyTypeDefSegmentOffset + (i * 8));
|
||||
surfaceType.ParseRawData();
|
||||
PolygonTypes.push_back(surfaceType);
|
||||
}
|
||||
// polygonTypes.push_back(
|
||||
// BitConverter::ToUInt64BE(rawData, polyTypeDefSegmentOffset + (i * 8)));
|
||||
|
||||
if (camDataAddress != SEGMENTED_NULL)
|
||||
{
|
||||
// Try to guess how many elements the CamDataList array has.
|
||||
// The "guessing algorithm" is basically a "best effort" one and it
|
||||
// is error-prone.
|
||||
// This is based mostly on observation of how CollisionHeader data is
|
||||
// usually ordered. If for some reason the data was in some other funny
|
||||
// order, this would probably break.
|
||||
// The most common ordering is:
|
||||
// - *CamData*
|
||||
// - SurfaceType
|
||||
// - CollisionPoly
|
||||
// - Vertices
|
||||
// - WaterBoxes
|
||||
// - CollisionHeader
|
||||
offset_t upperCameraBoundary = polyTypeDefSegmentOffset;
|
||||
if (upperCameraBoundary == 0)
|
||||
{
|
||||
upperCameraBoundary = polySegmentOffset;
|
||||
}
|
||||
if (upperCameraBoundary == 0)
|
||||
{
|
||||
upperCameraBoundary = vtxSegmentOffset;
|
||||
}
|
||||
if (upperCameraBoundary == 0)
|
||||
{
|
||||
upperCameraBoundary = waterBoxSegmentOffset;
|
||||
}
|
||||
if (upperCameraBoundary == 0)
|
||||
{
|
||||
upperCameraBoundary = rawDataIndex;
|
||||
}
|
||||
|
||||
camData =
|
||||
new CameraDataList(parent, name, rawData, camDataSegmentOffset, upperCameraBoundary);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!Globals::Instance->otrMode)
|
||||
{
|
||||
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("%sWaterBoxes", auxName.c_str()), waterBoxes.size(), declaration);
|
||||
}
|
||||
|
||||
if (polygons.size() > 0)
|
||||
{
|
||||
declaration.clear();
|
||||
|
||||
if (!Globals::Instance->otrMode)
|
||||
{
|
||||
for (size_t i = 0; i < polygons.size(); i++)
|
||||
{
|
||||
declaration +=
|
||||
StringHelper::Sprintf("\t%s,", polygons[i].GetBodySourceCode().c_str());
|
||||
if (i + 1 < polygons.size())
|
||||
declaration += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
parent->AddDeclarationArray(polySegmentOffset, DeclarationAlignment::Align4,
|
||||
polygons.size() * 16, polygons[0].GetSourceTypeName().c_str(),
|
||||
StringHelper::Sprintf("%sPolygons", auxName.c_str()),
|
||||
polygons.size(), declaration);
|
||||
}
|
||||
|
||||
declaration.clear();
|
||||
for (const auto& polyType : PolygonTypes)
|
||||
{
|
||||
declaration += StringHelper::Sprintf("\t%s,", polyType.GetBodySourceCode().c_str());
|
||||
}
|
||||
|
||||
if (polyTypeDefAddress != SEGMENTED_NULL)
|
||||
parent->AddDeclarationArray(polyTypeDefSegmentOffset, DeclarationAlignment::Align4,
|
||||
PolygonTypes.size() * 8,
|
||||
PolygonTypes[0].GetSourceTypeName().c_str(),
|
||||
StringHelper::Sprintf("%sSurfaceType", auxName.c_str()),
|
||||
PolygonTypes.size(), declaration);
|
||||
|
||||
declaration.clear();
|
||||
|
||||
if (vertices.size() > 0)
|
||||
{
|
||||
declaration.clear();
|
||||
|
||||
if (!Globals::Instance->otrMode)
|
||||
{
|
||||
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("%sVertices", auxName.c_str()), vertices.size(), declaration);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ZCollisionHeader::GetBodySourceCode() const
|
||||
{
|
||||
std::string declaration = "";
|
||||
|
||||
if (Globals::Instance->otrMode)
|
||||
return 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, parent->workerID);
|
||||
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str());
|
||||
|
||||
std::string polyName;
|
||||
Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName,
|
||||
parent->workerID);
|
||||
declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str());
|
||||
|
||||
std::string surfaceName;
|
||||
Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName,
|
||||
parent->workerID);
|
||||
declaration += StringHelper::Sprintf("\t%s,\n", surfaceName.c_str());
|
||||
|
||||
std::string camName;
|
||||
Globals::Instance->GetSegmentedPtrName(camDataAddress, parent, "CamData", camName,
|
||||
parent->workerID);
|
||||
declaration += StringHelper::Sprintf("\t%s,\n", camName.c_str());
|
||||
|
||||
std::string waterBoxName;
|
||||
Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName,
|
||||
parent->workerID);
|
||||
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;
|
||||
}
|
||||
|
||||
WaterBoxHeader::WaterBoxHeader(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
|
||||
{
|
||||
xMin = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
|
||||
ySurface = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
|
||||
zMin = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
|
||||
xLength = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
|
||||
zLength = BitConverter::ToInt16BE(rawData, rawDataIndex + 8);
|
||||
|
||||
if (Globals::Instance->game == ZGame::OOT_SW97)
|
||||
properties = BitConverter::ToInt16BE(rawData, rawDataIndex + 10);
|
||||
else
|
||||
properties = BitConverter::ToInt32BE(rawData, 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, offset_t rawDataIndex,
|
||||
offset_t upperCameraBoundary)
|
||||
{
|
||||
std::string declaration;
|
||||
|
||||
// Parse CameraDataEntries
|
||||
size_t numElements = (upperCameraBoundary - rawDataIndex) / 8;
|
||||
assert(numElements < 10000);
|
||||
|
||||
offset_t cameraPosDataSeg = rawDataIndex;
|
||||
for (size_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, "&%sCamPosData[%i]", prefix.c_str(), 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("%sCamDataList", 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("%sCamPosData", prefix.c_str()),
|
||||
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);
|
||||
}
|
||||
90
ZAPDTR/ZAPD/ZCollision.h
Normal file
90
ZAPDTR/ZAPD/ZCollision.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZCollisionPoly.h"
|
||||
#include "ZFile.h"
|
||||
#include "ZResource.h"
|
||||
#include "ZRoom/ZRoom.h"
|
||||
#include "ZSurfaceType.h"
|
||||
#include "ZVector.h"
|
||||
|
||||
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,
|
||||
offset_t rawDataIndex, offset_t upperCameraBoundary);
|
||||
~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<ZCollisionPoly> polygons;
|
||||
std::vector<ZSurfaceType> 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;
|
||||
};
|
||||
78
ZAPDTR/ZAPD/ZCollisionPoly.cpp
Normal file
78
ZAPDTR/ZAPD/ZCollisionPoly.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
#include "ZCollisionPoly.h"
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
|
||||
REGISTER_ZFILENODE(CollisionPoly, ZCollisionPoly);
|
||||
|
||||
ZCollisionPoly::ZCollisionPoly(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
}
|
||||
|
||||
ZCollisionPoly::~ZCollisionPoly()
|
||||
{
|
||||
}
|
||||
|
||||
void ZCollisionPoly::ParseRawData()
|
||||
{
|
||||
const auto& rawData = parent->GetRawData();
|
||||
type = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0);
|
||||
|
||||
vtxA = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
|
||||
vtxB = BitConverter::ToUInt16BE(rawData, rawDataIndex + 4);
|
||||
vtxC = BitConverter::ToUInt16BE(rawData, rawDataIndex + 6);
|
||||
|
||||
normX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 8);
|
||||
normY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 10);
|
||||
normZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 12);
|
||||
|
||||
dist = BitConverter::ToUInt16BE(rawData, rawDataIndex + 14);
|
||||
}
|
||||
|
||||
void ZCollisionPoly::DeclareReferences(const std::string& prefix)
|
||||
{
|
||||
std::string declaration;
|
||||
std::string auxName = name;
|
||||
|
||||
if (name == "")
|
||||
auxName = GetDefaultName(prefix);
|
||||
|
||||
parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(),
|
||||
GetSourceTypeName(), name.c_str(), GetBodySourceCode());
|
||||
}
|
||||
|
||||
std::string ZCollisionPoly::GetBodySourceCode() const
|
||||
{
|
||||
std::string declaration;
|
||||
|
||||
declaration +=
|
||||
StringHelper::Sprintf("{0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X}",
|
||||
type, vtxA, vtxB, vtxC, normX, normY, normZ, dist);
|
||||
return declaration;
|
||||
}
|
||||
|
||||
std::string ZCollisionPoly::GetDefaultName(const std::string& prefix) const
|
||||
{
|
||||
return StringHelper::Sprintf("%sCollisionPoly_%06X", prefix.c_str(), rawDataIndex);
|
||||
}
|
||||
|
||||
ZResourceType ZCollisionPoly::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::CollisionPoly;
|
||||
}
|
||||
|
||||
size_t ZCollisionPoly::GetRawDataSize() const
|
||||
{
|
||||
return 16;
|
||||
}
|
||||
|
||||
std::string ZCollisionPoly::GetSourceTypeName() const
|
||||
{
|
||||
return "CollisionPoly";
|
||||
}
|
||||
|
||||
bool ZCollisionPoly::DoesSupportArray() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
29
ZAPDTR/ZAPD/ZCollisionPoly.h
Normal file
29
ZAPDTR/ZAPD/ZCollisionPoly.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "ZFile.h"
|
||||
#include "ZResource.h"
|
||||
|
||||
class ZCollisionPoly : public ZResource
|
||||
{
|
||||
public:
|
||||
uint16_t type;
|
||||
uint16_t vtxA, vtxB, vtxC;
|
||||
uint16_t normX, normY, normZ;
|
||||
uint16_t dist;
|
||||
|
||||
ZCollisionPoly(ZFile* nParent);
|
||||
~ZCollisionPoly();
|
||||
|
||||
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;
|
||||
|
||||
bool DoesSupportArray() const override;
|
||||
|
||||
size_t GetRawDataSize() const override;
|
||||
};
|
||||
389
ZAPDTR/ZAPD/ZCutscene.cpp
Normal file
389
ZAPDTR/ZAPD/ZCutscene.cpp
Normal file
@@ -0,0 +1,389 @@
|
||||
#include "ZCutscene.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "Globals.h"
|
||||
#include "OtherStructs/CutsceneMM_Commands.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "WarningHandler.h"
|
||||
#include "ZResource.h"
|
||||
|
||||
REGISTER_ZFILENODE(Cutscene, ZCutscene);
|
||||
|
||||
ZCutscene::ZCutscene(ZFile* nParent) : ZResource(nParent)
|
||||
{
|
||||
genOTRDef = true;
|
||||
}
|
||||
|
||||
ZCutscene::~ZCutscene()
|
||||
{
|
||||
for (CutsceneCommand* cmd : commands)
|
||||
delete cmd;
|
||||
}
|
||||
|
||||
std::string ZCutscene::GetBodySourceCode() const
|
||||
{
|
||||
std::string output = "";
|
||||
|
||||
output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame);
|
||||
|
||||
for (size_t i = 0; i < commands.size(); i++)
|
||||
{
|
||||
CutsceneCommand* cmd = commands[i];
|
||||
output += " " + cmd->GenerateSourceCode();
|
||||
}
|
||||
|
||||
output += StringHelper::Sprintf(" CS_END(),", commands.size(), endFrame);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
size_t ZCutscene::GetRawDataSize() const
|
||||
{
|
||||
size_t size = 0;
|
||||
|
||||
// Beginning
|
||||
size += 8;
|
||||
|
||||
for (size_t i = 0; i < commands.size(); i++)
|
||||
{
|
||||
CutsceneCommand* cmd = commands[i];
|
||||
|
||||
size += cmd->GetCommandSize();
|
||||
}
|
||||
|
||||
// End
|
||||
if (Globals::Instance->game == ZGame::MM_RETAIL)
|
||||
{
|
||||
size += 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
size += 8;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void ZCutscene::ParseRawData()
|
||||
{
|
||||
ZResource::ParseRawData();
|
||||
|
||||
const auto& rawData = parent->GetRawData();
|
||||
|
||||
numCommands = BitConverter::ToInt32BE(rawData, rawDataIndex + 0);
|
||||
commands = std::vector<CutsceneCommand*>();
|
||||
|
||||
endFrame = BitConverter::ToInt32BE(rawData, rawDataIndex + 4);
|
||||
offset_t currentPtr = rawDataIndex + 8;
|
||||
commands.reserve(numCommands);
|
||||
for (int32_t i = 0; i < numCommands; i++)
|
||||
{
|
||||
uint32_t id = BitConverter::ToUInt32BE(rawData, currentPtr);
|
||||
|
||||
if (id == 0xFFFFFFFF)
|
||||
break;
|
||||
|
||||
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
|
||||
{
|
||||
printf("Cutscene Command: 0x%X (%i)\n", id, id);
|
||||
}
|
||||
|
||||
currentPtr += 4;
|
||||
|
||||
CutsceneCommand* cmd = nullptr;
|
||||
|
||||
if (Globals::Instance->game == ZGame::MM_RETAIL)
|
||||
{
|
||||
cmd = GetCommandMM(id, currentPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
cmd = GetCommandOoT(id, currentPtr);
|
||||
}
|
||||
|
||||
if (cmd == nullptr)
|
||||
{
|
||||
HANDLE_WARNING_RESOURCE(
|
||||
WarningType::NotImplemented, parent, this, rawDataIndex,
|
||||
StringHelper::Sprintf("Cutscene command not implemented"),
|
||||
StringHelper::Sprintf("Command ID: 0x%X\nIndex: %d\ncurrentPtr-rawDataIndex: 0x%X",
|
||||
id, i, currentPtr - rawDataIndex));
|
||||
cmd = new CutsceneMMCommand_NonImplemented(rawData, currentPtr);
|
||||
}
|
||||
|
||||
assert(cmd != nullptr);
|
||||
|
||||
cmd->commandIndex = i;
|
||||
cmd->SetCommandID(id);
|
||||
size_t commmandSize = cmd->GetCommandSize();
|
||||
if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG)
|
||||
{
|
||||
printf("\t Command size: 0x%zX (%zu)\n", commmandSize, commmandSize);
|
||||
}
|
||||
currentPtr += commmandSize - 4;
|
||||
|
||||
commands.push_back(cmd);
|
||||
}
|
||||
}
|
||||
|
||||
CutsceneCommand* ZCutscene::GetCommandOoT(uint32_t id, offset_t currentPtr) const
|
||||
{
|
||||
CutsceneCommands cmdID = static_cast<CutsceneCommands>(id);
|
||||
|
||||
const auto& rawData = parent->GetRawData();
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case 10: // CutsceneCommands::SetPlayerAction
|
||||
case 15: // CutsceneCommands::SetActorAction1
|
||||
case 17:
|
||||
case 18:
|
||||
case 23:
|
||||
case 34:
|
||||
case 39:
|
||||
case 46:
|
||||
case 76:
|
||||
case 85:
|
||||
case 93:
|
||||
case 105:
|
||||
case 107:
|
||||
case 110:
|
||||
case 119:
|
||||
case 123:
|
||||
case 138:
|
||||
case 139:
|
||||
case 144:
|
||||
case 14: // CutsceneCommands::SetActorAction2
|
||||
case 16:
|
||||
case 24:
|
||||
case 35:
|
||||
case 40:
|
||||
case 48:
|
||||
case 64:
|
||||
case 68:
|
||||
case 70:
|
||||
case 78:
|
||||
case 80:
|
||||
case 94:
|
||||
case 116:
|
||||
case 118:
|
||||
case 120:
|
||||
case 125:
|
||||
case 131:
|
||||
case 141:
|
||||
case 25: // CutsceneCommands::SetActorAction3
|
||||
case 36:
|
||||
case 41:
|
||||
case 50:
|
||||
case 67:
|
||||
case 69:
|
||||
case 72:
|
||||
case 81:
|
||||
case 106:
|
||||
case 117:
|
||||
case 121:
|
||||
case 126:
|
||||
case 132:
|
||||
case 29: // CutsceneCommands::SetActorAction4
|
||||
case 37:
|
||||
case 42:
|
||||
case 51:
|
||||
case 53:
|
||||
case 63:
|
||||
case 65:
|
||||
case 66:
|
||||
case 75:
|
||||
case 82:
|
||||
case 108:
|
||||
case 127:
|
||||
case 133:
|
||||
case 30: // CutsceneCommands::SetActorAction5
|
||||
case 38:
|
||||
case 43:
|
||||
case 47:
|
||||
case 54:
|
||||
case 79:
|
||||
case 83:
|
||||
case 128:
|
||||
case 135:
|
||||
case 44: // CutsceneCommands::SetActorAction6
|
||||
case 55:
|
||||
case 77:
|
||||
case 84:
|
||||
case 90:
|
||||
case 129:
|
||||
case 136:
|
||||
case 31: // CutsceneCommands::SetActorAction7
|
||||
case 52:
|
||||
case 57:
|
||||
case 58:
|
||||
case 88:
|
||||
case 115:
|
||||
case 130:
|
||||
case 137:
|
||||
case 49: // CutsceneCommands::SetActorAction8
|
||||
case 60:
|
||||
case 89:
|
||||
case 111:
|
||||
case 114:
|
||||
case 134:
|
||||
case 142:
|
||||
case 62: // CutsceneCommands::SetActorAction9
|
||||
case 143: // CutsceneCommands::SetActorAction10
|
||||
return new CutsceneCommand_ActorAction(rawData, currentPtr);
|
||||
|
||||
case 0x0B:
|
||||
case 0x0D:
|
||||
case 0x1A:
|
||||
case 0x1B:
|
||||
case 0x1C:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x3B:
|
||||
case 0x3D:
|
||||
case 0x47:
|
||||
case 0x49:
|
||||
case 0x6D:
|
||||
case 0x15:
|
||||
case 0x16:
|
||||
case 0x70:
|
||||
case 0x71:
|
||||
case 0x4A:
|
||||
return new CutsceneCommand_GenericCmd(rawData, currentPtr, cmdID);
|
||||
}
|
||||
|
||||
switch (cmdID)
|
||||
{
|
||||
case CutsceneCommands::Misc:
|
||||
case CutsceneCommands::SetLighting:
|
||||
case CutsceneCommands::PlayBGM:
|
||||
case CutsceneCommands::StopBGM:
|
||||
case CutsceneCommands::FadeBGM:
|
||||
return new CutsceneCommand_GenericCmd(rawData, currentPtr, cmdID);
|
||||
|
||||
case CutsceneCommands::SetCameraPos:
|
||||
case CutsceneCommands::SetCameraFocus:
|
||||
case CutsceneCommands::SetCameraPosLink:
|
||||
case CutsceneCommands::SetCameraFocusLink:
|
||||
return new CutsceneCommandSetCameraPos(rawData, currentPtr);
|
||||
|
||||
case CutsceneCommands::Cmd07:
|
||||
break;
|
||||
case CutsceneCommands::Cmd08:
|
||||
break;
|
||||
case CutsceneCommands::Cmd09:
|
||||
return new CutsceneCommand_Rumble(rawData, currentPtr);
|
||||
case CutsceneCommands::Textbox:
|
||||
return new CutsceneCommand_TextBox(rawData, currentPtr);
|
||||
|
||||
case CutsceneCommands::SetPlayerAction:
|
||||
case CutsceneCommands::SetActorAction1:
|
||||
case CutsceneCommands::SetActorAction2:
|
||||
case CutsceneCommands::SetActorAction3:
|
||||
case CutsceneCommands::SetActorAction4:
|
||||
case CutsceneCommands::SetActorAction5:
|
||||
case CutsceneCommands::SetActorAction6:
|
||||
case CutsceneCommands::SetActorAction7:
|
||||
case CutsceneCommands::SetActorAction8:
|
||||
case CutsceneCommands::SetActorAction9:
|
||||
case CutsceneCommands::SetActorAction10:
|
||||
break;
|
||||
|
||||
case CutsceneCommands::SetSceneTransFX:
|
||||
return new CutsceneCommandSceneTransFX(rawData, currentPtr);
|
||||
|
||||
case CutsceneCommands::SetTime:
|
||||
return new CutsceneCommand_SetTime(rawData, currentPtr);
|
||||
case CutsceneCommands::Terminator:
|
||||
return new CutsceneCommand_Terminator(rawData, currentPtr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CutsceneCommand* ZCutscene::GetCommandMM(uint32_t id, offset_t currentPtr) const
|
||||
{
|
||||
CutsceneMMCommands cmdID = static_cast<CutsceneMMCommands>(id);
|
||||
|
||||
const auto& rawData = parent->GetRawData();
|
||||
|
||||
if (((id >= 100) && (id < 150)) || (id == 201) || ((id >= 450) && (id < 600)))
|
||||
{
|
||||
return new CutsceneCommand_ActorAction(rawData, currentPtr);
|
||||
}
|
||||
|
||||
switch (cmdID)
|
||||
{
|
||||
case CutsceneMMCommands::CS_CMD_MISC:
|
||||
case CutsceneMMCommands::CS_CMD_SET_LIGHTING:
|
||||
case CutsceneMMCommands::CS_CMD_SCENE_TRANS_FX:
|
||||
case CutsceneMMCommands::CS_CMD_MOTIONBLUR:
|
||||
case CutsceneMMCommands::CS_CMD_GIVETATL:
|
||||
case CutsceneMMCommands::CS_CMD_PLAYSEQ:
|
||||
case CutsceneMMCommands::CS_CMD_130:
|
||||
case CutsceneMMCommands::CS_CMD_131:
|
||||
case CutsceneMMCommands::CS_CMD_132:
|
||||
case CutsceneMMCommands::CS_CMD_STOPSEQ:
|
||||
case CutsceneMMCommands::CS_CMD_PLAYAMBIENCE:
|
||||
case CutsceneMMCommands::CS_CMD_FADEAMBIENCE:
|
||||
case CutsceneMMCommands::CS_CMD_TERMINATOR:
|
||||
case CutsceneMMCommands::CS_CMD_CHOOSE_CREDITS_SCENES:
|
||||
|
||||
case CutsceneMMCommands::CS_CMD_UNK_FA:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_FE:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_FF:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_100:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_101:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_102:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_103:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_104:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_105:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_108:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_109:
|
||||
case CutsceneMMCommands::CS_CMD_UNK_12D:
|
||||
return new CutsceneMMCommand_GenericCmd(rawData, currentPtr, cmdID);
|
||||
|
||||
case CutsceneMMCommands::CS_CMD_TEXTBOX:
|
||||
return new CutsceneCommand_TextBox(rawData, currentPtr);
|
||||
case CutsceneMMCommands::CS_CMD_CAMERA:
|
||||
return new CutsceneMMCommand_Camera(rawData, currentPtr);
|
||||
case CutsceneMMCommands::CS_CMD_FADESCREEN:
|
||||
return new CutsceneMMCommand_FadeScreen(rawData, currentPtr);
|
||||
case CutsceneMMCommands::CS_CMD_FADESEQ:
|
||||
return new CutsceneMMCommand_FadeSeq(rawData, currentPtr);
|
||||
case CutsceneMMCommands::CS_CMD_SETTIME:
|
||||
return new CutsceneCommand_SetTime(rawData, currentPtr);
|
||||
case CutsceneMMCommands::CS_CMD_SET_PLAYER_ACTION:
|
||||
return new CutsceneCommand_ActorAction(rawData, currentPtr);
|
||||
case CutsceneMMCommands::CS_CMD_RUMBLE:
|
||||
return new CutsceneCommand_Rumble(rawData, currentPtr);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Declaration* ZCutscene::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(), auxName, 0, bodyStr);
|
||||
decl->staticConf = staticConf;
|
||||
return decl;
|
||||
}
|
||||
|
||||
std::string ZCutscene::GetSourceTypeName() const
|
||||
{
|
||||
return "CutsceneData";
|
||||
}
|
||||
|
||||
ZResourceType ZCutscene::GetResourceType() const
|
||||
{
|
||||
return ZResourceType::Cutscene;
|
||||
}
|
||||
36
ZAPDTR/ZAPD/ZCutscene.h
Normal file
36
ZAPDTR/ZAPD/ZCutscene.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "tinyxml2.h"
|
||||
|
||||
#include "OtherStructs/Cutscene_Commands.h"
|
||||
#include "ZFile.h"
|
||||
#include "ZResource.h"
|
||||
|
||||
class ZCutscene : public ZResource
|
||||
{
|
||||
public:
|
||||
ZCutscene(ZFile* nParent);
|
||||
~ZCutscene();
|
||||
|
||||
void ParseRawData() 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;
|
||||
|
||||
int32_t numCommands;
|
||||
int32_t endFrame;
|
||||
std::vector<CutsceneCommand*> commands;
|
||||
|
||||
protected:
|
||||
CutsceneCommand* GetCommandOoT(uint32_t id, offset_t currentPtr) const;
|
||||
CutsceneCommand* GetCommandMM(uint32_t id, offset_t currentPtr) const;
|
||||
};
|
||||
2254
ZAPDTR/ZAPD/ZDisplayList.cpp
Normal file
2254
ZAPDTR/ZAPD/ZDisplayList.cpp
Normal file
File diff suppressed because it is too large
Load Diff
262
ZAPDTR/ZAPD/ZDisplayList.h
Normal file
262
ZAPDTR/ZAPD/ZDisplayList.h
Normal file
@@ -0,0 +1,262 @@
|
||||
#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,
|
||||
};
|
||||
|
||||
|
||||
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;
|
||||
};
|
||||
1429
ZAPDTR/ZAPD/ZFile.cpp
Normal file
1429
ZAPDTR/ZAPD/ZFile.cpp
Normal file
File diff suppressed because it is too large
Load Diff
141
ZAPDTR/ZAPD/ZFile.h
Normal file
141
ZAPDTR/ZAPD/ZFile.h
Normal file
@@ -0,0 +1,141 @@
|
||||
#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,
|
||||
ExtractDirectory,
|
||||
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::vector<ZResource*> resources;
|
||||
std::string defines;
|
||||
|
||||
int workerID;
|
||||
bool isCompilable = false;
|
||||
|
||||
// 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, int nWorkerID);
|
||||
~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(offset_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(offset_t address) const;
|
||||
Declaration* GetDeclarationRanged(offset_t address) const;
|
||||
bool HasDeclaration(offset_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::string name;
|
||||
fs::path outName = "";
|
||||
fs::path basePath;
|
||||
fs::path outputPath;
|
||||
fs::path xmlFilePath;
|
||||
std::vector<uint8_t> rawData;
|
||||
|
||||
// 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);
|
||||
};
|
||||
420
ZAPDTR/ZAPD/ZLimb.cpp
Normal file
420
ZAPDTR/ZAPD/ZLimb.cpp
Normal file
@@ -0,0 +1,420 @@
|
||||
#include "ZLimb.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "Globals.h"
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "WarningHandler.h"
|
||||
#include "ZSkeleton.h"
|
||||
|
||||
REGISTER_ZFILENODE(Limb, ZLimb);
|
||||
|
||||
ZLimb::ZLimb(ZFile* nParent) : ZResource(nParent), segmentStruct(nParent)
|
||||
{
|
||||
RegisterOptionalAttribute("EnumName");
|
||||
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);
|
||||
|
||||
auto& enumNameXml = registeredAttributes.at("EnumName").value;
|
||||
if (enumNameXml != "")
|
||||
{
|
||||
enumName = enumNameXml;
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
if (Globals::Instance->otrMode)
|
||||
return "";
|
||||
|
||||
std::string dListStr;
|
||||
std::string dListStr2;
|
||||
Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr,
|
||||
parent->workerID);
|
||||
Globals::Instance->GetSegmentedArrayIndexedName(dList2Ptr, 8, parent, "Gfx", dListStr2,
|
||||
parent->workerID);
|
||||
|
||||
std::string entryStr = "\n\t";
|
||||
if (type == ZLimbType::Legacy)
|
||||
{
|
||||
std::string childName;
|
||||
std::string siblingName;
|
||||
Globals::Instance->GetSegmentedPtrName(childPtr, parent, "LegacyLimb", childName,
|
||||
parent->workerID);
|
||||
Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "LegacyLimb", siblingName,
|
||||
parent->workerID);
|
||||
|
||||
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
|
||||
{
|
||||
std::string childStr;
|
||||
std::string siblingStr;
|
||||
if (limbsTable != nullptr)
|
||||
{
|
||||
childStr = limbsTable->GetLimbEnumName(childIndex);
|
||||
siblingStr = limbsTable->GetLimbEnumName(siblingIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
childStr = StringHelper::Sprintf("0x%02X", childIndex);
|
||||
siblingStr = StringHelper::Sprintf("0x%02X", siblingIndex);
|
||||
}
|
||||
|
||||
if (type != ZLimbType::Curve)
|
||||
{
|
||||
entryStr += StringHelper::Sprintf("{ %i, %i, %i }, ", transX, transY, transZ);
|
||||
}
|
||||
entryStr += StringHelper::Sprintf("%s, %s,\n", childStr.c_str(), siblingStr.c_str());
|
||||
|
||||
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,
|
||||
parent->workerID);
|
||||
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::SetLimbIndex(uint8_t nLimbIndex)
|
||||
{
|
||||
limbIndex = nLimbIndex;
|
||||
}
|
||||
|
||||
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, parent->workerID);
|
||||
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);
|
||||
}
|
||||
74
ZAPDTR/ZAPD/ZLimb.h
Normal file
74
ZAPDTR/ZAPD/ZLimb.h
Normal file
@@ -0,0 +1,74 @@
|
||||
#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 ZLimbTable;
|
||||
|
||||
class ZLimb : public ZResource
|
||||
{
|
||||
public:
|
||||
std::string enumName;
|
||||
ZLimbTable* limbsTable = nullptr; // borrowed pointer, do not delete!
|
||||
|
||||
ZLimbType type = ZLimbType::Standard;
|
||||
|
||||
ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only
|
||||
segptr_t skinSegment = 0; // Skin only
|
||||
Struct_800A5E28 segmentStruct = {0}; // Skin only
|
||||
|
||||
// Legacy only
|
||||
float legTransX = 0, legTransY = 0, legTransZ = 0; // Vec3f
|
||||
uint16_t rotX = 0, rotY = 0, rotZ = 0; // Vec3s
|
||||
segptr_t childPtr = 0; // LegacyLimb*
|
||||
segptr_t siblingPtr = 0; // LegacyLimb*
|
||||
|
||||
segptr_t dListPtr = 0;
|
||||
segptr_t dList2Ptr = 0; // LOD and Curve Only
|
||||
|
||||
int16_t transX = 0, transY = 0, transZ = 0;
|
||||
uint8_t childIndex = 0, siblingIndex = 0;
|
||||
|
||||
uint8_t limbIndex = 0;
|
||||
|
||||
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);
|
||||
|
||||
void SetLimbIndex(uint8_t nLimbIndex);
|
||||
|
||||
protected:
|
||||
void DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix,
|
||||
const std::string& limbSuffix);
|
||||
};
|
||||
58
ZAPDTR/ZAPD/ZMtx.cpp
Normal file
58
ZAPDTR/ZAPD/ZMtx.cpp
Normal 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
24
ZAPDTR/ZAPD/ZMtx.h
Normal 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;
|
||||
};
|
||||
212
ZAPDTR/ZAPD/ZPath.cpp
Normal file
212
ZAPDTR/ZAPD/ZPath.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
#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;
|
||||
|
||||
pathways.reserve(numPaths);
|
||||
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);
|
||||
|
||||
points.reserve(numPoints);
|
||||
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, parent->workerID);
|
||||
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,
|
||||
parent->workerID);
|
||||
|
||||
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
51
ZAPDTR/ZAPD/ZPath.h
Normal 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;
|
||||
};
|
||||
101
ZAPDTR/ZAPD/ZPlayerAnimationData.cpp
Normal file
101
ZAPDTR/ZAPD/ZPlayerAnimationData.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "ZPlayerAnimationData.h"
|
||||
|
||||
#include "Utils/BitConverter.h"
|
||||
#include "Utils/StringHelper.h"
|
||||
#include "ZFile.h"
|
||||
#include <Globals.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 = "";
|
||||
|
||||
if (Globals::Instance->otrMode)
|
||||
return "";
|
||||
|
||||
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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user