From b2747aa8b4186034d6621e8e3eccc44d14ec27a7 Mon Sep 17 00:00:00 2001 From: Anghelo Carvajal Date: Sun, 24 Oct 2021 13:04:36 -0300 Subject: [PATCH] Subrepos updates (#360) * git subrepo pull tools/asm-differ --force subrepo: subdir: "tools/asm-differ" merged: "d218cdf0" upstream: origin: "https://github.com/simonlindholm/asm-differ.git" branch: "main" commit: "d218cdf0" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/graphovl --force subrepo: subdir: "tools/graphovl" merged: "f5fe93d7" upstream: origin: "https://github.com/AngheloAlf/graphovl.git" branch: "master" commit: "f5fe93d7" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/ZAPD --force subrepo: subdir: "tools/ZAPD" merged: "e7a8a48c" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "e7a8a48c" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/graphovl --force subrepo: subdir: "tools/graphovl" merged: "d14ea084" upstream: origin: "https://github.com/AngheloAlf/graphovl.git" branch: "master" commit: "d14ea084" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/ZAPD --force subrepo: subdir: "tools/ZAPD" merged: "e243634e" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "e243634e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/decomp-permuter --force subrepo: subdir: "tools/decomp-permuter" merged: "d1294dfa0" upstream: origin: "https://github.com/simonlindholm/decomp-permuter.git" branch: "main" commit: "d1294dfa0" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/graphovl --force subrepo: subdir: "tools/graphovl" merged: "f5fe93d75" upstream: origin: "https://github.com/AngheloAlf/graphovl.git" branch: "master" commit: "f5fe93d75" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull tools/ZAPD --force subrepo: subdir: "tools/ZAPD" merged: "d0cd6b397" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "d0cd6b397" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * add ExternalXMLFolder config * git subrepo pull --force tools/decomp-permuter subrepo: subdir: "tools/decomp-permuter" merged: "a20bac942" upstream: origin: "https://github.com/simonlindholm/decomp-permuter.git" branch: "main" commit: "a20bac942" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "4f7b8393e" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "4f7b8393e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * git subrepo pull --force tools/asm-differ subrepo: subdir: "tools/asm-differ" merged: "f30d43ace" upstream: origin: "https://github.com/simonlindholm/asm-differ.git" branch: "main" commit: "f30d43ace" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596" * Remove Segment="128" --- assets/xml/overlays/ovl_Arrow_Ice.xml | 4 +- assets/xml/overlays/ovl_En_Clear_Tag.xml | 2 +- assets/xml/overlays/ovl_En_Holl.xml | 2 +- format.sh | 1 + tools/ZAPD/.gitignore | 1 + tools/ZAPD/.gitrepo | 4 +- tools/ZAPD/ExporterTest/CollisionExporter.cpp | 10 +- tools/ZAPD/ExporterTest/CollisionExporter.h | 2 +- tools/ZAPD/ExporterTest/Main.cpp | 18 +- tools/ZAPD/ExporterTest/RoomExporter.cpp | 249 ++-- tools/ZAPD/ExporterTest/TextureExporter.cpp | 8 +- tools/ZAPD/ExporterTest/TextureExporter.h | 2 +- tools/ZAPD/Makefile | 20 +- tools/ZAPD/README.md | 6 +- tools/ZAPD/ZAPD/Declaration.cpp | 227 ++- tools/ZAPD/ZAPD/Declaration.h | 88 +- tools/ZAPD/ZAPD/GameConfig.cpp | 184 +++ tools/ZAPD/ZAPD/GameConfig.h | 58 + tools/ZAPD/ZAPD/Globals.cpp | 308 ++--- tools/ZAPD/ZAPD/Globals.h | 56 +- tools/ZAPD/ZAPD/ImageBackend.cpp | 13 +- tools/ZAPD/ZAPD/Main.cpp | 171 ++- .../ZAPD/OtherStructs/SkinLimbStructs.cpp | 341 +++++ .../ZAPD/ZAPD/OtherStructs/SkinLimbStructs.h | 113 ++ tools/ZAPD/ZAPD/OutputFormatter.cpp | 6 +- tools/ZAPD/ZAPD/OutputFormatter.h | 4 +- tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp | 6 +- tools/ZAPD/ZAPD/Overlays/ZOverlay.h | 4 +- tools/ZAPD/ZAPD/ZAnimation.cpp | 302 ++-- tools/ZAPD/ZAPD/ZAnimation.h | 31 +- tools/ZAPD/ZAPD/ZArray.cpp | 72 +- tools/ZAPD/ZAPD/ZArray.h | 8 +- tools/ZAPD/ZAPD/ZBackground.cpp | 67 +- tools/ZAPD/ZAPD/ZBackground.h | 25 +- tools/ZAPD/ZAPD/ZBlob.cpp | 47 +- tools/ZAPD/ZAPD/ZBlob.h | 7 +- tools/ZAPD/ZAPD/ZCollision.cpp | 163 ++- tools/ZAPD/ZAPD/ZCollision.h | 27 +- tools/ZAPD/ZAPD/ZCutscene.cpp | 84 +- tools/ZAPD/ZAPD/ZCutscene.h | 14 +- tools/ZAPD/ZAPD/ZCutsceneMM.cpp | 37 +- tools/ZAPD/ZAPD/ZCutsceneMM.h | 8 +- tools/ZAPD/ZAPD/ZDisplayList.cpp | 502 +++---- tools/ZAPD/ZAPD/ZDisplayList.h | 41 +- tools/ZAPD/ZAPD/ZFile.cpp | 1225 +++++++++-------- tools/ZAPD/ZAPD/ZFile.h | 98 +- tools/ZAPD/ZAPD/ZLimb.cpp | 641 ++------- tools/ZAPD/ZAPD/ZLimb.h | 129 +- tools/ZAPD/ZAPD/ZMtx.cpp | 49 +- tools/ZAPD/ZAPD/ZMtx.h | 11 +- tools/ZAPD/ZAPD/ZPath.cpp | 72 +- tools/ZAPD/ZAPD/ZPath.h | 4 +- tools/ZAPD/ZAPD/ZPlayerAnimationData.cpp | 97 ++ tools/ZAPD/ZAPD/ZPlayerAnimationData.h | 28 + tools/ZAPD/ZAPD/ZResource.cpp | 107 +- tools/ZAPD/ZAPD/ZResource.h | 121 +- .../ZRoom/Commands/SetActorCutsceneList.cpp | 9 +- .../ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp | 13 +- .../ZRoom/Commands/SetAlternateHeaders.cpp | 28 +- .../Commands/SetAnimatedMaterialList.cpp | 6 +- .../ZRoom/Commands/SetAnimatedMaterialList.h | 1 - .../ZRoom/Commands/SetCollisionHeader.cpp | 13 +- .../ZAPD/ZRoom/Commands/SetCollisionHeader.h | 2 +- .../ZAPD/ZAPD/ZRoom/Commands/SetCsCamera.cpp | 28 +- .../ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp | 14 +- .../ZAPD/ZRoom/Commands/SetEntranceList.cpp | 26 +- .../ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp | 20 +- .../ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp | 11 +- .../ZRoom/Commands/SetLightingSettings.cpp | 12 +- tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp | 339 ++--- tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h | 99 +- .../ZAPD/ZRoom/Commands/SetMinimapChests.cpp | 7 +- .../ZAPD/ZRoom/Commands/SetMinimapList.cpp | 8 +- .../ZAPD/ZRoom/Commands/SetObjectList.cpp | 10 +- .../ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp | 16 +- tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h | 2 - .../ZAPD/ZRoom/Commands/SetRoomBehavior.cpp | 1 + .../ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp | 18 +- tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h | 3 +- .../ZRoom/Commands/SetStartPositionList.cpp | 9 +- .../ZRoom/Commands/SetTransitionActorList.cpp | 11 +- tools/ZAPD/ZAPD/ZRoom/ZNames.h | 2 +- tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp | 47 +- tools/ZAPD/ZAPD/ZRoom/ZRoom.h | 15 +- tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp | 10 +- tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h | 2 +- tools/ZAPD/ZAPD/ZScalar.cpp | 34 +- tools/ZAPD/ZAPD/ZScalar.h | 12 +- tools/ZAPD/ZAPD/ZSkeleton.cpp | 128 +- tools/ZAPD/ZAPD/ZSkeleton.h | 17 +- tools/ZAPD/ZAPD/ZString.cpp | 22 +- tools/ZAPD/ZAPD/ZString.h | 3 +- tools/ZAPD/ZAPD/ZSymbol.cpp | 23 +- tools/ZAPD/ZAPD/ZSymbol.h | 4 +- tools/ZAPD/ZAPD/ZTexture.cpp | 73 +- tools/ZAPD/ZAPD/ZTexture.h | 11 +- tools/ZAPD/ZAPD/ZTextureAnimation.cpp | 129 +- tools/ZAPD/ZAPD/ZTextureAnimation.h | 16 +- tools/ZAPD/ZAPD/ZVector.cpp | 56 +- tools/ZAPD/ZAPD/ZVector.h | 16 +- tools/ZAPD/ZAPD/ZVtx.cpp | 28 +- tools/ZAPD/ZAPD/ZVtx.h | 8 +- tools/ZAPD/ZAPDUtils/Color3b.h | 14 +- tools/ZAPD/ZAPDUtils/StrHash.h | 6 +- tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp | 9 +- tools/ZAPD/ZAPDUtils/Utils/BinaryReader.h | 16 +- tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.cpp | 2 +- tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.h | 2 +- tools/ZAPD/ZAPDUtils/Utils/Directory.h | 2 +- tools/ZAPD/ZAPDUtils/Utils/Path.h | 23 +- tools/ZAPD/ZAPDUtils/Utils/StringHelper.h | 2 +- tools/ZAPD/ZAPDUtils/Vec2f.h | 12 +- tools/ZAPD/ZAPDUtils/Vec3f.h | 14 +- tools/ZAPD/copycheck.py | 2 + .../docs/zapd_extraction_xml_reference.md | 59 +- tools/ZAPD/docs/zapd_xml_spec.md | 55 + tools/ZAPDConfigs/MM/Config.xml | 8 + tools/asm-differ/.gitrepo | 4 +- tools/asm-differ/__init__.py | 0 tools/asm-differ/diff.py | 23 +- tools/decomp-permuter/.gitrepo | 2 +- tools/graphovl/.gitrepo | 4 +- tools/graphovl/graphovl.py | 70 +- tools/graphovl/graphovl_styles/classic.ini | 1 + tools/graphovl/graphovl_styles/soft.ini | 1 + .../graphovl_styles/solarized_dark.ini | 1 + .../graphovl_styles/solarized_light.ini | 1 + 127 files changed, 4132 insertions(+), 3488 deletions(-) create mode 100644 tools/ZAPD/ZAPD/GameConfig.cpp create mode 100644 tools/ZAPD/ZAPD/GameConfig.h create mode 100644 tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp create mode 100644 tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.h create mode 100644 tools/ZAPD/ZAPD/ZPlayerAnimationData.cpp create mode 100644 tools/ZAPD/ZAPD/ZPlayerAnimationData.h create mode 100644 tools/ZAPD/docs/zapd_xml_spec.md delete mode 100644 tools/asm-differ/__init__.py diff --git a/assets/xml/overlays/ovl_Arrow_Ice.xml b/assets/xml/overlays/ovl_Arrow_Ice.xml index e130bdd055..96c0f25220 100644 --- a/assets/xml/overlays/ovl_Arrow_Ice.xml +++ b/assets/xml/overlays/ovl_Arrow_Ice.xml @@ -1,5 +1,5 @@ - + @@ -8,4 +8,4 @@ - \ No newline at end of file + diff --git a/assets/xml/overlays/ovl_En_Clear_Tag.xml b/assets/xml/overlays/ovl_En_Clear_Tag.xml index 82a1e2fe8a..0cbfcf80ae 100644 --- a/assets/xml/overlays/ovl_En_Clear_Tag.xml +++ b/assets/xml/overlays/ovl_En_Clear_Tag.xml @@ -1,5 +1,5 @@ - + diff --git a/assets/xml/overlays/ovl_En_Holl.xml b/assets/xml/overlays/ovl_En_Holl.xml index 5679e16059..2baa5737c5 100644 --- a/assets/xml/overlays/ovl_En_Holl.xml +++ b/assets/xml/overlays/ovl_En_Holl.xml @@ -1,5 +1,5 @@ - + diff --git a/format.sh b/format.sh index c705e9affe..ed830a5025 100755 --- a/format.sh +++ b/format.sh @@ -25,4 +25,5 @@ echo "Running clang-tidy..." clang-tidy ${TIDY_OPTS} src/**/*.c -- ${COMPILER_OPTS} &> /dev/null echo "Adding missing final new lines..." find src/ -type f -name "*.c" -exec sed -i -e '$a\' {} \; +find assets/xml/ -type f -name "*.xml" -exec sed -i -e '$a\' {} \; echo "Done formatting all files." diff --git a/tools/ZAPD/.gitignore b/tools/ZAPD/.gitignore index 00ec03b0f2..68c502e36a 100644 --- a/tools/ZAPD/.gitignore +++ b/tools/ZAPD/.gitignore @@ -338,3 +338,4 @@ ZAPDUtils/ZAPDUtils.a .vscode/ build/ ZAPDUtils/build/ +ZAPD/BuildInfo.h diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo index 7201aacd35..94da913d0d 100644 --- a/tools/ZAPD/.gitrepo +++ b/tools/ZAPD/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/zeldaret/ZAPD.git branch = master - commit = 623d779f8ea111cb8cbb78a218c8454e819c4c13 - parent = 9f2368dd710e740ced0f8086de91228b87f41512 + commit = 4f7b8393ec8a3abd59649c2ba669e951fb61f3d2 + parent = 346df1bbc8ca21673fe63d884b6734c23a4d9f4b method = merge cmdver = 0.4.3 diff --git a/tools/ZAPD/ExporterTest/CollisionExporter.cpp b/tools/ZAPD/ExporterTest/CollisionExporter.cpp index 81a9b5464f..e00f5c1b0b 100644 --- a/tools/ZAPD/ExporterTest/CollisionExporter.cpp +++ b/tools/ZAPD/ExporterTest/CollisionExporter.cpp @@ -1,6 +1,7 @@ #include "CollisionExporter.h" -void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]]fs::path outPath, BinaryWriter* writer) +void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]] fs::path outPath, + BinaryWriter* writer) { ZCollisionHeader* col = (ZCollisionHeader*)res; @@ -35,9 +36,10 @@ void ExporterExample_Collision::Save(ZResource* res, [[maybe_unused]]fs::path ou for (uint16_t i = 0; i < col->vertices.size(); i++) { - writer->Write(col->vertices[i].x); - writer->Write(col->vertices[i].y); - writer->Write(col->vertices[i].z); + 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); diff --git a/tools/ZAPD/ExporterTest/CollisionExporter.h b/tools/ZAPD/ExporterTest/CollisionExporter.h index 2828995d04..5f48e6557e 100644 --- a/tools/ZAPD/ExporterTest/CollisionExporter.h +++ b/tools/ZAPD/ExporterTest/CollisionExporter.h @@ -1,7 +1,7 @@ #pragma once -#include "ZResource.h" #include "ZCollision.h" +#include "ZResource.h" class ExporterExample_Collision : public ZResourceExporter { diff --git a/tools/ZAPD/ExporterTest/Main.cpp b/tools/ZAPD/ExporterTest/Main.cpp index 1fb6bea77a..4f683a1ba3 100644 --- a/tools/ZAPD/ExporterTest/Main.cpp +++ b/tools/ZAPD/ExporterTest/Main.cpp @@ -1,7 +1,7 @@ -#include -#include #include #include +#include +#include enum class ExporterFileMode { @@ -10,7 +10,7 @@ enum class ExporterFileMode ModeExample3 = (int)ZFileMode::Custom + 3, }; -static void ExporterParseFileMode(std::string buildMode, ZFileMode& fileMode) +static void ExporterParseFileMode(const std::string& buildMode, ZFileMode& fileMode) { if (buildMode == "me1") fileMode = (ZFileMode)ExporterFileMode::ModeExample1; @@ -20,17 +20,15 @@ static void ExporterParseFileMode(std::string buildMode, ZFileMode& fileMode) fileMode = (ZFileMode)ExporterFileMode::ModeExample3; } -static void ExporterParseArgs([[maybe_unused]]int argc, char* argv[], int& i) +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") { - } } @@ -61,7 +59,8 @@ static void ExporterFileEnd(ZFile* file) 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. + // 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; @@ -75,5 +74,6 @@ static void ImportExporters() 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) \ No newline at end of file +// When ZAPD starts up, it will automatically call the below function, which in turn sets up our +// exporters. +REGISTER_EXPORTER(ImportExporters); diff --git a/tools/ZAPD/ExporterTest/RoomExporter.cpp b/tools/ZAPD/ExporterTest/RoomExporter.cpp index dc8c82302c..c4a6844fb5 100644 --- a/tools/ZAPD/ExporterTest/RoomExporter.cpp +++ b/tools/ZAPD/ExporterTest/RoomExporter.cpp @@ -1,41 +1,41 @@ #include "RoomExporter.h" +#include #include -#include #include -#include -#include -#include -#include +#include #include +#include +#include +#include +#include +#include #include #include -#include #include -#include -#include +#include +#include +#include #include #include -#include -#include -#include -#include +#include +#include void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* writer) { - ZRoom* room = (ZRoom*)res; + ZRoom* room = dynamic_cast(res); - //MemoryStream* memStream = new MemoryStream(); - //BinaryWriter* writer = new BinaryWriter(memStream); + // MemoryStream* memStream = new MemoryStream(); + // BinaryWriter* writer = new BinaryWriter(memStream); - for (uint i = 0; i < room->commands.size() * 8; i++) + for (size_t i = 0; i < room->commands.size() * 8; i++) writer->Write((uint8_t)0); - for (uint i = 0; i < room->commands.size(); i++) + 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) @@ -44,115 +44,115 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* { SetWind* cmdSetWind = (SetWind*)cmd; - writer->Write((uint8_t)0); // 0x01 - writer->Write((uint8_t)0); // 0x02 - writer->Write((uint8_t)0); // 0x03 + 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 + writer->Write(cmdSetWind->windWest); // 0x04 + writer->Write(cmdSetWind->windVertical); // 0x05 + writer->Write(cmdSetWind->windSouth); // 0x06 + writer->Write(cmdSetWind->clothFlappingStrength); // 0x07 } - break; + 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((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 + 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((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 + 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 + 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((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 + 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 + 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 + 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((uint8_t)cmdCsCam->cameras.size()); // 0x01 + writer->Write((uint8_t)0); // 0x02 + writer->Write((uint8_t)0); // 0x03 - writer->Write(cmdCsCam->segmentOffset); // 0x04 + 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((uint8_t)cmdMesh->data); // 0x01 + writer->Write((uint8_t)0); // 0x02 + writer->Write((uint8_t)0); // 0x03 - writer->Write(baseStreamEnd); // 0x04 + writer->Write(baseStreamEnd); // 0x04 uint32_t oldOffset = writer->GetBaseAddress(); writer->Seek(baseStreamEnd, SeekOffsetType::Start); @@ -163,15 +163,13 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* if (cmdMesh->meshHeaderType == 0) { - //writer->Write(cmdMesh->) + // writer->Write(cmdMesh->) } else if (cmdMesh->meshHeaderType == 1) { - } else if (cmdMesh->meshHeaderType == 2) { - } writer->Seek(oldOffset, SeekOffsetType::Start); @@ -181,20 +179,20 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* { 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 + 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 + 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); @@ -236,17 +234,17 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* { SetRoomList* cmdRoom = (SetRoomList*)cmd; - writer->Write((uint8_t)cmdRoom->rooms.size()); // 0x01 - writer->Write((uint8_t)0); // 0x02 - writer->Write((uint8_t)0); // 0x03 + writer->Write((uint8_t)cmdRoom->romfile->rooms.size()); // 0x01 + writer->Write((uint8_t)0); // 0x02 + writer->Write((uint8_t)0); // 0x03 - int baseStreamEnd = writer->GetLength(); - writer->Write(baseStreamEnd); // 0x04 + auto baseStreamEnd = writer->GetLength(); + writer->Write(baseStreamEnd); // 0x04 uint32_t oldOffset = writer->GetBaseAddress(); writer->Seek(baseStreamEnd, SeekOffsetType::Start); - for (RoomEntry entry : cmdRoom->rooms) + for (const auto& entry : cmdRoom->romfile->rooms) { writer->Write(entry.virtualAddressStart); writer->Write(entry.virtualAddressEnd); @@ -261,10 +259,10 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* 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 + 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 @@ -284,10 +282,10 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* 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 + 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); @@ -305,12 +303,12 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* { 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 + 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: @@ -319,10 +317,10 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* 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 + 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); @@ -344,30 +342,31 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* 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 + 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 + writer->Write((uint8_t)0); // 0x01 + writer->Write((uint8_t)0); // 0x02 + writer->Write((uint8_t)0); // 0x03 + writer->Write((uint8_t)0); // 0x04 + writer->Write((uint8_t)0); // 0x05 + writer->Write((uint8_t)0); // 0x06 + writer->Write((uint8_t)0); // 0x07 break; } } - //writer->Close(); - //File::WriteAllBytes(StringHelper::Sprintf("%s", res->GetName().c_str()), memStream->ToVector()); + // writer->Close(); + // File::WriteAllBytes(StringHelper::Sprintf("%s", res->GetName().c_str()), + // memStream->ToVector()); } diff --git a/tools/ZAPD/ExporterTest/TextureExporter.cpp b/tools/ZAPD/ExporterTest/TextureExporter.cpp index 95d84b8f7b..6488bed3a2 100644 --- a/tools/ZAPD/ExporterTest/TextureExporter.cpp +++ b/tools/ZAPD/ExporterTest/TextureExporter.cpp @@ -1,12 +1,14 @@ #include "TextureExporter.h" #include "../ZAPD/ZFile.h" -void ExporterExample_Texture::Save(ZResource* res, [[maybe_unused]]fs::path outPath, BinaryWriter* writer) +void ExporterExample_Texture::Save(ZResource* res, [[maybe_unused]] fs::path outPath, + BinaryWriter* writer) { ZTexture* tex = (ZTexture*)res; auto data = tex->parent->GetRawData(); - for (uint i = tex->GetRawDataIndex(); i < tex->GetRawDataIndex() + tex->GetRawDataSize(); i++) + for (offset_t i = tex->GetRawDataIndex(); i < tex->GetRawDataIndex() + tex->GetRawDataSize(); + i++) writer->Write(data[i]); -} \ No newline at end of file +} diff --git a/tools/ZAPD/ExporterTest/TextureExporter.h b/tools/ZAPD/ExporterTest/TextureExporter.h index fcee8be5ad..ffe6001dca 100644 --- a/tools/ZAPD/ExporterTest/TextureExporter.h +++ b/tools/ZAPD/ExporterTest/TextureExporter.h @@ -1,8 +1,8 @@ #pragma once +#include #include "ZResource.h" #include "ZTexture.h" -#include class ExporterExample_Texture : public ZResourceExporter { diff --git a/tools/ZAPD/Makefile b/tools/ZAPD/Makefile index e8f6c92a38..737b85ecf7 100644 --- a/tools/ZAPD/Makefile +++ b/tools/ZAPD/Makefile @@ -5,17 +5,22 @@ ASAN ?= 0 DEPRECATION_ON ?= 1 DEBUG ?= 0 COPYCHECK_ARGS ?= -# Set LLD=1 to use ld.lld as the linker LLD ?= 0 -CXX := g++ +# Use clang++ if available, else use g++ +ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0) + CXX := clang++ +else + CXX := g++ +endif + INC := -I ZAPD -I lib/elfio -I lib/libgfxd -I lib/tinyxml2 -I ZAPDUtils CXXFLAGS := -fpic -std=c++17 -Wall -Wextra -fno-omit-frame-pointer OPTFLAGS := ifneq ($(DEBUG),0) OPTIMIZATION_ON = 0 - DEPRECATION_OFF = 1 + CXXFLAGS += -g3 -DDEVELOPMENT -D_DEBUG COPYCHECK_ARGS += --devel DEPRECATION_ON = 0 else @@ -29,7 +34,7 @@ else endif ifneq ($(ASAN),0) - CXXFLAGS += -fsanitize=address + CXXFLAGS += -fsanitize=address -fsanitize=pointer-compare -fsanitize=pointer-subtract -fsanitize=undefined endif ifneq ($(DEPRECATION_ON),0) CXXFLAGS += -DDEPRECATION_ON @@ -38,6 +43,11 @@ endif 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 @@ -105,4 +115,4 @@ ZAPDUtils: # Linking ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils - $(CXX) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive $(LDFLAGS) $(OUTPUT_OPTION) + $(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive $(LDFLAGS) $(OUTPUT_OPTION) diff --git a/tools/ZAPD/README.md b/tools/ZAPD/README.md index 4d7ade27e1..e2764b6277 100644 --- a/tools/ZAPD/README.md +++ b/tools/ZAPD/README.md @@ -30,7 +30,7 @@ You can configure a bit your ZAPD build with the following options: - `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_OFF=1`: Disables deprecation warnings. + - `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: @@ -110,8 +110,10 @@ ZAPD also accepts the following list of extra parameters: - Can be used only in `e` or `bsf` modes. - `-tm MODE`: Test Mode (enables certain experimental features). To enable it, set `MODE` to `1`. - `-wno` / `--warn-no-offsets` : Enable warnings for nodes that dont have offsets specified. Takes priority over `-eno`/ `--error-no-offsets`. -- `-eno`/ `--error-no-offsets` : Enable errors for nodes that dont have offsets specified. +- `-eno` / `--error-no-offsets` : Enable errors for nodes that dont have offsets specified. - `-se` / `--set-exporter` : Sets which exporter to use. - `--gcc-compat` : Enables GCC compatible mode. Slower. +- `-s` / `--static` : Mark every asset as `static`. + - This behaviour can be overridden per asset using `Static=` in the respective XML node. 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. diff --git a/tools/ZAPD/ZAPD/Declaration.cpp b/tools/ZAPD/ZAPD/Declaration.cpp index 63a3918050..d2a86ffcc5 100644 --- a/tools/ZAPD/ZAPD/Declaration.cpp +++ b/tools/ZAPD/ZAPD/Declaration.cpp @@ -1,37 +1,31 @@ #include "Declaration.h" -Declaration::Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, size_t nSize, - std::string nText) +#include "Globals.h" +#include "Utils/StringHelper.h" + +Declaration::Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nText) { + address = nAddress; alignment = nAlignment; - padding = nPadding; size = nSize; text = nText; } -Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, std::string nText) - : Declaration(nAlignment, DeclarationPadding::None, nSize, 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(DeclarationAlignment nAlignment, DeclarationPadding nPadding, size_t nSize, - std::string nVarType, std::string nVarName, bool nIsArray, - std::string nText) - : Declaration(nAlignment, nPadding, nSize, nText) -{ - varType = nVarType; - varName = nVarName; - isArray = nIsArray; -} - -Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, size_t nArrayItemCnt, - std::string nText) - : Declaration(nAlignment, DeclarationPadding::None, nSize, nText) +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; @@ -39,10 +33,10 @@ Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, std::str arrayItemCnt = nArrayItemCnt; } -Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, std::string nArrayItemCntStr, - std::string nText) - : Declaration(nAlignment, DeclarationPadding::None, nSize, nText) +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; @@ -50,30 +44,179 @@ Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, std::str arrayItemCntStr = nArrayItemCntStr; } -Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, size_t nArrayItemCnt, - std::string nText, bool nIsExternal) - : Declaration(nAlignment, nSize, nVarType, nVarName, nIsArray, nArrayItemCnt, nText) +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(DeclarationAlignment nAlignment, DeclarationPadding nPadding, size_t nSize, - std::string nVarType, std::string nVarName, bool nIsArray, - size_t nArrayItemCnt, std::string nText) - : Declaration(nAlignment, nPadding, nSize, nText) -{ - varType = nVarType; - varName = nVarName; - isArray = nIsArray; - arrayItemCnt = nArrayItemCnt; -} - -Declaration::Declaration(std::string nIncludePath, size_t nSize, std::string nVarType, - std::string nVarName) - : Declaration(DeclarationAlignment::None, DeclarationPadding::None, nSize, "") +Declaration::Declaration(offset_t nAddress, const std::string& nIncludePath, size_t nSize, + const std::string& nVarType, const std::string& nVarName) + : Declaration(nAddress, DeclarationAlignment::Align4, nSize, "") { includePath = nIncludePath; varType = nVarType; varName = nVarName; } + +bool Declaration::IsStatic() const +{ + switch (staticConf) + { + case StaticConfig::Off: + return false; + + case StaticConfig::Global: + return Globals::Instance->forceStatic; + + case StaticConfig::On: + return true; + } + + return false; +} + +std::string Declaration::GetNormalDeclarationStr() const +{ + std::string output; + + if (preText != "") + output += preText + "\n"; + + if (IsStatic()) + { + output += "static "; + } + + if (isArray) + { + if (arrayItemCntStr != "") + { + output += StringHelper::Sprintf("%s %s[%s];\n", varType.c_str(), varName.c_str(), + arrayItemCntStr.c_str()); + } + else if (arrayItemCnt == 0) + { + output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str()); + } + else + { + output += StringHelper::Sprintf("%s %s[%i] = {\n", varType.c_str(), varName.c_str(), + arrayItemCnt); + } + + 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 != "") + output += + StringHelper::Sprintf("%s %s[%s] = {\n#include \"%s\"\n};", varType.c_str(), + varName.c_str(), arrayItemCntStr.c_str(), includePath.c_str()); + else if (arrayItemCnt != 0) + output += StringHelper::Sprintf("%s %s[%i] = {\n#include \"%s\"\n};", varType.c_str(), + varName.c_str(), arrayItemCnt, includePath.c_str()); + else + output += StringHelper::Sprintf("%s %s[] = {\n#include \"%s\"\n};", varType.c_str(), + varName.c_str(), includePath.c_str()); + + if (rightText != "") + output += " " + rightText + ""; + + output += "\n"; + + if (postText != "") + output += postText + "\n"; + + output += "\n"; + + return output; +} + +std::string Declaration::GetExternStr() const +{ + if (IsStatic() || varType == "") + { + return ""; + } + + if (isArray) + { + if (arrayItemCntStr != "") + { + return StringHelper::Sprintf("extern %s %s[%s];\n", varType.c_str(), varName.c_str(), + arrayItemCntStr.c_str()); + } + else if (arrayItemCnt != 0) + 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()); +} diff --git a/tools/ZAPD/ZAPD/Declaration.h b/tools/ZAPD/ZAPD/Declaration.h index f955110e78..138524a4c2 100644 --- a/tools/ZAPD/ZAPD/Declaration.h +++ b/tools/ZAPD/ZAPD/Declaration.h @@ -3,63 +3,77 @@ #include #include +// 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 { - None, Align4, Align8, Align16 }; -enum class DeclarationPadding +enum class StaticConfig { - None, - Pad4, - Pad8, - Pad16 + Off, + Global, + On }; class Declaration { public: + offset_t address; DeclarationAlignment alignment; - DeclarationPadding padding; 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::string preText; + std::string text; + std::string rightText; + std::string postText; + std::string preComment; + std::string postComment; + std::string varType; + std::string varName; + std::string includePath; bool isExternal = false; bool isArray = false; size_t arrayItemCnt = 0; - std::string arrayItemCntStr = ""; - std::vector references; + std::string arrayItemCntStr; + std::vector references; bool isUnaccounted = false; bool isPlaceholder = false; + bool declaredInXml = false; + StaticConfig staticConf = StaticConfig::Global; - Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, std::string nText); - Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, size_t nSize, - std::string nVarType, std::string nVarName, bool nIsArray, std::string nText); - Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, size_t nArrayItemCnt, std::string nText); - Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, std::string nArrayItemCntStr, - std::string nText); - Declaration(DeclarationAlignment nAlignment, size_t nSize, std::string nVarType, - std::string nVarName, bool nIsArray, size_t nArrayItemCnt, std::string nText, - bool nIsExternal); - Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, size_t nSize, - std::string nVarType, std::string nVarName, bool nIsArray, size_t nArrayItemCnt, - std::string nText); - Declaration(std::string nIncludePath, size_t nSize, std::string nVarType, std::string nVarName); + Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nVarType, const std::string& nVarName, bool nIsArray, + const std::string& nText); + Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nVarType, const std::string& nVarName, bool nIsArray, + size_t nArrayItemCnt, const std::string& nText); + Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nVarType, const std::string& nVarName, bool nIsArray, + const std::string& nArrayItemCntStr, const std::string& nText); + Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nVarType, const std::string& nVarName, bool nIsArray, + size_t nArrayItemCnt, const std::string& nText, bool nIsExternal); + + Declaration(offset_t nAddress, const std::string& nIncludePath, size_t nSize, + const std::string& nVarType, const std::string& nVarName); + + bool IsStatic() const; + + std::string GetNormalDeclarationStr() const; + std::string GetExternalDeclarationStr() const; + + std::string GetExternStr() const; + + std::string GetStaticForwardDeclarationStr() const; protected: - Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, size_t nSize, - std::string nText); -}; \ No newline at end of file + Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nText); +}; diff --git a/tools/ZAPD/ZAPD/GameConfig.cpp b/tools/ZAPD/ZAPD/GameConfig.cpp new file mode 100644 index 0000000000..f197493a4a --- /dev/null +++ b/tools/ZAPD/ZAPD/GameConfig.cpp @@ -0,0 +1,184 @@ +#include "GameConfig.h" + +#include +#include + +#include "Utils/Directory.h" +#include "Utils/File.h" +#include "Utils/Path.h" +#include "ZFile.h" +#include "tinyxml2.h" + +using ConfigFunc = void (GameConfig::*)(const tinyxml2::XMLElement&); + +GameConfig::~GameConfig() +{ + for (auto& declPair : segmentRefFiles) + { + for (auto& file : declPair.second) + { + delete file; + } + } +} + +void GameConfig::ReadTexturePool(const fs::path& texturePoolXmlPath) +{ + tinyxml2::XMLDocument doc; + tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.c_str()); + + if (eResult != tinyxml2::XML_SUCCESS) + { + fprintf(stderr, "Warning: Unable to read texture pool XML with error code %i\n", eResult); + return; + } + + tinyxml2::XMLNode* root = doc.FirstChild(); + + if (root == nullptr) + return; + + for (tinyxml2::XMLElement* child = root->FirstChildElement(); child != nullptr; + child = child->NextSiblingElement()) + { + if (std::string_view(child->Name()) == "Texture") + { + std::string crcStr = child->Attribute("CRC"); + fs::path texPath = child->Attribute("Path"); + std::string texName; + + uint32_t crc = strtoul(crcStr.c_str(), nullptr, 16); + + texturePool[crc].path = texPath; + } + } +} + +void GameConfig::GenSymbolMap(const fs::path& symbolMapPath) +{ + auto symbolLines = File::ReadAllLines(symbolMapPath); + + for (std::string& symbolLine : symbolLines) + { + auto split = StringHelper::Split(symbolLine, " "); + uint32_t addr = strtoul(split[0].c_str(), nullptr, 16); + std::string symbolName = split[1]; + + symbolMap[addr] = std::move(symbolName); + } +} + +void GameConfig::ConfigFunc_SymbolMap(const tinyxml2::XMLElement& element) +{ + std::string fileName = element.Attribute("File"); + GenSymbolMap(Path::GetDirectoryName(configFilePath) / fileName); +} + +void GameConfig::ConfigFunc_ActorList(const tinyxml2::XMLElement& element) +{ + std::string fileName = element.Attribute("File"); + std::vector lines = + File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName); + + for (auto& line : lines) + actorList.emplace_back(std::move(line)); +} + +void GameConfig::ConfigFunc_ObjectList(const tinyxml2::XMLElement& element) +{ + std::string fileName = element.Attribute("File"); + std::vector lines = + File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName); + + for (auto& line : lines) + objectList.emplace_back(std::move(line)); +} + +void GameConfig::ConfigFunc_TexturePool(const tinyxml2::XMLElement& element) +{ + std::string fileName = element.Attribute("File"); + ReadTexturePool(Path::GetDirectoryName(configFilePath) / fileName); +} + +void GameConfig::ConfigFunc_BGConfig(const tinyxml2::XMLElement& element) +{ + bgScreenWidth = element.IntAttribute("ScreenWidth", 320); + bgScreenHeight = element.IntAttribute("ScreenHeight", 240); +} + +void GameConfig::ConfigFunc_ExternalXMLFolder(const tinyxml2::XMLElement& element) +{ + const char* pathValue = element.Attribute("Path"); + if (pathValue == nullptr) + { + throw std::runtime_error( + StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t Missing 'Path' attribute in `ExternalXMLFolder` element.\n")); + } + if (externalXmlFolder != "") + { + throw std::runtime_error(StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t `ExternalXMLFolder` is duplicated.\n")); + } + externalXmlFolder = pathValue; +} + +void GameConfig::ConfigFunc_ExternalFile(const tinyxml2::XMLElement& element) +{ + const char* xmlPathValue = element.Attribute("XmlPath"); + if (xmlPathValue == nullptr) + { + throw std::runtime_error( + StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t Missing 'XmlPath' attribute in `ExternalFile` element.\n")); + } + const char* outPathValue = element.Attribute("OutPath"); + if (outPathValue == nullptr) + { + throw std::runtime_error( + StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t Missing 'OutPath' attribute in `ExternalFile` element.\n")); + } + + externalFiles.push_back(ExternalFile(fs::path(xmlPathValue), fs::path(outPathValue))); +} + +void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath) +{ + static const std::map ConfigFuncDictionary = { + {"SymbolMap", &GameConfig::ConfigFunc_SymbolMap}, + {"ActorList", &GameConfig::ConfigFunc_ActorList}, + {"ObjectList", &GameConfig::ConfigFunc_ObjectList}, + {"TexturePool", &GameConfig::ConfigFunc_TexturePool}, + {"BGConfig", &GameConfig::ConfigFunc_BGConfig}, + {"ExternalXMLFolder", &GameConfig::ConfigFunc_ExternalXMLFolder}, + {"ExternalFile", &GameConfig::ConfigFunc_ExternalFile}, + }; + + configFilePath = argConfigFilePath; + 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); + } +} diff --git a/tools/ZAPD/ZAPD/GameConfig.h b/tools/ZAPD/ZAPD/GameConfig.h new file mode 100644 index 0000000000..c478d16ceb --- /dev/null +++ b/tools/ZAPD/ZAPD/GameConfig.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include +#include +#include + +#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> segmentRefFiles; + std::map symbolMap; + std::vector actorList; + std::vector objectList; + std::map texturePool; // Key = CRC + + // ZBackground + uint32_t bgScreenWidth = 320, bgScreenHeight = 240; + + // ExternalFile + fs::path externalXmlFolder; + std::vector externalFiles; + + GameConfig() = default; + ~GameConfig(); + + void ReadTexturePool(const fs::path& texturePoolXmlPath); + void GenSymbolMap(const fs::path& symbolMapPath); + + void ConfigFunc_SymbolMap(const tinyxml2::XMLElement& element); + void ConfigFunc_ActorList(const tinyxml2::XMLElement& element); + void ConfigFunc_ObjectList(const tinyxml2::XMLElement& element); + void ConfigFunc_TexturePool(const tinyxml2::XMLElement& element); + void ConfigFunc_BGConfig(const tinyxml2::XMLElement& element); + void ConfigFunc_ExternalXMLFolder(const tinyxml2::XMLElement& element); + void ConfigFunc_ExternalFile(const tinyxml2::XMLElement& element); + + void ReadConfigFile(const fs::path& configFilePath); +}; diff --git a/tools/ZAPD/ZAPD/Globals.cpp b/tools/ZAPD/ZAPD/Globals.cpp index b3bc067bf1..036e4a5cbf 100644 --- a/tools/ZAPD/ZAPD/Globals.cpp +++ b/tools/ZAPD/ZAPD/Globals.cpp @@ -1,175 +1,35 @@ #include "Globals.h" + +#include +#include + #include #include -#include #include "tinyxml2.h" -using namespace tinyxml2; - Globals* Globals::Instance; Globals::Globals() { Instance = this; - files = std::vector(); - segments = std::vector(); - symbolMap = std::map(); - segmentRefs = std::map(); - segmentRefFiles = std::map(); game = ZGame::OOT_RETAIL; genSourceFile = true; testMode = false; profile = false; useLegacyZDList = false; useExternalResources = true; - lastScene = nullptr; verbosity = VerbosityLevel::VERBOSITY_SILENT; - currentExporter = ""; outputPath = Directory::GetCurrentDirectory(); } -std::string Globals::FindSymbolSegRef(int32_t segNumber, uint32_t symbolAddress) +Globals::~Globals() { - if (segmentRefs.find(segNumber) != segmentRefs.end()) + auto& exporters = GetExporterMap(); + + for (auto& it : exporters) { - if (segmentRefFiles.find(segNumber) == segmentRefFiles.end()) - { - XMLDocument doc; - std::string filePath = segmentRefs[segNumber]; - XMLError eResult = doc.LoadFile(filePath.c_str()); - - if (eResult != tinyxml2::XML_SUCCESS) - return "ERROR"; - - tinyxml2::XMLNode* root = doc.FirstChild(); - - if (root == nullptr) - return "ERROR"; - - for (XMLElement* child = root->FirstChildElement(); child != NULL; - child = child->NextSiblingElement()) - { - if (std::string(child->Name()) == "File") - { - ZFile* file = new ZFile(fileMode, child, "", "", filePath, true); - file->GeneratePlaceholderDeclarations(); - segmentRefFiles[segNumber] = file; - break; - } - } - } - - return segmentRefFiles[segNumber]->GetDeclarationName(symbolAddress, "ERROR"); - } - - return "ERROR"; -} - -void Globals::ReadConfigFile(const std::string& configFilePath) -{ - 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."); - return; - } - - tinyxml2::XMLNode* root = doc.FirstChild(); - - if (root == nullptr) - return; - - for (tinyxml2::XMLElement* child = root->FirstChildElement(); child != NULL; - child = child->NextSiblingElement()) - { - if (std::string(child->Name()) == "SymbolMap") - { - std::string fileName = std::string(child->Attribute("File")); - GenSymbolMap(Path::GetDirectoryName(configFilePath) + "/" + fileName); - } - else if (std::string(child->Name()) == "Segment") - { - std::string fileName = std::string(child->Attribute("File")); - int32_t segNumber = child->IntAttribute("Number"); - segmentRefs[segNumber] = fileName; - } - else if (std::string(child->Name()) == "ActorList") - { - std::string fileName = std::string(child->Attribute("File")); - std::vector lines = - File::ReadAllLines(Path::GetDirectoryName(configFilePath) + "/" + fileName); - - for (std::string line : lines) - cfg.actorList.push_back(StringHelper::Strip(line, "\r")); - } - else if (std::string(child->Name()) == "ObjectList") - { - std::string fileName = std::string(child->Attribute("File")); - std::vector lines = - File::ReadAllLines(Path::GetDirectoryName(configFilePath) + "/" + fileName); - - for (std::string line : lines) - cfg.objectList.push_back(StringHelper::Strip(line, "\r")); - } - else if (std::string(child->Name()) == "TexturePool") - { - std::string fileName = std::string(child->Attribute("File")); - ReadTexturePool(Path::GetDirectoryName(configFilePath) + "/" + fileName); - } - else if (std::string(child->Name()) == "BGConfig") - { - cfg.bgScreenWidth = child->IntAttribute("ScreenWidth", 320); - cfg.bgScreenHeight = child->IntAttribute("ScreenHeight", 240); - } - } -} - -void Globals::ReadTexturePool(const std::string& texturePoolXmlPath) -{ - tinyxml2::XMLDocument doc; - tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.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 != NULL; - child = child->NextSiblingElement()) - { - if (std::string(child->Name()) == "Texture") - { - std::string crcStr = std::string(child->Attribute("CRC")); - fs::path texPath = std::string(child->Attribute("Path")); - std::string texName = ""; - - uint32_t crc = strtoul(crcStr.c_str(), NULL, 16); - - cfg.texturePool[crc].path = texPath; - } - } -} - -void Globals::GenSymbolMap(const std::string& symbolMapPath) -{ - auto symbolLines = File::ReadAllLines(symbolMapPath); - - for (std::string symbolLine : symbolLines) - { - auto split = StringHelper::Split(symbolLine, " "); - uint32_t addr = strtoul(split[0].c_str(), NULL, 16); - std::string symbolName = split[1]; - - symbolMap[addr] = symbolName; + delete it.second; } } @@ -177,9 +37,10 @@ void Globals::AddSegment(int32_t segment, ZFile* file) { if (std::find(segments.begin(), segments.end(), segment) == segments.end()) segments.push_back(segment); + if (cfg.segmentRefFiles.find(segment) == cfg.segmentRefFiles.end()) + cfg.segmentRefFiles[segment] = std::vector(); - segmentRefs[segment] = file->GetXmlFilePath().string(); - segmentRefFiles[segment] = file; + cfg.segmentRefFiles[segment].push_back(file); } bool Globals::HasSegment(int32_t segment) @@ -187,21 +48,21 @@ bool Globals::HasSegment(int32_t segment) return std::find(segments.begin(), segments.end(), segment) != segments.end(); } -std::map* Globals::GetExporterMap() +std::map& Globals::GetExporterMap() { static std::map exporters; - return &exporters; + return exporters; } void Globals::AddExporter(std::string exporterName, ExporterSet* exporterSet) { - auto exporters = GetExporterMap(); - (*exporters)[exporterName] = exporterSet; + auto& exporters = GetExporterMap(); + exporters[exporterName] = exporterSet; } ZResourceExporter* Globals::GetExporter(ZResourceType resType) { - auto exporters = *GetExporterMap(); + auto& exporters = GetExporterMap(); if (currentExporter != "" && exporters[currentExporter]->exporters.find(resType) != exporters[currentExporter]->exporters.end()) @@ -212,10 +73,141 @@ ZResourceExporter* Globals::GetExporter(ZResourceType resType) ExporterSet* Globals::GetExporterSet() { - auto exporters = *GetExporterMap(); + auto& exporters = GetExporterMap(); if (currentExporter != "") return exporters[currentExporter]; else return nullptr; -} \ No newline at end of file +} + +bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile, + const std::string& expectedType, std::string& declName) +{ + if (segAddress == 0) + { + declName = "NULL"; + return true; + } + + uint8_t segment = GETSEGNUM(segAddress); + uint32_t offset = Seg2Filespace(segAddress, currentFile->baseAddress); + ZSymbol* sym; + + sym = currentFile->GetSymbolResource(offset); + if (sym != nullptr) + { + if (expectedType == "" || expectedType == sym->GetSourceTypeName()) + { + declName = sym->GetName(); + return true; + } + } + sym = currentFile->GetSymbolResource(segAddress); + if (sym != nullptr) + { + if (expectedType == "" || expectedType == sym->GetSourceTypeName()) + { + declName = sym->GetName(); + return true; + } + } + + if (currentFile->IsSegmentedInFilespaceRange(segAddress)) + { + if (currentFile->GetDeclarationPtrName(segAddress, expectedType, declName)) + return true; + } + else if (HasSegment(segment)) + { + for (auto file : cfg.segmentRefFiles[segment]) + { + offset = Seg2Filespace(segAddress, file->baseAddress); + + sym = file->GetSymbolResource(offset); + if (sym != nullptr) + { + if (expectedType == "" || expectedType == sym->GetSourceTypeName()) + { + declName = sym->GetName(); + return true; + } + } + sym = file->GetSymbolResource(segAddress); + if (sym != nullptr) + { + if (expectedType == "" || expectedType == sym->GetSourceTypeName()) + { + declName = sym->GetName(); + return true; + } + } + + if (file->IsSegmentedInFilespaceRange(segAddress)) + { + if (file->GetDeclarationPtrName(segAddress, expectedType, declName)) + return true; + } + } + } + + const auto& symbolFromMap = Globals::Instance->symbolMap.find(segAddress); + if (symbolFromMap != Globals::Instance->symbolMap.end()) + { + declName = "&" + symbolFromMap->second; + return true; + } + + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; +} + +bool Globals::GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize, + ZFile* currentFile, const std::string& expectedType, + std::string& declName) +{ + if (segAddress == 0) + { + declName = "NULL"; + return true; + } + + uint8_t segment = GETSEGNUM(segAddress); + + if (currentFile->IsSegmentedInFilespaceRange(segAddress)) + { + bool addressFound = currentFile->GetDeclarationArrayIndexedName(segAddress, elementSize, + expectedType, declName); + if (addressFound) + return true; + } + else if (HasSegment(segment)) + { + for (auto file : cfg.segmentRefFiles[segment]) + { + if (file->IsSegmentedInFilespaceRange(segAddress)) + { + bool addressFound = file->GetDeclarationArrayIndexedName(segAddress, elementSize, + expectedType, declName); + if (addressFound) + return true; + } + } + } + + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; +} + +ExternalFile::ExternalFile(fs::path nXmlPath, fs::path nOutPath) + : xmlPath{nXmlPath}, outPath{nOutPath} +{ +} + +ExporterSet::~ExporterSet() +{ + for (auto& it : exporters) + { + delete it.second; + } +} diff --git a/tools/ZAPD/ZAPD/Globals.h b/tools/ZAPD/ZAPD/Globals.h index 60c79db121..265f1af241 100644 --- a/tools/ZAPD/ZAPD/Globals.h +++ b/tools/ZAPD/ZAPD/Globals.h @@ -3,6 +3,7 @@ #include #include #include +#include "GameConfig.h" #include "ZFile.h" class ZRoom; @@ -14,36 +15,17 @@ enum class VerbosityLevel VERBOSITY_DEBUG }; -struct TexturePoolEntry -{ - fs::path path = ""; // Path to Shared Texture -}; - -class GameConfig -{ -public: - std::map segmentRefs; - std::map segmentRefFiles; - std::map symbolMap; - std::vector actorList; - std::vector objectList; - std::map texturePool; // Key = CRC - - // ZBackground - uint32_t bgScreenWidth = 320, bgScreenHeight = 240; - - GameConfig() = default; -}; - typedef void (*ExporterSetFunc)(ZFile*); typedef bool (*ExporterSetFuncBool)(ZFileMode fileMode); typedef void (*ExporterSetFuncVoid)(int argc, char* argv[], int& i); -typedef void (*ExporterSetFuncVoid2)(std::string buildMode, ZFileMode& fileMode); +typedef void (*ExporterSetFuncVoid2)(const std::string& buildMode, ZFileMode& fileMode); typedef void (*ExporterSetFuncVoid3)(); class ExporterSet { public: + ~ExporterSet(); + std::map exporters; ExporterSetFuncVoid parseArgsFunc = nullptr; ExporterSetFuncVoid2 parseFileModeFunc = nullptr; @@ -76,25 +58,37 @@ public: bool errorNoOffset = false; bool verboseUnaccounted = false; bool gccCompat = false; + bool forceStatic = false; std::vector files; + std::vector externalFiles; std::vector segments; - std::map segmentRefs; - std::map segmentRefFiles; - ZRoom* lastScene; std::map symbolMap; std::string currentExporter; - static std::map* GetExporterMap(); + static std::map& GetExporterMap(); static void AddExporter(std::string exporterName, ExporterSet* exporterSet); Globals(); - std::string FindSymbolSegRef(int32_t segNumber, uint32_t symbolAddress); - void ReadConfigFile(const std::string& configFilePath); - void ReadTexturePool(const std::string& texturePoolXmlPath); - void GenSymbolMap(const std::string& symbolMapPath); + ~Globals(); + void AddSegment(int32_t segment, ZFile* file); bool HasSegment(int32_t segment); + ZResourceExporter* GetExporter(ZResourceType resType); ExporterSet* GetExporterSet(); -}; \ No newline at end of file + + /** + * Search in every file (and the symbol map) for the `segAddress` passed as parameter. + * If the segment of `currentFile` is the same segment of `segAddress`, then that file will be + * used only, otherwise, the search will be performed in every other file. + * The name of that variable will be stored in the `declName` parameter. + * Returns `true` if the address is found. `false` otherwise, + * in which case `declName` will be set to the address formatted as a pointer. + */ + bool GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile, + const std::string& expectedType, std::string& declName); + + bool GetSegmentedArrayIndexedName(segptr_t segAddress, size_t elementSize, ZFile* currentFile, + const std::string& expectedType, std::string& declName); +}; diff --git a/tools/ZAPD/ZAPD/ImageBackend.cpp b/tools/ZAPD/ZAPD/ImageBackend.cpp index a8fb900f64..137e326c33 100644 --- a/tools/ZAPD/ZAPD/ImageBackend.cpp +++ b/tools/ZAPD/ZAPD/ImageBackend.cpp @@ -387,11 +387,22 @@ void ImageBackend::SetPalette(const ImageBackend& pal) { 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(y * pal.width + x, r, g, b, a); + SetPaletteIndex(index, r, g, b, a); } } } diff --git a/tools/ZAPD/ZAPD/Main.cpp b/tools/ZAPD/ZAPD/Main.cpp index e7fc6fcc73..298ca02629 100644 --- a/tools/ZAPD/ZAPD/Main.cpp +++ b/tools/ZAPD/ZAPD/Main.cpp @@ -20,13 +20,13 @@ #endif #include +#include #include "tinyxml2.h" -using namespace tinyxml2; - extern const char gBuildHash[]; -bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, ZFileMode fileMode); +bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath, + ZFileMode fileMode); void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const fs::path& outPath); void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath); @@ -113,7 +113,7 @@ int main(int argc, char* argv[]) } } - Globals* g = new Globals(); + Globals* g = new Globals; // Parse other "commands" for (int32_t i = 2; i < argc; i++) @@ -141,30 +141,30 @@ int main(int argc, char* argv[]) } else if (arg == "-gsf") // Generate source file during extraction { - Globals::Instance->genSourceFile = std::string(argv[++i]) == "1"; + Globals::Instance->genSourceFile = std::string_view(argv[++i]) == "1"; } else if (arg == "-tm") // Test Mode (enables certain experimental features) { - Globals::Instance->testMode = std::string(argv[++i]) == "1"; + 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(argv[++i]) == "1"; + Globals::Instance->testMode = std::string_view(argv[++i]) == "1"; } else if (arg == "-ulzdl") // Use Legacy ZDisplay List { - Globals::Instance->useLegacyZDList = std::string(argv[++i]) == "1"; + Globals::Instance->useLegacyZDList = std::string_view(argv[++i]) == "1"; } else if (arg == "-profile") // Enable profiling { - Globals::Instance->profile = std::string(argv[++i]) == "1"; + 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(argv[++i]) == "1"; + Globals::Instance->useExternalResources = std::string_view(argv[++i]) == "1"; } else if (arg == "-tt") // Set texture type { @@ -178,7 +178,7 @@ int main(int argc, char* argv[]) } else if (arg == "-rconf") // Read Config File { - Globals::Instance->ReadConfigFile(argv[++i]); + Globals::Instance->cfg.ReadConfigFile(argv[++i]); } else if (arg == "-eh") // Enable Error Handler { @@ -218,6 +218,10 @@ int main(int argc, char* argv[]) { Globals::Instance->gccCompat = true; } + else if (arg == "-s" || arg == "--static") + { + Globals::Instance->forceStatic = true; + } } // Parse File Mode @@ -258,6 +262,7 @@ int main(int argc, char* argv[]) if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash); + // TODO: switch if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) { bool procFileModeSuccess = false; @@ -267,39 +272,30 @@ int main(int argc, char* argv[]) if (!procFileModeSuccess) { - if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) + bool parseSuccessful; + + for (auto& extFile : Globals::Instance->cfg.externalFiles) { - bool parseSuccessful = - Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath, fileMode); + fs::path externalXmlFilePath = + Globals::Instance->cfg.externalXmlFolder / extFile.xmlPath; + + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + { + printf("Parsing external file from config: '%s'\n", + externalXmlFilePath.c_str()); + } + + parseSuccessful = Parse(externalXmlFilePath, Globals::Instance->baseRomPath, + extFile.outPath, ZFileMode::ExternalFile); if (!parseSuccessful) return 1; } - else if (fileMode == ZFileMode::BuildTexture) - { - TextureType texType = Globals::Instance->texType; - BuildAssetTexture(Globals::Instance->inputPath, texType, - Globals::Instance->outputPath); - } - else if (fileMode == ZFileMode::BuildBackground) - { - BuildAssetBackground(Globals::Instance->inputPath, Globals::Instance->outputPath); - } - else if (fileMode == ZFileMode::BuildBlob) - { - BuildAssetBlob(Globals::Instance->inputPath, Globals::Instance->outputPath); - } - else if (fileMode == ZFileMode::BuildOverlay) - { - ZOverlay* overlay = ZOverlay::FromBuild( - Path::GetDirectoryName(Globals::Instance->inputPath.string()), - Path::GetDirectoryName(Globals::Instance->cfgPath.string())); - - if (overlay) - File::WriteAllText(Globals::Instance->outputPath.string(), - overlay->GetSourceOutputCode("")); - } + parseSuccessful = Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath, + Globals::Instance->outputPath, fileMode); + if (!parseSuccessful) + return 1; } } else if (fileMode == ZFileMode::BuildTexture) @@ -321,18 +317,20 @@ int main(int argc, char* argv[]) ZOverlay::FromBuild(Path::GetDirectoryName(Globals::Instance->inputPath), Path::GetDirectoryName(Globals::Instance->cfgPath)); - if (overlay) + if (overlay != nullptr) File::WriteAllText(Globals::Instance->outputPath.string(), overlay->GetSourceOutputCode("")); } + delete g; return 0; } -bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, ZFileMode fileMode) +bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path& outPath, + ZFileMode fileMode) { - XMLDocument doc; - XMLError eResult = doc.LoadFile(xmlFilePath.string().c_str()); + tinyxml2::XMLDocument doc; + tinyxml2::XMLError eResult = doc.LoadFile(xmlFilePath.string().c_str()); if (eResult != tinyxml2::XML_SUCCESS) { @@ -340,7 +338,7 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, ZFileMode file return false; } - XMLNode* root = doc.FirstChild(); + tinyxml2::XMLNode* root = doc.FirstChild(); if (root == nullptr) { @@ -348,45 +346,78 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, ZFileMode file return false; } - for (XMLElement* child = root->FirstChildElement(); child != NULL; + for (tinyxml2::XMLElement* child = root->FirstChildElement(); child != NULL; child = child->NextSiblingElement()) { - if (std::string(child->Name()) == "File") + if (std::string_view(child->Name()) == "File") { - ZFile* file = new ZFile(fileMode, child, basePath, "", xmlFilePath, false); + ZFile* file = new ZFile(fileMode, child, basePath, outPath, "", xmlFilePath); Globals::Instance->files.push_back(file); + if (fileMode == ZFileMode::ExternalFile) + { + Globals::Instance->externalFiles.push_back(file); + file->isExternalFile = true; + } + } + else if (std::string(child->Name()) == "ExternalFile") + { + const char* xmlPathValue = child->Attribute("XmlPath"); + if (xmlPathValue == nullptr) + { + throw std::runtime_error(StringHelper::Sprintf( + "Parse: Fatal error in '%s'.\n" + "\t Missing 'XmlPath' attribute in `ExternalFile` element.\n", + xmlFilePath.c_str())); + } + const char* outPathValue = child->Attribute("OutPath"); + if (outPathValue == nullptr) + { + throw std::runtime_error(StringHelper::Sprintf( + "Parse: Fatal error in '%s'.\n" + "\t Missing 'OutPath' attribute in `ExternalFile` element.\n", + xmlFilePath.c_str())); + } + + fs::path externalXmlFilePath = + Globals::Instance->cfg.externalXmlFolder / fs::path(xmlPathValue); + fs::path externalOutFilePath = fs::path(outPathValue); + + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + { + printf("Parsing external file: '%s'\n", externalXmlFilePath.c_str()); + } + + // Recursion. What can go wrong? + Parse(externalXmlFilePath, basePath, externalOutFilePath, ZFileMode::ExternalFile); } else { - throw std::runtime_error( - StringHelper::Sprintf("Parse: Fatal error in '%s'.\n\t Found a resource outside of " - "a File element: '%s'\n", - xmlFilePath.c_str(), child->Name())); + throw std::runtime_error(StringHelper::Sprintf( + "Parse: Fatal error in '%s'.\n\t A resource was found outside of " + "a File element: '%s'\n", + xmlFilePath.c_str(), child->Name())); } } - ExporterSet* exporterSet = Globals::Instance->GetExporterSet(); - - if (exporterSet != nullptr && exporterSet->beginXMLFunc != nullptr) - exporterSet->beginXMLFunc(); - - for (ZFile* file : Globals::Instance->files) + if (fileMode != ZFileMode::ExternalFile) { - if (fileMode == ZFileMode::BuildSourceFile) - file->BuildSourceFile(); - else - file->ExtractResources(); + ExporterSet* exporterSet = Globals::Instance->GetExporterSet(); + + if (exporterSet != nullptr && exporterSet->beginXMLFunc != nullptr) + exporterSet->beginXMLFunc(); + + for (ZFile* file : Globals::Instance->files) + { + if (fileMode == ZFileMode::BuildSourceFile) + file->BuildSourceFile(); + else + file->ExtractResources(); + } + + if (exporterSet != nullptr && exporterSet->endXMLFunc != nullptr) + exporterSet->endXMLFunc(); } - if (exporterSet != nullptr && exporterSet->endXMLFunc != nullptr) - exporterSet->endXMLFunc(); - - // All done, free files - for (ZFile* file : Globals::Instance->files) - delete file; - - Globals::Instance->files.clear(); - return true; } @@ -419,7 +450,7 @@ 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->GetSourceOutputCode(name); + std::string src = blob->GetBodySourceCode(); File::WriteAllText(outPath.string(), src); diff --git a/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp b/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp new file mode 100644 index 0000000000..9d16de4389 --- /dev/null +++ b/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp @@ -0,0 +1,341 @@ +#include "SkinLimbStructs.h" + +#include "Globals.h" +#include "Utils/BitConverter.h" +#include "Utils/StringHelper.h" +#include "ZDisplayList.h" +#include "ZFile.h" + +/* Struct_800A57C0 */ + +Struct_800A57C0::Struct_800A57C0(ZFile* nParent) : ZResource(nParent) +{ +} + +void Struct_800A57C0::ParseRawData() +{ + const auto& rawData = parent->GetRawData(); + + unk_0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x00); + unk_2 = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x02); + unk_4 = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x04); + unk_6 = BitConverter::ToInt8BE(rawData, rawDataIndex + 0x06); + unk_7 = BitConverter::ToInt8BE(rawData, rawDataIndex + 0x07); + unk_8 = BitConverter::ToInt8BE(rawData, rawDataIndex + 0x08); + unk_9 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x09); +} + +std::string Struct_800A57C0::GetBodySourceCode() const +{ + return StringHelper::Sprintf("0x%02X, %i, %i, %i, %i, %i, 0x%02X", unk_0, unk_2, unk_4, unk_6, + unk_7, unk_8, unk_9); +} + +std::string Struct_800A57C0::GetSourceTypeName() const +{ + return "Struct_800A57C0"; +} + +ZResourceType Struct_800A57C0::GetResourceType() const +{ + // TODO + return ZResourceType::Error; +} + +size_t Struct_800A57C0::GetRawDataSize() const +{ + return 0x0A; +} + +/* Struct_800A598C_2 */ + +Struct_800A598C_2::Struct_800A598C_2(ZFile* nParent) : ZResource(nParent) +{ +} + +void Struct_800A598C_2::ParseRawData() +{ + const auto& rawData = parent->GetRawData(); + + unk_0 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x00); + x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x02); + y = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x04); + z = BitConverter::ToInt16BE(rawData, rawDataIndex + 0x06); + unk_8 = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0x08); +} + +std::string Struct_800A598C_2::GetBodySourceCode() const +{ + return StringHelper::Sprintf("0x%02X, %i, %i, %i, 0x%02X", unk_0, x, y, z, unk_8); +} + +std::string Struct_800A598C_2::GetSourceTypeName() const +{ + return "Struct_800A598C_2"; +} + +ZResourceType Struct_800A598C_2::GetResourceType() const +{ + // TODO + return ZResourceType::Error; +} + +size_t Struct_800A598C_2::GetRawDataSize() const +{ + return 0x0A; +} + +/* Struct_800A598C */ + +Struct_800A598C::Struct_800A598C(ZFile* nParent) : ZResource(nParent) +{ +} + +void Struct_800A598C::ParseRawData() +{ + const auto& rawData = parent->GetRawData(); + + unk_0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x00); + unk_2 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x02); + unk_4 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x04); + unk_8 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x08); + unk_C = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0C); + + if (unk_8 != 0 && GETSEGNUM(unk_8) == parent->segment) + { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + for (size_t i = 0; i < unk_0; i++) + { + Struct_800A57C0 unk8_data(parent); + unk8_data.ExtractFromFile(unk_8_Offset); + unk_8_arr.push_back(unk8_data); + + unk_8_Offset += unk8_data.GetRawDataSize(); + } + } + + if (unk_C != 0 && GETSEGNUM(unk_8) == parent->segment) + { + uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); + for (size_t i = 0; i < unk_2; i++) + { + Struct_800A598C_2 unkC_data(parent); + unkC_data.ExtractFromFile(unk_C_Offset); + unk_C_arr.push_back(unkC_data); + + unk_C_Offset += unkC_data.GetRawDataSize(); + } + } +} + +void Struct_800A598C::DeclareReferences(const std::string& prefix) +{ + std::string varPrefix = prefix; + if (name != "") + varPrefix = name; + + if (unk_8 != 0 && GETSEGNUM(unk_8) == parent->segment) + { + const auto& res = unk_8_arr.at(0); + std::string unk_8_Str = res.GetDefaultName(varPrefix); + + size_t arrayItemCnt = unk_8_arr.size(); + std::string entryStr = ""; + + for (size_t i = 0; i < arrayItemCnt; i++) + { + auto& child = unk_8_arr[i]; + child.DeclareReferences(varPrefix); + entryStr += StringHelper::Sprintf("\t{ %s },", child.GetBodySourceCode().c_str()); + + if (i < arrayItemCnt - 1) + entryStr += "\n"; + } + + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + Declaration* decl = parent->GetDeclaration(unk_8_Offset); + if (decl == nullptr) + { + parent->AddDeclarationArray(unk_8_Offset, res.GetDeclarationAlignment(), + arrayItemCnt * res.GetRawDataSize(), + res.GetSourceTypeName(), unk_8_Str, arrayItemCnt, entryStr); + } + else + decl->text = entryStr; + } + + if (unk_C != 0 && GETSEGNUM(unk_C) == parent->segment) + { + const auto& res = unk_C_arr.at(0); + std::string unk_C_Str = res.GetDefaultName(varPrefix); + + size_t arrayItemCnt = unk_C_arr.size(); + std::string entryStr = ""; + + for (size_t i = 0; i < arrayItemCnt; i++) + { + auto& child = unk_C_arr[i]; + child.DeclareReferences(varPrefix); + entryStr += StringHelper::Sprintf("\t{ %s },", child.GetBodySourceCode().c_str()); + + if (i < arrayItemCnt - 1) + entryStr += "\n"; + } + + uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); + Declaration* decl = parent->GetDeclaration(unk_C_Offset); + if (decl == nullptr) + { + parent->AddDeclarationArray(unk_C_Offset, res.GetDeclarationAlignment(), + arrayItemCnt * res.GetRawDataSize(), + res.GetSourceTypeName(), unk_C_Str, arrayItemCnt, entryStr); + } + else + decl->text = entryStr; + } +} + +std::string Struct_800A598C::GetBodySourceCode() const +{ + std::string unk_8_Str; + std::string unk_C_Str; + Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Struct_800A57C0", unk_8_Str); + Globals::Instance->GetSegmentedPtrName(unk_C, parent, "Struct_800A598C_2", unk_C_Str); + + std::string entryStr = StringHelper::Sprintf("\n\t\tARRAY_COUNTU(%s), ARRAY_COUNTU(%s),\n", + unk_8_Str.c_str(), unk_C_Str.c_str()); + entryStr += + StringHelper::Sprintf("\t\t%i, %s, %s\n\t", unk_4, unk_8_Str.c_str(), unk_C_Str.c_str()); + + return entryStr; +} + +std::string Struct_800A598C::GetSourceTypeName() const +{ + return "Struct_800A598C"; +} + +ZResourceType Struct_800A598C::GetResourceType() const +{ + // TODO + return ZResourceType::Error; +} + +size_t Struct_800A598C::GetRawDataSize() const +{ + return 0x10; +} + +/* Struct_800A5E28 */ + +Struct_800A5E28::Struct_800A5E28(ZFile* nParent) : ZResource(nParent) +{ +} + +void Struct_800A5E28::ParseRawData() +{ + const auto& rawData = parent->GetRawData(); + + unk_0 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x00); + unk_2 = BitConverter::ToUInt16BE(rawData, rawDataIndex + 0x02); + unk_4 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x04); + unk_8 = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x08); + + if (unk_4 != 0 && GETSEGNUM(unk_4) == parent->segment) + { + uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); + for (size_t i = 0; i < unk_2; i++) + { + Struct_800A598C unk_4_data(parent); + unk_4_data.ExtractFromFile(unk_4_Offset); + unk_4_arr.push_back(unk_4_data); + + unk_4_Offset += unk_4_data.GetRawDataSize(); + } + } +} + +void Struct_800A5E28::DeclareReferences(const std::string& prefix) +{ + std::string varPrefix = prefix; + if (name != "") + varPrefix = name; + + ZResource::DeclareReferences(varPrefix); + + if (unk_4 != 0 && 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 != 0 && 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); + ZDisplayList* 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); + parent->AddResource(unk_8_dlist); + } +} + +std::string Struct_800A5E28::GetBodySourceCode() const +{ + std::string unk_4_Str; + std::string unk_8_Str; + Globals::Instance->GetSegmentedPtrName(unk_4, parent, "Struct_800A598C", unk_4_Str); + Globals::Instance->GetSegmentedPtrName(unk_8, parent, "Gfx", unk_8_Str); + + std::string entryStr = "\n"; + entryStr += StringHelper::Sprintf("\t%i, ARRAY_COUNTU(%s),\n", unk_0, unk_4_Str.c_str()); + entryStr += StringHelper::Sprintf("\t%s, %s\n", unk_4_Str.c_str(), unk_8_Str.c_str()); + + return entryStr; +} + +std::string Struct_800A5E28::GetSourceTypeName() const +{ + return "Struct_800A5E28"; +} + +ZResourceType Struct_800A5E28::GetResourceType() const +{ + // TODO + return ZResourceType::Error; +} + +size_t Struct_800A5E28::GetRawDataSize() const +{ + return 0x0C; +} diff --git a/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.h b/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.h new file mode 100644 index 0000000000..33edd07cae --- /dev/null +++ b/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.h @@ -0,0 +1,113 @@ +#pragma once + +#include +#include +#include + +#include "ZResource.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; + +protected: + 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; + +protected: + 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; + +protected: + 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 unk_8_arr; + std::vector 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; + +protected: + 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 unk_4_arr; + // ZDisplayList* unk_8_dlist = nullptr; +}; diff --git a/tools/ZAPD/ZAPD/OutputFormatter.cpp b/tools/ZAPD/ZAPD/OutputFormatter.cpp index 4c92b621ec..393ec1936a 100644 --- a/tools/ZAPD/ZAPD/OutputFormatter.cpp +++ b/tools/ZAPD/ZAPD/OutputFormatter.cpp @@ -101,9 +101,9 @@ int (*OutputFormatter::StaticWriter())(const char* buf, int count) return &WriteStatic; } -OutputFormatter::OutputFormatter(uint32_t tabSize, uint32_t defaultIndent, uint32_t lineLimit) - : tabSize{tabSize}, lineLimit{lineLimit}, col{0}, nest{0}, nestIndent{defaultIndent}, - currentIndent{defaultIndent}, wordNests(0), wordP{word}, spaceP{space} +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} { } diff --git a/tools/ZAPD/ZAPD/OutputFormatter.h b/tools/ZAPD/ZAPD/OutputFormatter.h index b024d958eb..28955b1cd1 100644 --- a/tools/ZAPD/ZAPD/OutputFormatter.h +++ b/tools/ZAPD/ZAPD/OutputFormatter.h @@ -29,7 +29,7 @@ private: static int WriteStatic(const char* buf, int count); public: - OutputFormatter(uint32_t tabSize = 4, uint32_t defaultIndent = 4, uint32_t lineLimit = 120); + 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 @@ -37,4 +37,4 @@ public: int Write(const std::string& buf); std::string GetOutput(); -}; \ No newline at end of file +}; diff --git a/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp index 0f68c849cb..a842a7e7d9 100644 --- a/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp +++ b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp @@ -51,7 +51,7 @@ ZOverlay::ZOverlay() entries = std::vector(); } -ZOverlay::ZOverlay(std::string nName) : ZOverlay() +ZOverlay::ZOverlay(const std::string& nName) : ZOverlay() { name = nName; } @@ -251,7 +251,7 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath) std::string ZOverlay::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) { - std::string output = ""; + std::string output; output += ".section .ovl\n"; @@ -286,7 +286,7 @@ std::string ZOverlay::GetSourceOutputCode([[maybe_unused]] const std::string& pr return output; } -SectionType ZOverlay::GetSectionTypeFromStr(std::string sectionName) +SectionType ZOverlay::GetSectionTypeFromStr(const std::string& sectionName) { if (sectionName == ".rel.text" || sectionName == ".text") return SectionType::Text; diff --git a/tools/ZAPD/ZAPD/Overlays/ZOverlay.h b/tools/ZAPD/ZAPD/Overlays/ZOverlay.h index 971a66e840..98ead90132 100644 --- a/tools/ZAPD/ZAPD/Overlays/ZOverlay.h +++ b/tools/ZAPD/ZAPD/Overlays/ZOverlay.h @@ -56,7 +56,7 @@ class ZOverlay public: std::string name; - ZOverlay(std::string nName); + ZOverlay(const std::string& nName); ~ZOverlay(); static ZOverlay* FromBuild(fs::path buildPath, fs::path cfgFolderPath); std::string GetSourceOutputCode(const std::string& prefix); @@ -67,7 +67,7 @@ private: ZOverlay(); - static SectionType GetSectionTypeFromStr(std::string sectionName); + 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, diff --git a/tools/ZAPD/ZAPD/ZAnimation.cpp b/tools/ZAPD/ZAPD/ZAnimation.cpp index e0ee26366c..9242f657a8 100644 --- a/tools/ZAPD/ZAPD/ZAnimation.cpp +++ b/tools/ZAPD/ZAPD/ZAnimation.cpp @@ -1,5 +1,7 @@ #include "ZAnimation.h" + #include + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/File.h" @@ -23,73 +25,15 @@ void ZAnimation::ParseRawData() frameCount = BitConverter::ToInt16BE(parent->GetRawData(), rawDataIndex + 0); } -std::string ZAnimation::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - return ""; -} - ZResourceType ZAnimation::GetResourceType() const { return ZResourceType::Animation; } +/* ZNormalAnimation */ + ZNormalAnimation::ZNormalAnimation(ZFile* nParent) : ZAnimation(nParent) { - rotationValues = std::vector(); - rotationIndices = std::vector(); - limit = 0; -} - -std::string ZNormalAnimation::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - if (parent != nullptr) - { - std::string defaultPrefix = name.c_str(); - defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables - - std::string headerStr = StringHelper::Sprintf("\n\t{ %i },\n", frameCount); - headerStr += StringHelper::Sprintf("\t%sFrameData,\n", defaultPrefix.c_str()); - headerStr += StringHelper::Sprintf("\t%sJointIndices,\n", defaultPrefix.c_str()); - headerStr += StringHelper::Sprintf("\t%i\n", limit); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), StringHelper::Sprintf("%s", name.c_str()), - headerStr); - - std::string indicesStr = ""; - std::string valuesStr = " "; - const uint8_t lineLength = 14; - const uint8_t offset = 0; - - for (size_t i = 0; i < rotationValues.size(); i++) - { - valuesStr += StringHelper::Sprintf("0x%04X, ", rotationValues[i]); - - if ((i - offset + 1) % lineLength == 0) - valuesStr += "\n "; - } - - 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(rotationValuesSeg, DeclarationAlignment::Align16, - rotationValues.size() * 2, "static s16", - StringHelper::Sprintf("%sFrameData", defaultPrefix.c_str()), - rotationValues.size(), valuesStr); - - parent->AddDeclarationArray(rotationIndicesSeg, DeclarationAlignment::Align16, - rotationIndices.size() * 6, "static JointIndex", - StringHelper::Sprintf("%sJointIndices", defaultPrefix.c_str()), - rotationIndices.size(), indicesStr); - } - - return ""; } size_t ZNormalAnimation::GetRawDataSize() const @@ -108,23 +52,26 @@ void ZNormalAnimation::ParseRawData() const uint8_t* data = parent->GetRawData().data(); - rotationValuesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 4) & 0x00FFFFFF; - rotationIndicesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 8) & 0x00FFFFFF; + rotationValuesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 4); + rotationIndicesSeg = BitConverter::ToInt32BE(data, rawDataIndex + 8); limit = BitConverter::ToInt16BE(data, rawDataIndex + 12); - uint32_t currentPtr = rotationValuesSeg; + rotationValuesOffset = Seg2Filespace(rotationValuesSeg, parent->baseAddress); + rotationIndicesOffset = Seg2Filespace(rotationIndicesSeg, parent->baseAddress); + + uint32_t currentPtr = rotationValuesOffset; // Read the Rotation Values - for (uint32_t i = 0; i < ((rotationIndicesSeg - rotationValuesSeg) / 2); i++) + for (uint32_t i = 0; i < ((rotationIndicesOffset - rotationValuesOffset) / 2); i++) { rotationValues.push_back(BitConverter::ToInt16BE(data, currentPtr)); currentPtr += 2; } - currentPtr = rotationIndicesSeg; + currentPtr = rotationIndicesOffset; // Read the Rotation Indices - for (uint32_t i = 0; i < ((rawDataIndex - rotationIndicesSeg) / 6); i++) + for (uint32_t i = 0; i < ((rawDataIndex - rotationIndicesOffset) / 6); i++) { rotationIndices.push_back(RotationIndex(BitConverter::ToInt16BE(data, currentPtr), BitConverter::ToInt16BE(data, currentPtr + 2), @@ -133,31 +80,71 @@ void ZNormalAnimation::ParseRawData() } } +void ZNormalAnimation::DeclareReferences(const std::string& prefix) +{ + std::string defaultPrefix = prefix.c_str(); + if (name != "") + defaultPrefix = name; + + // replace g prefix with s for local variables + if (defaultPrefix.at(0) == 'g') + defaultPrefix.replace(0, 1, "s"); + + std::string indicesStr = ""; + std::string valuesStr = " "; + const uint8_t lineLength = 14; + const uint8_t offset = 0; + + for (size_t i = 0; i < rotationValues.size(); i++) + { + valuesStr += StringHelper::Sprintf("0x%04X, ", rotationValues[i]); + + if ((i - offset + 1) % lineLength == 0) + valuesStr += "\n "; + } + + parent->AddDeclarationArray(rotationValuesOffset, DeclarationAlignment::Align16, + rotationValues.size() * 2, "s16", + StringHelper::Sprintf("%sFrameData", defaultPrefix.c_str()), + rotationValues.size(), valuesStr); + + for (size_t i = 0; i < rotationIndices.size(); i++) + { + indicesStr += StringHelper::Sprintf(" { 0x%04X, 0x%04X, 0x%04X },", rotationIndices[i].x, + rotationIndices[i].y, rotationIndices[i].z); + + if (i != (rotationIndices.size() - 1)) + indicesStr += "\n"; + } + + parent->AddDeclarationArray(rotationIndicesOffset, DeclarationAlignment::Align16, + rotationIndices.size() * 6, "JointIndex", + StringHelper::Sprintf("%sJointIndices", defaultPrefix.c_str()), + rotationIndices.size(), indicesStr); +} + +std::string ZNormalAnimation::GetBodySourceCode() const +{ + std::string frameDataName; + Globals::Instance->GetSegmentedPtrName(rotationValuesSeg, parent, "s16", frameDataName); + std::string jointIndicesName; + Globals::Instance->GetSegmentedPtrName(rotationIndicesSeg, parent, "JointIndex", + jointIndicesName); + + std::string headerStr = + StringHelper::Sprintf("\n\t{ %i }, %s,\n", frameCount, frameDataName.c_str()); + headerStr += StringHelper::Sprintf("\t%s, %i\n", jointIndicesName.c_str(), limit); + + return headerStr; +} + +/* ZLinkAnimation */ + ZLinkAnimation::ZLinkAnimation(ZFile* nParent) : ZAnimation(nParent) { segmentAddress = 0; } -std::string ZLinkAnimation::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - if (parent != nullptr) - { - std::string segSymbol = - segmentAddress == 0 ? - "NULL" : - parent->GetDeclarationName( - segmentAddress, - StringHelper::Sprintf("%sSeg%06X", name.c_str(), segmentAddress)); - std::string headerStr = - StringHelper::Sprintf("\n\t{ %i },\n\t0x%08X\n", frameCount, segmentAddress); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), StringHelper::Sprintf("%s", name.c_str()), - headerStr); - } - - return ""; -} - size_t ZLinkAnimation::GetRawDataSize() const { return 8; @@ -172,8 +159,16 @@ void ZLinkAnimation::ParseRawData() { ZAnimation::ParseRawData(); - const uint8_t* data = parent->GetRawData().data(); - segmentAddress = (BitConverter::ToInt32BE(data, rawDataIndex + 4)); + const auto& rawData = parent->GetRawData(); + segmentAddress = BitConverter::ToInt32BE(rawData, rawDataIndex + 4); +} + +std::string ZLinkAnimation::GetBodySourceCode() const +{ + std::string segSymbol; + Globals::Instance->GetSegmentedPtrName(segmentAddress, parent, "", segSymbol); + + return StringHelper::Sprintf("\n\t{ %i }, %s\n", frameCount, segSymbol.c_str()); } /* ZCurveAnimation */ @@ -280,14 +275,6 @@ void ZCurveAnimation::ParseRawData() } } -void ZCurveAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, GetRawDataSize(), - GetSourceTypeName(), name, ""); -} - void ZCurveAnimation::DeclareReferences(const std::string& prefix) { if (refIndex != 0) @@ -308,7 +295,7 @@ void ZCurveAnimation::DeclareReferences(const std::string& prefix) Declaration* decl = parent->GetDeclaration(refIndexOffset); if (decl == nullptr) { - parent->AddDeclarationArray(refIndexOffset, DeclarationAlignment::None, + parent->AddDeclarationArray(refIndexOffset, DeclarationAlignment::Align4, arrayItemCnt * 1, "u8", refIndexStr, arrayItemCnt, entryStr); } @@ -325,7 +312,7 @@ void ZCurveAnimation::DeclareReferences(const std::string& prefix) "%sCurveAnime_%s_%06X", prefix.c_str(), transformDataArr.at(0).GetSourceTypeName().c_str(), transformDataOffset); - std::string entryStr = ""; + std::string entryStr; uint16_t arrayItemCnt = transformDataArr.size(); size_t i = 0; @@ -338,7 +325,7 @@ void ZCurveAnimation::DeclareReferences(const std::string& prefix) Declaration* decl = parent->GetDeclaration(transformDataOffset); if (decl == nullptr) { - parent->AddDeclarationArray(transformDataOffset, DeclarationAlignment::None, + parent->AddDeclarationArray(transformDataOffset, DeclarationAlignment::Align4, arrayItemCnt * transformDataArr.at(0).GetRawDataSize(), transformDataArr.at(0).GetSourceTypeName(), transformDataStr, arrayItemCnt, entryStr); @@ -367,7 +354,7 @@ void ZCurveAnimation::DeclareReferences(const std::string& prefix) Declaration* decl = parent->GetDeclaration(copyValuesOffset); if (decl == nullptr) { - parent->AddDeclarationArray(copyValuesOffset, DeclarationAlignment::None, + parent->AddDeclarationArray(copyValuesOffset, DeclarationAlignment::Align4, arrayItemCnt * 2, "s16", copyValuesStr, arrayItemCnt, entryStr); } @@ -378,81 +365,28 @@ void ZCurveAnimation::DeclareReferences(const std::string& prefix) } } +std::string ZCurveAnimation::GetBodySourceCode() const +{ + std::string refIndexStr; + Globals::Instance->GetSegmentedPtrName(refIndex, parent, "u8", refIndexStr); + std::string transformDataStr; + Globals::Instance->GetSegmentedPtrName(transformData, parent, "TransformData", + transformDataStr); + std::string copyValuesStr; + Globals::Instance->GetSegmentedPtrName(copyValues, parent, "s16", copyValuesStr); + + return StringHelper::Sprintf("\n\t%s,\n\t%s,\n\t%s,\n\t%i, %i\n", refIndexStr.c_str(), + transformDataStr.c_str(), copyValuesStr.c_str(), unk_0C, unk_10); +} + size_t ZCurveAnimation::GetRawDataSize() const { return 0x10; } -std::string ZCurveAnimation::GetSourceOutputCode(const std::string& prefix) +DeclarationAlignment ZCurveAnimation::GetDeclarationAlignment() const { - std::string bodyStr = ""; - uint32_t address = Seg2Filespace(rawDataIndex, parent->baseAddress); - - std::string refIndexStr = "NULL"; - if (refIndex != 0) - { - uint32_t refIndexOffset = Seg2Filespace(refIndex, parent->baseAddress); - Declaration* decl = parent->GetDeclaration(refIndexOffset); - if (decl == nullptr) - { - refIndexStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Ref", - refIndexOffset); - } - else - { - refIndexStr = decl->varName; - } - } - - std::string transformDataStr = "NULL"; - if (transformData != 0) - { - uint32_t transformDataOffset = Seg2Filespace(transformData, parent->baseAddress); - Declaration* decl = parent->GetDeclaration(transformDataOffset); - if (decl == nullptr) - { - transformDataStr = StringHelper::Sprintf( - "%sCurveAnime_%s_%06X", prefix.c_str(), - transformDataArr.at(0).GetSourceTypeName().c_str(), transformDataOffset); - } - else - { - transformDataStr = decl->varName; - } - } - - std::string copyValuesStr = "NULL"; - if (copyValues != 0) - { - uint32_t copyValuesOffset = Seg2Filespace(copyValues, parent->baseAddress); - Declaration* decl = parent->GetDeclaration(copyValuesOffset); - if (decl == nullptr) - { - copyValuesStr = StringHelper::Sprintf("%sCurveAnime_%s_%06X", prefix.c_str(), "Copy", - copyValuesOffset); - } - else - { - copyValuesStr = decl->varName; - } - } - - bodyStr = - StringHelper::Sprintf("\n %s,\n %s,\n %s,\n %i, %i\n", refIndexStr.c_str(), - transformDataStr.c_str(), copyValuesStr.c_str(), unk_0C, unk_10); - - Declaration* decl = parent->GetDeclaration(address); - if (decl == nullptr) - { - parent->AddDeclaration(address, DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), name, bodyStr); - } - else - { - decl->text = bodyStr; - } - - return ""; + return DeclarationAlignment::Align16; } std::string ZCurveAnimation::GetSourceTypeName() const @@ -466,14 +400,6 @@ ZLegacyAnimation::ZLegacyAnimation(ZFile* nParent) : ZAnimation(nParent) { } -void ZLegacyAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZAnimation::ExtractFromXML(reader, nRawDataIndex); - - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), name, ""); -} - void ZLegacyAnimation::ParseRawData() { ZAnimation::ParseRawData(); @@ -543,7 +469,7 @@ void ZLegacyAnimation::DeclareReferences(const std::string& prefix) if (GETSEGNUM(jointKey) == parent->segment && !parent->HasDeclaration(jointKeyOffset)) { const auto res = jointKeyArray.at(0); - std::string jointKeyBody = ""; + std::string jointKeyBody; for (size_t i = 0; i < jointKeyArray.size(); i++) { @@ -567,8 +493,10 @@ std::string ZLegacyAnimation::GetBodySourceCode() const { std::string body = "\n"; - std::string frameDataName = parent->GetDeclarationPtrName(frameData); - std::string jointKeyName = parent->GetDeclarationPtrName(jointKey); + std::string frameDataName; + std::string jointKeyName; + Globals::Instance->GetSegmentedPtrName(frameData, parent, "s16", frameDataName); + Globals::Instance->GetSegmentedPtrName(jointKey, parent, "JointKey", jointKeyName); body += StringHelper::Sprintf("\t%i, %i,\n", frameCount, limbCount); body += StringHelper::Sprintf("\t%s,\n", frameDataName.c_str()); @@ -577,20 +505,6 @@ std::string ZLegacyAnimation::GetBodySourceCode() const return body; } -std::string ZLegacyAnimation::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - std::string body = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr || decl->isPlaceholder) - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), name, body); - else - decl->text = body; - - return ""; -} - std::string ZLegacyAnimation::GetSourceTypeName() const { return "LegacyAnimationHeader"; diff --git a/tools/ZAPD/ZAPD/ZAnimation.h b/tools/ZAPD/ZAPD/ZAnimation.h index 61662099a7..e5b69d3ef8 100644 --- a/tools/ZAPD/ZAPD/ZAnimation.h +++ b/tools/ZAPD/ZAPD/ZAnimation.h @@ -23,7 +23,6 @@ public: ZAnimation(ZFile* nParent); - std::string GetSourceOutputCode(const std::string& prefix) override; ZResourceType GetResourceType() const override; protected: @@ -35,17 +34,21 @@ class ZNormalAnimation : public ZAnimation public: std::vector rotationValues; std::vector rotationIndices; - uint32_t rotationValuesSeg; - uint32_t rotationIndicesSeg; - int16_t limit; + segptr_t rotationValuesSeg = 0; + segptr_t rotationIndicesSeg = 0; + offset_t rotationValuesOffset = 0; + offset_t rotationIndicesOffset = 0; + int16_t limit = 0; ZNormalAnimation(ZFile* nParent); - std::string GetSourceOutputCode(const std::string& prefix) override; + void DeclareReferences(const std::string& prefix) override; + + std::string GetBodySourceCode() const override; + size_t GetRawDataSize() const override; std::string GetSourceTypeName() const override; -protected: void ParseRawData() override; }; @@ -56,11 +59,11 @@ public: ZLinkAnimation(ZFile* nParent); - std::string GetSourceOutputCode(const std::string& prefix) override; + std::string GetBodySourceCode() const override; + size_t GetRawDataSize() const override; std::string GetSourceTypeName() const override; -protected: void ParseRawData() override; }; @@ -115,16 +118,17 @@ protected: std::vector copyValuesArr; public: - ZCurveAnimation(); ZCurveAnimation(ZFile* nParent); void ParseXML(tinyxml2::XMLElement* reader) override; void ParseRawData() override; - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; void DeclareReferences(const std::string& prefix) override; + + std::string GetBodySourceCode() const override; + size_t GetRawDataSize() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + DeclarationAlignment GetDeclarationAlignment() const override; std::string GetSourceTypeName() const override; }; @@ -156,13 +160,10 @@ class ZLegacyAnimation : public ZAnimation public: ZLegacyAnimation(ZFile* nParent); - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; - void ParseRawData() override; void DeclareReferences(const std::string& prefix) override; - std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + std::string GetBodySourceCode() const override; std::string GetSourceTypeName() const override; diff --git a/tools/ZAPD/ZAPD/ZArray.cpp b/tools/ZAPD/ZAPD/ZArray.cpp index b30c217bbc..b1ba3a6693 100644 --- a/tools/ZAPD/ZAPD/ZArray.cpp +++ b/tools/ZAPD/ZAPD/ZArray.cpp @@ -1,5 +1,7 @@ #include "ZArray.h" + #include + #include "Globals.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -53,28 +55,56 @@ void ZArray::ParseXML(tinyxml2::XMLElement* reader) } } -std::string ZArray::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) +Declaration* ZArray::DeclareVar(const std::string& prefix, const std::string& bodyStr) { - std::string output = ""; + 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++) { - output += resList.at(i)->GetBodySourceCode(); + const auto& res = resList[i]; + output += "\t"; - if (i < arrayCnt - 1) + if (res->GetResourceType() == ZResourceType::Scalar || + res->GetResourceType() == ZResourceType::Vertex) + output += resList.at(i)->GetBodySourceCode(); + else + output += StringHelper::Sprintf("{ %s }", resList.at(i)->GetBodySourceCode().c_str()); + + if (i < arrayCnt - 1 || res->IsExternalResource()) output += ",\n"; } - if (parent != nullptr) - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(), - resList.at(0)->GetSourceTypeName(), name, arrayCnt, output); - - return ""; -} - -std::string ZArray::GetSourceTypeName() const -{ - return resList.at(0)->GetSourceTypeName(); + return output; } size_t ZArray::GetRawDataSize() const @@ -85,7 +115,21 @@ size_t ZArray::GetRawDataSize() const 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(); +} diff --git a/tools/ZAPD/ZAPD/ZArray.h b/tools/ZAPD/ZAPD/ZArray.h index 257a9dc585..46a04d7329 100644 --- a/tools/ZAPD/ZAPD/ZArray.h +++ b/tools/ZAPD/ZAPD/ZArray.h @@ -14,14 +14,16 @@ public: void ParseXML(tinyxml2::XMLElement* reader) override; - std::string GetSourceOutputCode(const std::string& prefix) override; - - std::string GetSourceTypeName() const 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; + protected: size_t arrayCnt; std::string childName; diff --git a/tools/ZAPD/ZAPD/ZBackground.cpp b/tools/ZAPD/ZAPD/ZBackground.cpp index ed2968c729..4125f239f3 100644 --- a/tools/ZAPD/ZAPD/ZBackground.cpp +++ b/tools/ZAPD/ZAPD/ZBackground.cpp @@ -1,4 +1,5 @@ #include "ZBackground.h" + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/File.h" @@ -10,21 +11,12 @@ REGISTER_ZFILENODE(Background, ZBackground); #define JPEG_MARKER 0xFFD8FFE0 #define MARKER_DQT 0xFFDB +#define MARKER_EOI 0xFFD9 ZBackground::ZBackground(ZFile* nParent) : ZResource(nParent) { } -ZBackground::ZBackground(const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent) - : ZResource(nParent) -{ - rawDataIndex = nRawDataIndex; - name = GetDefaultName(prefix.c_str(), rawDataIndex); - outName = name; - - ParseRawData(); -} - void ZBackground::ParseRawData() { ZResource::ParseRawData(); @@ -36,7 +28,7 @@ void ZBackground::ParseRawData() uint8_t val = rawData.at(rawDataIndex + i); data.push_back(val); - if (BitConverter::ToUInt16BE(rawData, rawDataIndex + i) == 0xFFD9) + if (BitConverter::ToUInt16BE(rawData, rawDataIndex + i) == MARKER_EOI) { data.push_back(rawData.at(rawDataIndex + i + 1)); break; @@ -60,12 +52,6 @@ void ZBackground::ParseBinaryFile(const std::string& inFolder, bool appendOutNam CheckValidJpeg(filepath.generic_string()); } -void ZBackground::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - DeclareVar("", ""); -} - void ZBackground::CheckValidJpeg(const std::string& filepath) { std::string filename = outName; @@ -132,16 +118,28 @@ size_t ZBackground::GetRawDataSize() const return Globals::Instance->cfg.bgScreenHeight * Globals::Instance->cfg.bgScreenWidth * 2; } -void ZBackground::DeclareVar(const std::string& prefix, const std::string& bodyStr) const +Declaration* ZBackground::DeclareVar(const std::string& prefix, + [[maybe_unused]] const std::string& bodyStr) { std::string auxName = name; + std::string auxOutName = outName; - if (name == "") - auxName = GetDefaultName(prefix, rawDataIndex); + if (auxName == "") + auxName = GetDefaultName(prefix); - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align8, GetRawDataSize(), - GetSourceTypeName(), auxName, "SCREEN_WIDTH * SCREEN_HEIGHT / 4", - bodyStr); + 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->staticConf = staticConf; + return decl; } bool ZBackground::IsExternalResource() const @@ -177,23 +175,9 @@ std::string ZBackground::GetBodySourceCode() const return bodyStr; } -std::string ZBackground::GetSourceOutputCode(const std::string& prefix) +std::string ZBackground::GetDefaultName(const std::string& prefix) const { - std::string bodyStr = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - - if (decl == nullptr) - DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - - return ""; -} - -std::string ZBackground::GetDefaultName(const std::string& prefix, uint32_t address) -{ - return StringHelper::Sprintf("%sBackground_%06X", prefix.c_str(), address); + return StringHelper::Sprintf("%sBackground_%06X", prefix.c_str(), rawDataIndex); } std::string ZBackground::GetSourceTypeName() const @@ -205,3 +189,8 @@ ZResourceType ZBackground::GetResourceType() const { return ZResourceType::Background; } + +DeclarationAlignment ZBackground::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align8; +} diff --git a/tools/ZAPD/ZAPD/ZBackground.h b/tools/ZAPD/ZAPD/ZBackground.h index 8071f84cc8..e3728bd984 100644 --- a/tools/ZAPD/ZAPD/ZBackground.h +++ b/tools/ZAPD/ZAPD/ZBackground.h @@ -11,25 +11,24 @@ protected: public: ZBackground(ZFile* nParent); - ZBackground(const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent); + + void ParseBinaryFile(const std::string& inFolder, bool appendOutName); void ParseRawData() override; - void ParseBinaryFile(const std::string& inFolder, bool appendOutName); - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; - void CheckValidJpeg(const std::string& filepath); + 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; - size_t GetRawDataSize() const override; - - void DeclareVar(const std::string& prefix, const std::string& bodyStr) const; + void Save(const fs::path& outFolder) override; bool IsExternalResource() const override; - std::string GetExternalExtension() const override; - void Save(const fs::path& outFolder) override; - std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; - static std::string GetDefaultName(const std::string& prefix, uint32_t address); - 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); }; diff --git a/tools/ZAPD/ZAPD/ZBlob.cpp b/tools/ZAPD/ZAPD/ZBlob.cpp index 3c187336d3..c1f0788206 100644 --- a/tools/ZAPD/ZAPD/ZBlob.cpp +++ b/tools/ZAPD/ZAPD/ZBlob.cpp @@ -1,12 +1,12 @@ #include "ZBlob.h" + +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/File.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" #include "ZFile.h" -using namespace tinyxml2; - REGISTER_ZFILENODE(Blob, ZBlob); ZBlob::ZBlob(ZFile* nParent) : ZResource(nParent) @@ -14,19 +14,6 @@ ZBlob::ZBlob(ZFile* nParent) : ZResource(nParent) RegisterRequiredAttribute("Size"); } -// Build Source File Mode -ZBlob* ZBlob::BuildFromXML(XMLElement* reader, const std::string& inFolder, bool readFile) -{ - ZBlob* blob = new ZBlob(nullptr); - - blob->ParseXML(reader); - - if (readFile) - blob->blobData = File::ReadAllBytes(inFolder + "/" + blob->name + ".bin"); - - return blob; -} - ZBlob* ZBlob::FromFile(const std::string& filePath) { ZBlob* blob = new ZBlob(nullptr); @@ -49,14 +36,38 @@ void ZBlob::ParseRawData() parent->GetRawData().begin() + rawDataIndex + blobSize); } -std::string ZBlob::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) +Declaration* ZBlob::DeclareVar(const std::string& prefix, + [[maybe_unused]] const std::string& bodyStr) { - std::string sourceOutput = ""; + 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 += " "; + sourceOutput += "\t"; sourceOutput += StringHelper::Sprintf("0x%02X, ", blobData[i]); diff --git a/tools/ZAPD/ZAPD/ZBlob.h b/tools/ZAPD/ZAPD/ZBlob.h index 2f8d315729..86623b5119 100644 --- a/tools/ZAPD/ZAPD/ZBlob.h +++ b/tools/ZAPD/ZAPD/ZBlob.h @@ -8,13 +8,14 @@ class ZBlob : public ZResource public: ZBlob(ZFile* nParent); - static ZBlob* BuildFromXML(tinyxml2::XMLElement* reader, const std::string& inFolder, - bool readFile); static ZBlob* FromFile(const std::string& filePath); void ParseXML(tinyxml2::XMLElement* reader) override; void ParseRawData() override; - std::string GetSourceOutputCode(const std::string& prefix) override; + + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; + std::string GetBodySourceCode() const override; + std::string GetSourceOutputHeader(const std::string& prefix) override; void Save(const fs::path& outFolder) override; diff --git a/tools/ZAPD/ZAPD/ZCollision.cpp b/tools/ZAPD/ZAPD/ZCollision.cpp index eb37d71e3e..f9c0bf7d62 100644 --- a/tools/ZAPD/ZAPD/ZCollision.cpp +++ b/tools/ZAPD/ZAPD/ZCollision.cpp @@ -1,6 +1,8 @@ #include "ZCollision.h" -#include + +#include #include + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -13,9 +15,6 @@ ZCollisionHeader::ZCollisionHeader(ZFile* nParent) : ZResource(nParent) ZCollisionHeader::~ZCollisionHeader() { - for (WaterBoxHeader* waterBox : waterBoxes) - delete waterBox; - delete camData; } @@ -51,8 +50,16 @@ void ZCollisionHeader::ParseRawData() vertices.reserve(numVerts); polygons.reserve(numPolygons); + uint32_t currentPtr = vtxSegmentOffset; + for (uint16_t i = 0; i < numVerts; i++) - vertices.push_back(VertexEntry(rawData, vtxSegmentOffset + (i * 6))); + { + ZVector vec(parent); + vec.ExtractFromBinary(currentPtr, ZScalarType::ZSCALAR_S16, 3); + + currentPtr += vec.GetRawDataSize(); + vertices.push_back(vec); + } for (uint16_t i = 0; i < numPolygons; i++) polygons.push_back(PolygonEntry(rawData, polySegmentOffset + (i * 16))); @@ -74,34 +81,38 @@ void ZCollisionHeader::ParseRawData() polyTypeDefSegmentOffset, polygonTypes.size()); for (uint16_t i = 0; i < numWaterBoxes; i++) - waterBoxes.push_back(new WaterBoxHeader( + waterBoxes.push_back(WaterBoxHeader( rawData, waterBoxSegmentOffset + (i * (Globals::Instance->game == ZGame::OOT_SW97 ? 12 : 16)))); +} - std::string declaration = ""; +void ZCollisionHeader::DeclareReferences(const std::string& prefix) +{ + std::string declaration; + std::string auxName = name; + + if (name == "") + auxName = GetDefaultName(prefix); if (waterBoxes.size() > 0) { for (size_t i = 0; i < waterBoxes.size(); i++) { - declaration += StringHelper::Sprintf("\t{ %i, %i, %i, %i, %i, 0x%08X },", - waterBoxes[i]->xMin, waterBoxes[i]->ySurface, - waterBoxes[i]->zMin, waterBoxes[i]->xLength, - waterBoxes[i]->zLength, waterBoxes[i]->properties); + declaration += + StringHelper::Sprintf("\t{ %s },", waterBoxes[i].GetBodySourceCode().c_str()); if (i + 1 < waterBoxes.size()) declaration += "\n"; } - } - if (waterBoxAddress != 0) parent->AddDeclarationArray( - waterBoxSegmentOffset, DeclarationAlignment::None, 16 * waterBoxes.size(), "WaterBox", - StringHelper::Sprintf("%s_waterBoxes_%06X", name.c_str(), waterBoxSegmentOffset), 0, - declaration); + waterBoxSegmentOffset, DeclarationAlignment::Align4, 16 * waterBoxes.size(), "WaterBox", + StringHelper::Sprintf("%s_waterBoxes_%06X", auxName.c_str(), waterBoxSegmentOffset), + waterBoxes.size(), declaration); + } if (polygons.size() > 0) { - declaration = ""; + declaration.clear(); for (size_t i = 0; i < polygons.size(); i++) { @@ -113,17 +124,13 @@ void ZCollisionHeader::ParseRawData() declaration += "\n"; } - if (polyAddress != 0) - { - parent->AddDeclarationArray( - polySegmentOffset, DeclarationAlignment::None, polygons.size() * 16, - "CollisionPoly", - StringHelper::Sprintf("%s_polygons_%08X", name.c_str(), polySegmentOffset), 0, - declaration); - } + parent->AddDeclarationArray( + polySegmentOffset, DeclarationAlignment::Align4, polygons.size() * 16, "CollisionPoly", + StringHelper::Sprintf("%s_polygons_%08X", auxName.c_str(), polySegmentOffset), + polygons.size(), declaration); } - declaration = ""; + declaration.clear(); for (size_t i = 0; i < polygonTypes.size(); i++) { declaration += StringHelper::Sprintf("\t{ 0x%08lX, 0x%08lX },", polygonTypes[i] >> 32, @@ -135,57 +142,71 @@ void ZCollisionHeader::ParseRawData() if (polyTypeDefAddress != 0) parent->AddDeclarationArray( - polyTypeDefSegmentOffset, DeclarationAlignment::None, polygonTypes.size() * 8, + polyTypeDefSegmentOffset, DeclarationAlignment::Align4, polygonTypes.size() * 8, "SurfaceType", - StringHelper::Sprintf("%s_surfaceType_%08X", name.c_str(), polyTypeDefSegmentOffset), 0, - declaration); + StringHelper::Sprintf("%s_surfaceType_%08X", auxName.c_str(), polyTypeDefSegmentOffset), + polygonTypes.size(), declaration); - declaration = ""; + declaration.clear(); if (vertices.size() > 0) { - declaration = ""; + declaration.clear(); for (size_t i = 0; i < vertices.size(); i++) { - declaration += StringHelper::Sprintf("\t{ %6i, %6i, %6i },", vertices[i].x, - vertices[i].y, vertices[i].z); + 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, DeclarationAlignment::None, vertices.size() * 6, "Vec3s", - StringHelper::Sprintf("%s_vtx_%08X", name.c_str(), vtxSegmentOffset), 0, - declaration); - - declaration = ""; + vtxSegmentOffset, first.GetDeclarationAlignment(), + vertices.size() * first.GetRawDataSize(), first.GetSourceTypeName(), + StringHelper::Sprintf("%s_vtx_%08X", auxName.c_str(), vtxSegmentOffset), + vertices.size(), declaration); } +} - declaration = ""; - char waterBoxStr[2048]; - - if (waterBoxAddress != 0) - sprintf(waterBoxStr, "%s_waterBoxes_%06X", name.c_str(), waterBoxSegmentOffset); - else - sprintf(waterBoxStr, "NULL"); +std::string ZCollisionHeader::GetBodySourceCode() const +{ + std::string declaration; declaration += "\n"; - declaration += StringHelper::Sprintf(" { %i, %i, %i },\n { %i, %i, %i },\n", absMinX, - absMinY, absMinZ, absMaxX, absMaxY, absMaxZ); + declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMinX, absMinY, absMinZ); + declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMaxX, absMaxY, absMaxZ); - declaration += StringHelper::Sprintf( - " %i,\n %s_vtx_%08X,\n %i,\n %s_polygons_%08X,\n %s_surfaceType_%08X,\n " - "%s_camDataList_%08X,\n %i,\n %s\n", - numVerts, name.c_str(), vtxSegmentOffset, numPolygons, name.c_str(), polySegmentOffset, - name.c_str(), polyTypeDefSegmentOffset, name.c_str(), camDataSegmentOffset, numWaterBoxes, - waterBoxStr); + std::string vtxName; + Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName); + declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str()); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, DeclarationPadding::Pad16, 44, - GetSourceTypeName(), name, declaration); + std::string polyName; + Globals::Instance->GetSegmentedPtrName(polyAddress, parent, "CollisionPoly", polyName); + declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numPolygons, polyName.c_str()); + + std::string surfaceName; + Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName); + declaration += StringHelper::Sprintf("\t%s,\n", surfaceName.c_str()); + + std::string camName; + Globals::Instance->GetSegmentedPtrName(camDataAddress, parent, "CamData", camName); + declaration += StringHelper::Sprintf("\t%s,\n", camName.c_str()); + + std::string waterBoxName; + Globals::Instance->GetSegmentedPtrName(waterBoxAddress, parent, "WaterBox", waterBoxName); + declaration += StringHelper::Sprintf("\t%i,\n\t%s\n", numWaterBoxes, waterBoxName.c_str()); + + return declaration; +} + +std::string ZCollisionHeader::GetDefaultName(const std::string& prefix) const +{ + return StringHelper::Sprintf("%sCol_%06X", prefix.c_str(), rawDataIndex); } std::string ZCollisionHeader::GetSourceTypeName() const @@ -217,15 +238,6 @@ PolygonEntry::PolygonEntry(const std::vector& rawData, uint32_t rawData d = BitConverter::ToUInt16BE(data, rawDataIndex + 14); } -VertexEntry::VertexEntry(const std::vector& rawData, uint32_t rawDataIndex) -{ - const uint8_t* data = rawData.data(); - - x = BitConverter::ToInt16BE(data, rawDataIndex + 0); - y = BitConverter::ToInt16BE(data, rawDataIndex + 2); - z = BitConverter::ToInt16BE(data, rawDataIndex + 4); -} - WaterBoxHeader::WaterBoxHeader(const std::vector& rawData, uint32_t rawDataIndex) { const uint8_t* data = rawData.data(); @@ -242,12 +254,18 @@ WaterBoxHeader::WaterBoxHeader(const std::vector& rawData, uint32_t raw properties = BitConverter::ToInt32BE(data, rawDataIndex + 12); } +std::string WaterBoxHeader::GetBodySourceCode() const +{ + return StringHelper::Sprintf("%i, %i, %i, %i, %i, 0x%08X", xMin, ySurface, zMin, xLength, + zLength, properties); +} + CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, const std::vector& rawData, uint32_t rawDataIndex, uint32_t polyTypeDefSegmentOffset, [[maybe_unused]] uint32_t polygonTypesCnt) { - std::string declaration = ""; + std::string declaration; // Parse CameraDataEntries int32_t numElements = (polyTypeDefSegmentOffset - rawDataIndex) / 8; @@ -299,7 +317,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, } parent->AddDeclarationArray( - rawDataIndex, DeclarationAlignment::None, entries.size() * 8, "CamData", + rawDataIndex, DeclarationAlignment::Align4, entries.size() * 8, "CamData", StringHelper::Sprintf("%s_camDataList_%08X", prefix.c_str(), rawDataIndex), entries.size(), declaration); @@ -307,7 +325,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, if (numDataTotal > 0) { - declaration = ""; + declaration.clear(); for (uint32_t i = 0; i < numDataTotal; i++) { CameraPositionData* data = @@ -322,12 +340,21 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, int32_t cameraPosDataIndex = GETSEGOFFSET(cameraPosDataSeg); uint32_t entrySize = numDataTotal * 0x6; parent->AddDeclarationArray( - cameraPosDataIndex, DeclarationAlignment::None, entrySize, "Vec3s", + cameraPosDataIndex, DeclarationAlignment::Align4, entrySize, "Vec3s", StringHelper::Sprintf("%s_camPosData_%08X", prefix.c_str(), cameraPosDataIndex), numDataTotal, declaration); } } +CameraDataList::~CameraDataList() +{ + for (auto entry : entries) + delete entry; + + for (auto camPosData : cameraPositionData) + delete camPosData; +} + CameraPositionData::CameraPositionData(const std::vector& rawData, uint32_t rawDataIndex) { x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0); diff --git a/tools/ZAPD/ZAPD/ZCollision.h b/tools/ZAPD/ZAPD/ZCollision.h index 29420646a3..d0325bfb95 100644 --- a/tools/ZAPD/ZAPD/ZCollision.h +++ b/tools/ZAPD/ZAPD/ZCollision.h @@ -3,6 +3,7 @@ #include "ZFile.h" #include "ZResource.h" #include "ZRoom/ZRoom.h" +#include "ZVector.h" class PolygonEntry { @@ -14,17 +15,14 @@ public: PolygonEntry(const std::vector& rawData, uint32_t rawDataIndex); }; -class VertexEntry -{ -public: - int16_t x, y, z; - - VertexEntry(const std::vector& rawData, uint32_t rawDataIndex); -}; - class WaterBoxHeader { public: + WaterBoxHeader(const std::vector& rawData, uint32_t rawDataIndex); + + std::string GetBodySourceCode() const; + +protected: int16_t xMin; int16_t ySurface; int16_t zMin; @@ -32,8 +30,6 @@ public: int16_t zLength; int16_t pad; int32_t properties; - - WaterBoxHeader(const std::vector& rawData, uint32_t rawDataIndex); }; class CameraPositionData @@ -61,6 +57,7 @@ public: CameraDataList(ZFile* parent, const std::string& prefix, const std::vector& rawData, uint32_t rawDataIndex, uint32_t polyTypeDefSegmentOffset, uint32_t polygonTypesCnt); + ~CameraDataList(); }; class ZCollisionHeader : public ZResource @@ -81,16 +78,20 @@ public: uint32_t vtxSegmentOffset, polySegmentOffset, polyTypeDefSegmentOffset, camDataSegmentOffset, waterBoxSegmentOffset; - std::vector vertices; + std::vector vertices; std::vector polygons; std::vector polygonTypes; - std::vector waterBoxes; - CameraDataList* camData; + std::vector 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; diff --git a/tools/ZAPD/ZAPD/ZCutscene.cpp b/tools/ZAPD/ZAPD/ZCutscene.cpp index 5db169077a..237481079f 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.cpp +++ b/tools/ZAPD/ZAPD/ZCutscene.cpp @@ -87,8 +87,7 @@ CutsceneCommandSceneTransFX::~CutsceneCommandSceneTransFX() std::string ZCutscene::GetBodySourceCode() const { - std::string output = ""; - size_t size = 0; + std::string output; uint32_t curPtr = 0; output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame); @@ -98,7 +97,6 @@ std::string ZCutscene::GetBodySourceCode() const CutsceneCommand* cmd = commands[i]; output += " " + cmd->GenerateSourceCode(curPtr); curPtr += cmd->GetCommandSize(); - size += cmd->GetCommandSize(); } output += StringHelper::Sprintf(" CS_END(),\n", commands.size(), endFrame); @@ -106,32 +104,6 @@ std::string ZCutscene::GetBodySourceCode() const return output; } -std::string ZCutscene::GetSourceOutputCode(const std::string& prefix) -{ - std::string bodyStr = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - - if (decl == nullptr) - DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - - return ""; -} - -void ZCutscene::DeclareVar(const std::string& prefix, const std::string& bodyStr) const -{ - std::string auxName = name; - - if (auxName == "") - auxName = StringHelper::Sprintf("%sCutsceneData0x%06X", prefix.c_str(), rawDataIndex); - - parent->AddDeclarationArray(getSegmentOffset(), DeclarationAlignment::Align4, - DeclarationPadding::Pad16, GetRawDataSize(), GetSourceTypeName(), - auxName, 0, bodyStr); -} - size_t ZCutscene::GetRawDataSize() const { size_t size = 0; @@ -152,12 +124,6 @@ size_t ZCutscene::GetRawDataSize() const return size; } -void ZCutscene::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - DeclareVar(parent->GetName(), ""); -} - void ZCutscene::ParseRawData() { ZResource::ParseRawData(); @@ -526,10 +492,10 @@ std::string CutsceneCommandSetCameraPos::GetCName() std::string CutsceneCommandSetCameraPos::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; - std::string listStr = ""; - std::string posStr = ""; + std::string listStr; + std::string posStr; if (commandID == (int32_t)CutsceneCommands::SetCameraFocus) { @@ -617,7 +583,7 @@ std::string CutsceneCommandFadeBGM::GetCName() std::string CutsceneCommandFadeBGM::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_FADE_BGM_LIST(%i),\n", entries.size()); @@ -670,7 +636,7 @@ CutsceneCommandPlayBGM::CutsceneCommandPlayBGM(const std::vector& rawDa std::string CutsceneCommandPlayBGM::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_PLAY_BGM_LIST(%i),\n", entries.size()); @@ -713,7 +679,7 @@ CutsceneCommandStopBGM::CutsceneCommandStopBGM(const std::vector& rawDa std::string CutsceneCommandStopBGM::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_STOP_BGM_LIST(%i),\n", entries.size()); @@ -771,7 +737,7 @@ CutsceneCommandEnvLighting::CutsceneCommandEnvLighting(const std::vector& raw std::string CutsceneCommandUnknown9::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_CMD_09_LIST(%i),\n", entries.size()); @@ -885,7 +851,7 @@ CutsceneCommandUnknown::CutsceneCommandUnknown(const std::vector& rawDa std::string CutsceneCommandUnknown::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_UNK_DATA_LIST(0x%02X, %i),\n", commandID, entries.size()); @@ -943,7 +909,7 @@ std::string CutsceneCommandDayTime::GetCName() std::string CutsceneCommandDayTime::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_TIME_LIST(%i),\n", entries.size()); @@ -994,7 +960,7 @@ std::string CutsceneCommandTextbox::GetCName() std::string CutsceneCommandTextbox::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_TEXT_LIST(%i),\n", entries.size()); @@ -1060,8 +1026,8 @@ CutsceneCommandActorAction::CutsceneCommandActorAction(const std::vectoraction, entries[i]->startFrame, entries[i]->endFrame, entries[i]->rotX, entries[i]->rotY, entries[i]->rotZ, entries[i]->startPosX, entries[i]->startPosY, entries[i]->startPosZ, entries[i]->endPosX, entries[i]->endPosY, @@ -1117,7 +1083,7 @@ std::string CutsceneCommandTerminator::GetCName() std::string CutsceneCommandTerminator::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_TERMINATOR(0x%04X, %i, %i),\n", base, startFrame, endFrame); @@ -1139,7 +1105,7 @@ CutsceneCommandEnd::CutsceneCommandEnd(const std::vector& rawData, uint std::string CutsceneCommandEnd::GenerateSourceCode([[maybe_unused]] uint32_t baseAddress) { - std::string result = ""; + std::string result; result += StringHelper::Sprintf("CS_END(),\n"); @@ -1193,7 +1159,7 @@ CutsceneCommandSpecialAction::CutsceneCommandSpecialAction(const std::vectorAddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), + GetSourceTypeName(), auxName, 0, bodyStr); + decl->staticConf = staticConf; + return decl; +} + std::string ZCutsceneBase::GetSourceTypeName() const { return "CutsceneData"; diff --git a/tools/ZAPD/ZAPD/ZCutscene.h b/tools/ZAPD/ZAPD/ZCutscene.h index 19389a90dd..cbb6a78b02 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.h +++ b/tools/ZAPD/ZAPD/ZCutscene.h @@ -413,13 +413,9 @@ class ZCutsceneBase : public ZResource public: ZCutsceneBase(ZFile* nParent); - std::string GetBodySourceCode() const override = 0; - - virtual void DeclareVar(const std::string& prefix, const std::string& bodyStr) const = 0; + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetSourceTypeName() const override; - - virtual uint32_t getSegmentOffset() const = 0; }; class ZCutscene : public ZCutsceneBase @@ -431,17 +427,13 @@ public: void ParseRawData() override; std::string GetBodySourceCode() const override; - void DeclareVar(const std::string& prefix, const std::string& bodyStr) const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + size_t GetRawDataSize() const override; - CutsceneCommands GetCommandFromID(int32_t id); - uint32_t getSegmentOffset() const override { return rawDataIndex; } ZResourceType GetResourceType() const override; - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; + CutsceneCommands GetCommandFromID(int32_t id); -protected: int32_t numCommands; int32_t endFrame; std::vector commands; diff --git a/tools/ZAPD/ZAPD/ZCutsceneMM.cpp b/tools/ZAPD/ZAPD/ZCutsceneMM.cpp index 4d3c2af513..d0208bc070 100644 --- a/tools/ZAPD/ZAPD/ZCutsceneMM.cpp +++ b/tools/ZAPD/ZAPD/ZCutsceneMM.cpp @@ -1,4 +1,5 @@ #include "ZCutsceneMM.h" + #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -14,7 +15,7 @@ ZCutsceneMM::~ZCutsceneMM() std::string ZCutsceneMM::GetBodySourceCode() const { - std::string output = ""; + std::string output; output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),", numCommands, endFrame); @@ -22,51 +23,19 @@ std::string ZCutsceneMM::GetBodySourceCode() const { if ((i % 4) == 0) output += "\n "; - output += StringHelper::Sprintf("0x%08X,", data[i]); + output += StringHelper::Sprintf("0x%08X, ", data[i]); } return output; } -std::string ZCutsceneMM::GetSourceOutputCode(const std::string& prefix) -{ - std::string bodyStr = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - - if (decl == nullptr) - DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - - return ""; -} - -void ZCutsceneMM::DeclareVar(const std::string& prefix, const std::string& bodyStr) const -{ - std::string auxName = name; - - if (auxName == "") - auxName = StringHelper::Sprintf("%sCutsceneData0x%06X", prefix.c_str(), rawDataIndex); - - parent->AddDeclarationArray(getSegmentOffset(), DeclarationAlignment::Align4, GetRawDataSize(), - "s32", auxName, 0, bodyStr); -} - size_t ZCutsceneMM::GetRawDataSize() const { return 8 + data.size() * 4; } -void ZCutsceneMM::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - DeclareVar(parent->GetName(), ""); -} - void ZCutsceneMM::ParseRawData() { - segmentOffset = rawDataIndex; const auto& rawData = parent->GetRawData(); numCommands = BitConverter::ToInt32BE(rawData, rawDataIndex + 0); diff --git a/tools/ZAPD/ZAPD/ZCutsceneMM.h b/tools/ZAPD/ZAPD/ZCutsceneMM.h index 91a40e8430..41b7de37f3 100644 --- a/tools/ZAPD/ZAPD/ZCutsceneMM.h +++ b/tools/ZAPD/ZAPD/ZCutsceneMM.h @@ -10,22 +10,16 @@ class ZCutsceneMM : public ZCutsceneBase { public: - uint32_t segmentOffset; - ZCutsceneMM(ZFile* nParent); virtual ~ZCutsceneMM(); std::string GetBodySourceCode() const override; - void DeclareVar(const std::string& prefix, const std::string& bodyStr) const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + size_t GetRawDataSize() const override; - uint32_t getSegmentOffset() const override { return segmentOffset; } void ParseRawData() override; ZResourceType GetResourceType() const override; - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; - protected: int32_t numCommands; int32_t endFrame; diff --git a/tools/ZAPD/ZAPD/ZDisplayList.cpp b/tools/ZAPD/ZAPD/ZDisplayList.cpp index 24353d4375..63c5684228 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.cpp +++ b/tools/ZAPD/ZAPD/ZDisplayList.cpp @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "Globals.h" #include "OutputFormatter.h" @@ -17,8 +17,6 @@ REGISTER_ZFILENODE(DList, ZDisplayList); ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent) { - defines = ""; - sceneSegName = ""; lastTexWidth = 0; lastTexHeight = 0; lastTexAddr = 0; @@ -45,21 +43,30 @@ void ZDisplayList::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDat rawDataIndex = nRawDataIndex; ParseXML(reader); - int32_t rawDataSize = ZDisplayList::GetDListLength( - parent->GetRawData(), rawDataIndex, - Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); - numInstructions = rawDataSize / 8; - ParseRawData(); + // Don't parse raw data of external files + if (parent->GetMode() != ZFileMode::ExternalFile) + { + int32_t rawDataSize = ZDisplayList::GetDListLength( + parent->GetRawData(), rawDataIndex, + Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + numInstructions = rawDataSize / 8; + ParseRawData(); + } - DeclareVar("", ""); + Declaration* decl = DeclareVar("", ""); + decl->declaredInXml = true; } -ZDisplayList::ZDisplayList(uint32_t nRawDataIndex, int32_t rawDataSize, ZFile* nParent) - : ZDisplayList(nParent) +void ZDisplayList::ExtractFromBinary(uint32_t nRawDataIndex, int32_t rawDataSize) { rawDataIndex = nRawDataIndex; - name = StringHelper::Sprintf("DL_%06X", rawDataIndex); + name = GetDefaultName(parent->GetName()); numInstructions = rawDataSize / 8; + + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); } @@ -80,14 +87,20 @@ Declaration* ZDisplayList::DeclareVar([[maybe_unused]] const std::string& prefix const std::string& bodyStr) { Declaration* decl = - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align8, GetRawDataSize(), - GetSourceTypeName(), name, 0, bodyStr); + parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), + GetSourceTypeName(), name, numInstructions, bodyStr); decl->isExternal = true; + decl->staticConf = staticConf; return decl; } -void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, std::string prefix, - char* line) +std::string ZDisplayList::GetDefaultName(const std::string& prefix) const +{ + return StringHelper::Sprintf("%sDL_%06X", prefix.c_str(), rawDataIndex); +} + +void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, + const std::string& prefix, char* line) { switch (opcode) { @@ -259,9 +272,10 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, st sprintf(line, "gsSPBranchLessZraw(%sDlist0x%06X, 0x%02X, 0x%02X),", prefix.c_str(), h & 0x00FFFFFF, (a / 5) | (b / 2), z); - ZDisplayList* nList = new ZDisplayList( - h & 0x00FFFFFF, GetDListLength(parent->GetRawData(), h & 0x00FFFFFF, dListType), - parent); + ZDisplayList* nList = new ZDisplayList(parent); + nList->ExtractFromBinary( + h & 0x00FFFFFF, GetDListLength(parent->GetRawData(), h & 0x00FFFFFF, dListType)); + nList->SetName(nList->GetDefaultName(prefix)); otherDLists.push_back(nList); i++; @@ -277,7 +291,8 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, st } } -void ZDisplayList::ParseF3DEX(F3DEXOpcode opcode, uint64_t data, std::string prefix, char* line) +void ZDisplayList::ParseF3DEX(F3DEXOpcode opcode, uint64_t data, const std::string& prefix, + char* line) { switch (opcode) { @@ -428,7 +443,7 @@ int32_t ZDisplayList::GetDListLength(const std::vector& rawData, uint32 size_t rawDataSize = rawData.size(); while (true) { - if (ptr > rawDataSize) + if (ptr >= rawDataSize) { throw std::runtime_error(StringHelper::Sprintf( "%s: Fatal error.\n" @@ -470,7 +485,7 @@ bool ZDisplayList::SequenceCheck(std::vector sequence, int32_t sta } int32_t ZDisplayList::OptimizationChecks(int32_t startIndex, std::string& output, - std::string prefix) + const std::string& prefix) { int32_t result = -1; @@ -483,13 +498,8 @@ int32_t ZDisplayList::OptimizationChecks(int32_t startIndex, std::string& output } int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std::string& output, - std::string prefix) + [[maybe_unused]] const std::string& prefix) { - if (Globals::Instance->lastScene == nullptr) - { - return -1; - } - std::vector sequence = {F3DZEXOpcode::G_SETTIMG, F3DZEXOpcode::G_SETTILE, F3DZEXOpcode::G_RDPLOADSYNC, F3DZEXOpcode::G_LOADBLOCK, F3DZEXOpcode::G_RDPPIPESYNC, F3DZEXOpcode::G_SETTILE, @@ -507,7 +517,7 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std uint32_t texAddr, tmem, rtile, fmt, siz, sizB, width, height, width2, height2, pal, cms, cmt, masks, maskt, shifts, shiftt; - std::string texStr = ""; + std::string texStr; // gsDPSetTextureImage { @@ -523,17 +533,7 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std lastTexSeg = segmentNumber; - ZFile* auxParent = parent; - if (parent->segment != segmentNumber && Globals::Instance->HasSegment(segmentNumber)) - auxParent = Globals::Instance->segmentRefFiles.at(segmentNumber); - - Declaration* decl = auxParent->GetDeclaration(texAddr); - if (Globals::Instance->HasSegment(segmentNumber) && decl != nullptr) - texStr = decl->varName; - else if (lastTexture != nullptr) - texStr = lastTexture->GetName(); - else - texStr = auxParent->GetDeclarationPtrName(data & 0xFFFFFFFF); + Globals::Instance->GetSegmentedPtrName(data & 0xFFFFFFFF, parent, "", texStr); } // gsDPSetTile @@ -602,12 +602,12 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std height2 = (vvv >> 2) + 1; } - std::string fmtTbl[] = {"G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", + const char* fmtTbl[] = {"G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I"}; - std::string sizTbl[] = {"G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b"}; + const char* sizTbl[] = {"G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b"}; // output += StringHelper::Sprintf("gsDPLoadTextureBlock(%s, %s, %s, %i, %i, %i, %i, %i, %i, - // %i, %i, %i),", texStr.c_str(), fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), width, height, + // %i, %i, %i),", texStr.c_str(), fmtTbl[fmt], sizTbl[siz].c_str(), width, height, // pal, cms, cmt, masks, maskt, shifts, shiftt); if (siz == 2 && sizB == 0) @@ -615,26 +615,26 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std if (tmem != 0) output += StringHelper::Sprintf( "gsDPLoadMultiBlock_4b(%s, %i, %i, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", - texStr.c_str(), tmem, rtile, fmtTbl[fmt].c_str(), width2, height2, pal, cms, - cmt, masks, maskt, shifts, shiftt); + texStr.c_str(), tmem, rtile, fmtTbl[fmt], width2, height2, pal, cms, cmt, masks, + maskt, shifts, shiftt); else output += StringHelper::Sprintf( "gsDPLoadTextureBlock_4b(%s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", - texStr.c_str(), fmtTbl[fmt].c_str(), width2, height2, pal, cms, cmt, masks, - maskt, shifts, shiftt); + texStr.c_str(), fmtTbl[fmt], width2, height2, pal, cms, cmt, masks, maskt, + shifts, shiftt); } else if (siz == 2 && sizB != 0) { if (tmem != 0) output += StringHelper::Sprintf( "gsDPLoadMultiBlock(%s, %i, %i, %s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", - texStr.c_str(), tmem, rtile, fmtTbl[fmt].c_str(), sizTbl[sizB].c_str(), width2, - height2, pal, cms, cmt, masks, maskt, shifts, shiftt); + texStr.c_str(), tmem, rtile, fmtTbl[fmt], sizTbl[sizB], width2, height2, pal, + cms, cmt, masks, maskt, shifts, shiftt); else output += StringHelper::Sprintf( "gsDPLoadTextureBlock(%s, %s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", - texStr.c_str(), fmtTbl[fmt].c_str(), sizTbl[sizB].c_str(), width2, height2, pal, - cms, cmt, masks, maskt, shifts, shiftt); + texStr.c_str(), fmtTbl[fmt], sizTbl[sizB], width2, height2, pal, cms, cmt, + masks, maskt, shifts, shiftt); } else { @@ -647,15 +647,15 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std lastTexSiz = (F3DZEXTexSizes)siz; lastTexLoaded = true; - TextureGenCheck(prefix); + TextureGenCheck(); return -1; } output += StringHelper::Sprintf( "gsDPLoadMultiBlock(%s, %i, %i, %s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i),", - texStr.c_str(), tmem, rtile, fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), width, - height, pal, cms, cmt, masks, maskt, shifts, shiftt); + texStr.c_str(), tmem, rtile, fmtTbl[fmt], sizTbl[siz], width, height, pal, cms, cmt, + masks, maskt, shifts, shiftt); } lastTexAddr = texAddr; @@ -665,7 +665,7 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std lastTexSiz = (F3DZEXTexSizes)siz; lastTexLoaded = true; - TextureGenCheck(prefix); + TextureGenCheck(); return (int32_t)sequence.size(); } @@ -673,7 +673,7 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std return -1; } -void ZDisplayList::Opcode_G_DL(uint64_t data, std::string prefix, char* line) +void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* line) { int32_t pp = (data & 0x00FF000000000000) >> 56; int32_t segNum = GETSEGNUM(data); @@ -713,9 +713,10 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, std::string prefix, char* line) } else { - ZDisplayList* nList = new ZDisplayList( - GETSEGOFFSET(data), GetDListLength(parent->GetRawData(), GETSEGOFFSET(data), dListType), - parent); + ZDisplayList* nList = new ZDisplayList(parent); + nList->ExtractFromBinary(GETSEGOFFSET(data), GetDListLength(parent->GetRawData(), + GETSEGOFFSET(data), dListType)); + nList->SetName(nList->GetDefaultName(prefix)); otherDLists.push_back(nList); } @@ -780,10 +781,10 @@ void ZDisplayList::Opcode_G_MTX(uint64_t data, char* line) else pp = (data & 0x000000FF00000000) >> 32; - std::string matrixRef = ""; + std::string matrixRef; - if (Globals::Instance->symbolMap.find(mm) != Globals::Instance->symbolMap.end()) - matrixRef = StringHelper::Sprintf("&%s", Globals::Instance->symbolMap[mm].c_str()); + if (Globals::Instance->cfg.symbolMap.find(mm) != Globals::Instance->cfg.symbolMap.end()) + matrixRef = StringHelper::Sprintf("&%s", Globals::Instance->cfg.symbolMap[mm].c_str()); else matrixRef = StringHelper::Sprintf("0x%08X", mm); @@ -832,29 +833,28 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, char* line) StringHelper::Sprintf("0x%08X", segmented), ""); return; } - references.push_back(vtxAddr); + references.push_back(data); { uint32_t currentPtr = Seg2Filespace(data, parent->baseAddress); + Declaration* decl; // Check for vertex intersections from other display lists // TODO: These two could probably be condenced to one... - if (parent->GetDeclarationRanged(vtxAddr + (nn * 16)) != nullptr) + decl = parent->GetDeclarationRanged(vtxAddr + (nn * 16)); + if (decl != nullptr) { - // Declaration* decl = parent->GetDeclarationRanged(vtxAddr + (nn * 16)); - uint32_t addr = parent->GetDeclarationRangedAddress(vtxAddr + (nn * 16)); - int32_t diff = addr - vtxAddr; + int32_t diff = decl->address - vtxAddr; if (diff > 0) nn = diff / 16; else nn = 0; } - if (parent->GetDeclarationRanged(vtxAddr) != nullptr) + decl = parent->GetDeclarationRanged(vtxAddr); + if (decl != nullptr) { - // Declaration* decl = parent->GetDeclarationRanged(vtxAddr); - uint32_t addr = parent->GetDeclarationRangedAddress(vtxAddr); - int32_t diff = addr - vtxAddr; + int32_t diff = decl->address - vtxAddr; if (diff > 0) nn = diff / 16; else @@ -869,8 +869,7 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, char* line) for (int32_t i = 0; i < nn; i++) { ZVtx vtx(parent); - vtx.SetRawDataIndex(currentPtr); - vtx.ParseRawData(); + vtx.ExtractFromFile(currentPtr); vtxList.push_back(vtx); currentPtr += 16; @@ -899,13 +898,13 @@ void ZDisplayList::Opcode_G_TEXTURE(uint64_t data, char* line) nnnnnnn == 1 ? "G_ON" : "G_OFF"); } -void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, std::string prefix, char* line) +void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, char* line) { int32_t __ = (data & 0x00FF000000000000) >> 48; int32_t www = (data & 0x00000FFF00000000) >> 32; - std::string fmtTbl[] = {"G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", + const char* fmtTbl[] = {"G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I"}; - std::string sizTbl[] = {"G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b"}; + const char* sizTbl[] = {"G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b"}; uint32_t fmt = (__ & 0xE0) >> 5; uint32_t siz = (__ & 0x18) >> 3; @@ -913,7 +912,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, std::string prefix, char* lin if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) printf("TextureGenCheck G_SETTIMG\n"); - TextureGenCheck(prefix); // HOTSPOT + TextureGenCheck(); // HOTSPOT lastTexFmt = (F3DZEXTexFormats)fmt; lastTexSiz = (F3DZEXTexSizes)siz; @@ -945,14 +944,15 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, std::string prefix, char* lin sprintf(texStr, "0x%08lX", data & 0xFFFFFFFF); } - sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt].c_str(), - sizTbl[siz].c_str(), www + 1, texStr); + sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt], sizTbl[siz], www + 1, + texStr); } else { - sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %sTex_%06lX),", fmtTbl[fmt].c_str(), - sizTbl[siz].c_str(), www + 1, Globals::Instance->lastScene->GetName().c_str(), - GETSEGOFFSET(data)); + std::string texName; + Globals::Instance->GetSegmentedPtrName(data, parent, "", texName); + sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt], sizTbl[siz], www + 1, + texName.c_str()); } } @@ -976,21 +976,21 @@ void ZDisplayList::Opcode_G_SETTILE(uint64_t data, char* line) int32_t bbbb = (data & 0b0000000000000000000000000000000000000000000000000000000011110000) >> 4; int32_t uuuu = (data & 0b0000000000000000000000000000000000000000000000000000000000001111); - std::string fmtTbl[] = {"G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", + const char* fmtTbl[] = {"G_IM_FMT_RGBA", "G_IM_FMT_YUV", "G_IM_FMT_CI", "G_IM_FMT_IA", "G_IM_FMT_I"}; - std::string sizTbl[] = {"G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b"}; + const char* sizTbl[] = {"G_IM_SIZ_4b", "G_IM_SIZ_8b", "G_IM_SIZ_16b", "G_IM_SIZ_32b"}; if (fff == (int32_t)F3DZEXTexFormats::G_IM_FMT_CI) lastCISiz = (F3DZEXTexSizes)ii; lastTexSizTest = (F3DZEXTexSizes)ii; - sprintf(line, "gsDPSetTile(%s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),", - fmtTbl[fff].c_str(), sizTbl[ii].c_str(), nnnnnnnnn, mmmmmmmmm, ttt, pppp, cc, aaaa, - ssss, dd, bbbb, uuuu); + sprintf(line, "gsDPSetTile(%s, %s, %i, %i, %i, %i, %i, %i, %i, %i, %i, %i),", fmtTbl[fff], + sizTbl[ii], nnnnnnnnn, mmmmmmmmm, ttt, pppp, cc, aaaa, ssss, dd, bbbb, uuuu); } -void ZDisplayList::Opcode_G_SETTILESIZE(uint64_t data, std::string prefix, char* line) +void ZDisplayList::Opcode_G_SETTILESIZE(uint64_t data, [[maybe_unused]] const std::string& prefix, + char* line) { int32_t sss = (data & 0x00FFF00000000000) >> 44; int32_t ttt = (data & 0x00000FFF00000000) >> 32; @@ -1024,7 +1024,7 @@ void ZDisplayList::Opcode_G_SETTILESIZE(uint64_t data, std::string prefix, char* if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) printf("TextureGenCheck G_SETTILESIZE\n"); - TextureGenCheck(prefix); + TextureGenCheck(); sprintf(line, "gsDPSetTileSize(%i, %i, %i, %i, %i),", i, sss, ttt, uuu, vvv); } @@ -1061,13 +1061,13 @@ void ZDisplayList::Opcode_G_SETCOMBINE(uint64_t data, char* line) int32_t ab1 = (data & 0b00000000000000000000000000000000000000000000000000000000111000) >> 3; int32_t ad1 = (data & 0b00000000000000000000000000000000000000000000000000000000000111) >> 0; - std::string modesA[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", + const char* modesA[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "NOISE", "0", "9", "10", "11", "12", "13", "14", "0"}; - std::string modesB[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", + const char* modesB[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "CENTER", "K4", "8", "9", "10", "11", "12", "13", "14", "0"}; - std::string modesC[] = {"COMBINED", + const char* modesC[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", @@ -1099,21 +1099,20 @@ void ZDisplayList::Opcode_G_SETCOMBINE(uint64_t data, char* line) "29", "30", "0"}; - std::string modesD[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", + const char* modesD[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0"}; - std::string modes2[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", + const char* modes2[] = {"COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0"}; - std::string modes2C[] = {"LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE", + const char* modes2C[] = {"LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "PRIM_LOD_FRAC", "0"}; sprintf(line, "gsDPSetCombineLERP(%s, %s, %s, %s, %s, %s, %s, %s,\n %s, %s, " "%s, %s, %s, %s, %s, %s),", - modesA[a0].c_str(), modesB[b0].c_str(), modesC[c0].c_str(), modesD[d0].c_str(), - modes2[aa0].c_str(), modes2[ab0].c_str(), modes2C[ac0].c_str(), modes2[ad0].c_str(), - modesA[a1].c_str(), modesB[b1].c_str(), modesC[c1].c_str(), modesD[d1].c_str(), - modes2[aa1].c_str(), modes2[ab1].c_str(), modes2C[ac1].c_str(), modes2[ad1].c_str()); + modesA[a0], modesB[b0], modesC[c0], modesD[d0], modes2[aa0], modes2[ab0], modes2C[ac0], + modes2[ad0], modesA[a1], modesB[b1], modesC[c1], modesD[d1], modes2[aa1], modes2[ab1], + modes2C[ac1], modes2[ad1]); } void ZDisplayList::Opcode_G_SETPRIMCOLOR(uint64_t data, char* line) @@ -1258,7 +1257,7 @@ void ZDisplayList::Opcode_G_SETOTHERMODE_L(uint64_t data, char* line) G_RM_VISCVG2, G_RM_OPA_CI2}; - std::map str = { + std::map str = { {G_RM_FOG_SHADE_A, "G_RM_FOG_SHADE_A"}, {G_RM_FOG_PRIM_A, "G_RM_FOG_PRIM_A"}, {G_RM_PASS, "G_RM_PASS"}, @@ -1384,60 +1383,49 @@ void ZDisplayList::Opcode_G_SETOTHERMODE_L(uint64_t data, char* line) if (mode2Str == "") { - int32_t remainingFlags = mode2; - if (mode2 & AA_EN) { mode2Str += "AA_EN | "; - remainingFlags ^= AA_EN; } if (mode2 & Z_CMP) { mode2Str += "Z_CMP | "; - remainingFlags ^= Z_CMP; } if (mode2 & Z_UPD) { mode2Str += "Z_UPD | "; - remainingFlags ^= Z_UPD; } if (mode2 & IM_RD) { mode2Str += "IM_RD | "; - remainingFlags ^= IM_RD; } if (mode2 & CLR_ON_CVG) { mode2Str += "CLR_ON_CVG | "; - remainingFlags ^= CLR_ON_CVG; } if (mode2 & CVG_DST_CLAMP) { mode2Str += "CVG_DST_CLAMP | "; - remainingFlags ^= CVG_DST_CLAMP; } if (mode2 & CVG_DST_WRAP) { mode2Str += "CVG_DST_WRAP | "; - remainingFlags ^= CVG_DST_WRAP; } if (mode2 & CVG_DST_FULL) { mode2Str += "CVG_DST_FULL | "; - remainingFlags ^= CVG_DST_FULL; } if (mode2 & CVG_DST_SAVE) { mode2Str += "CVG_DST_SAVE | "; - remainingFlags ^= CVG_DST_SAVE; } int32_t zMode = mode2 & 0xC00; @@ -1445,35 +1433,29 @@ void ZDisplayList::Opcode_G_SETOTHERMODE_L(uint64_t data, char* line) if (zMode == ZMODE_INTER) { mode2Str += "ZMODE_INTER | "; - remainingFlags ^= ZMODE_INTER; } else if (zMode == ZMODE_XLU) { mode2Str += "ZMODE_XLU | "; - remainingFlags ^= ZMODE_XLU; } else if (zMode == ZMODE_DEC) { mode2Str += "ZMODE_DEC | "; - remainingFlags ^= ZMODE_DEC; } if (mode2 & CVG_X_ALPHA) { mode2Str += "CVG_X_ALPHA | "; - remainingFlags ^= CVG_X_ALPHA; } if (mode2 & ALPHA_CVG_SEL) { mode2Str += "ALPHA_CVG_SEL | "; - remainingFlags ^= ALPHA_CVG_SEL; } if (mode2 & FORCE_BL) { mode2Str += "FORCE_BL | "; - remainingFlags ^= FORCE_BL; } int32_t bp = (mode2 >> 28) & 0b11; @@ -1503,14 +1485,15 @@ void ZDisplayList::Opcode_G_SETOTHERMODE_H(uint64_t data, char* line) if (sft == 14) // G_MDSFT_TEXTLUT { - std::string types[] = {"G_TT_NONE", "G_TT_NONE", "G_TT_RGBA16", "G_TT_IA16"}; - sprintf(line, "gsDPSetTextureLUT(%s),", types[dd >> 14].c_str()); + const char* types[] = {"G_TT_NONE", "G_TT_NONE", "G_TT_RGBA16", "G_TT_IA16"}; + sprintf(line, "gsDPSetTextureLUT(%s),", types[dd >> 14]); } else sprintf(line, "gsSPSetOtherMode(0xE3, %i, %i, 0x%08X),", sft, nn + 1, dd); } -void ZDisplayList::Opcode_G_LOADTLUT(uint64_t data, std::string prefix, char* line) +void ZDisplayList::Opcode_G_LOADTLUT(uint64_t data, [[maybe_unused]] const std::string& prefix, + char* line) { int32_t t = (data & 0x0000000007000000) >> 24; int32_t ccc = (data & 0x00000000003FF000) >> 14; @@ -1524,19 +1507,19 @@ void ZDisplayList::Opcode_G_LOADTLUT(uint64_t data, std::string prefix, char* li if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) printf("TextureGenCheck G_LOADTLUT (lastCISiz: %i)\n", (uint32_t)lastCISiz); - TextureGenCheck(prefix); + TextureGenCheck(); sprintf(line, "gsDPLoadTLUTCmd(%i, %i),", t, ccc); } -void ZDisplayList::Opcode_G_ENDDL(std::string prefix, char* line) +void ZDisplayList::Opcode_G_ENDDL([[maybe_unused]] const std::string& prefix, char* line) { sprintf(line, "gsSPEndDisplayList(),"); if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) printf("TextureGenCheck G_ENDDL\n"); - TextureGenCheck(prefix); + TextureGenCheck(); } std::string ZDisplayList::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) @@ -1599,24 +1582,17 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count) { ZDisplayList* self = static_cast(gfxd_udata_get()); uint32_t vtxOffset = Seg2Filespace(seg, self->parent->baseAddress); - std::string vtxName = ""; - // Probably an external asset we are unable to track - if (!Globals::Instance->HasSegment(GETSEGNUM(seg))) + if (GETSEGNUM(seg) == self->parent->segment) { - vtxName = StringHelper::Sprintf("0x%08X", seg); - } - else - { - self->references.push_back(vtxOffset); + Declaration* decl; // Check for vertex intersections from other display lists // TODO: These two could probably be condenced to one... - if (self->parent->GetDeclarationRanged(vtxOffset + (count * 16)) != nullptr) + decl = self->parent->GetDeclarationRanged(vtxOffset + (count * 16)); + if (decl != nullptr) { - // Declaration* decl = self->parent->GetDeclarationRanged(vtxOffset + (count * 16)); - uint32_t addr = self->parent->GetDeclarationRangedAddress(vtxOffset + (count * 16)); - int32_t diff = addr - vtxOffset; + int32_t diff = decl->address - vtxOffset; if (diff > 0) count = diff / 16; @@ -1624,11 +1600,10 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count) count = 0; } - if (self->parent->GetDeclarationRanged(vtxOffset) != nullptr) + decl = self->parent->GetDeclarationRanged(vtxOffset); + if (decl != nullptr) { - // Declaration* decl = self->parent->GetDeclarationRanged(vtxOffset); - uint32_t addr = self->parent->GetDeclarationRangedAddress(vtxOffset); - int32_t diff = addr - vtxOffset; + int32_t diff = decl->address - vtxOffset; if (diff > 0) count = diff / 16; @@ -1645,19 +1620,17 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count) for (int32_t i = 0; i < count; i++) { ZVtx vtx(self->parent); - vtx.SetRawDataIndex(currentPtr); - vtx.ParseRawData(); + vtx.ExtractFromFile(currentPtr); vtxList.push_back(vtx); currentPtr += 16; } self->vertices[vtxOffset] = vtxList; } - - vtxName = "@r"; } - gfxd_puts(vtxName.c_str()); + self->references.push_back(seg); + gfxd_puts("@r"); return 1; } @@ -1667,7 +1640,6 @@ static int32_t GfxdCallback_Texture(segptr_t seg, int32_t fmt, int32_t siz, int3 { ZDisplayList* self = static_cast(gfxd_udata_get()); uint32_t texOffset = Seg2Filespace(seg, self->parent->baseAddress); - uint32_t texSegNum = GETSEGNUM(seg); self->lastTexWidth = width; self->lastTexHeight = height; @@ -1678,21 +1650,10 @@ static int32_t GfxdCallback_Texture(segptr_t seg, int32_t fmt, int32_t siz, int3 self->lastTexLoaded = true; self->lastTexIsPalette = false; - self->TextureGenCheck(self->curPrefix); + self->TextureGenCheck(); - std::string texName = ""; - - ZFile* auxParent = self->parent; - if (self->parent->segment != texSegNum && Globals::Instance->HasSegment(texSegNum)) - auxParent = Globals::Instance->segmentRefFiles.at(texSegNum); - - Declaration* decl = auxParent->GetDeclaration(texOffset); - if (Globals::Instance->HasSegment(texSegNum) && decl != nullptr) - texName = decl->varName; - else if (self->lastTexture != nullptr) - texName = self->lastTexture->GetName(); - else - texName = auxParent->GetDeclarationPtrName(seg); + std::string texName; + Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", texName); gfxd_puts(texName.c_str()); @@ -1703,7 +1664,6 @@ static int32_t GfxdCallback_Palette(uint32_t seg, [[maybe_unused]] int32_t idx, { ZDisplayList* self = static_cast(gfxd_udata_get()); uint32_t palOffset = Seg2Filespace(seg, self->parent->baseAddress); - uint32_t palSegNum = GETSEGNUM(seg); self->lastTexWidth = sqrt(count); self->lastTexHeight = sqrt(count); @@ -1714,21 +1674,10 @@ static int32_t GfxdCallback_Palette(uint32_t seg, [[maybe_unused]] int32_t idx, self->lastTexLoaded = true; self->lastTexIsPalette = true; - self->TextureGenCheck(self->curPrefix); + self->TextureGenCheck(); - std::string palName = ""; - - ZFile* auxParent = self->parent; - if (self->parent->segment != palSegNum && Globals::Instance->HasSegment(palSegNum)) - auxParent = Globals::Instance->segmentRefFiles.at(palSegNum); - - Declaration* decl = auxParent->GetDeclaration(palOffset); - if (Globals::Instance->HasSegment(palSegNum) && decl != nullptr) - palName = decl->varName; - else if (self->lastTlut != nullptr) - palName = self->lastTlut->GetName(); - else - palName = auxParent->GetDeclarationPtrName(seg); + std::string palName; + Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", palName); gfxd_puts(palName.c_str()); @@ -1741,22 +1690,20 @@ static int32_t GfxdCallback_DisplayList(uint32_t seg) uint32_t dListOffset = GETSEGOFFSET(seg); uint32_t dListSegNum = GETSEGNUM(seg); - if ((dListSegNum <= 6) && Globals::Instance->HasSegment(dListSegNum)) + std::string dListName = ""; + bool addressFound = Globals::Instance->GetSegmentedPtrName(seg, self->parent, "Gfx", dListName); + + if (!addressFound && self->parent->segment == dListSegNum) { - ZDisplayList* newDList = new ZDisplayList( + ZDisplayList* newDList = new ZDisplayList(self->parent); + newDList->ExtractFromBinary( dListOffset, - self->GetDListLength(self->parent->GetRawData(), dListOffset, self->dListType), - self->parent); - newDList->parent = self->parent; + self->GetDListLength(self->parent->GetRawData(), dListOffset, self->dListType)); + newDList->SetName(newDList->GetDefaultName(self->parent->GetName())); self->otherDLists.push_back(newDList); + dListName = newDList->GetName(); } - ZFile* auxParent = self->parent; - if (self->parent->segment != dListSegNum && Globals::Instance->HasSegment(dListSegNum)) - auxParent = Globals::Instance->segmentRefFiles.at(dListSegNum); - - std::string dListName = auxParent->GetDeclarationPtrName(seg); - gfxd_puts(dListName.c_str()); return 1; @@ -1764,30 +1711,26 @@ static int32_t GfxdCallback_DisplayList(uint32_t seg) static int32_t GfxdCallback_Matrix(uint32_t seg) { - std::string mtxName = ""; + std::string mtxName; ZDisplayList* self = static_cast(gfxd_udata_get()); - if (Globals::Instance->symbolMap.find(seg) != Globals::Instance->symbolMap.end()) - mtxName = StringHelper::Sprintf("&%s", Globals::Instance->symbolMap[seg].c_str()); - else if (Globals::Instance->HasSegment(GETSEGNUM(seg))) + bool addressFound = Globals::Instance->GetSegmentedPtrName(seg, self->parent, "Mtx", mtxName); + if (!addressFound && GETSEGNUM(seg) == self->parent->segment) { Declaration* decl = self->parent->GetDeclaration(Seg2Filespace(seg, self->parent->baseAddress)); if (decl == nullptr) { - ZMtx mtx(self->GetName(), Seg2Filespace(seg, self->parent->baseAddress), self->parent); + ZMtx mtx(self->parent); + mtx.SetName(mtx.GetDefaultName(self->GetName())); + mtx.ExtractFromFile(Seg2Filespace(seg, self->parent->baseAddress)); + mtx.DeclareVar(self->GetName(), ""); mtx.GetSourceOutputCode(self->GetName()); self->mtxList.push_back(mtx); mtxName = "&" + mtx.GetName(); } - else - { - mtxName = "&" + decl->varName; - } } - else - mtxName = StringHelper::Sprintf("0x%08X", seg); gfxd_puts(mtxName.c_str()); @@ -1796,7 +1739,7 @@ static int32_t GfxdCallback_Matrix(uint32_t seg) std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) { - std::string sourceOutput = ""; + std::string sourceOutput; if (Globals::Instance->useLegacyZDList) sourceOutput += ProcessLegacy(prefix); @@ -1829,46 +1772,29 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) } } - if (Globals::Instance->lastScene == nullptr) // TODO: Bit of a hack but it works for now... - parent->defines += defines; - // Generate Vertex Declarations for (auto& item : vertices) { - std::string declaration = ""; + std::string declaration; - uint32_t curAddr = item.first; + offset_t curAddr = item.first; + auto& firstVtx = item.second.at(0); for (auto vtx : item.second) { declaration += StringHelper::Sprintf("\t%s,\n", vtx.GetBodySourceCode().c_str()); - - curAddr += vtx.GetRawDataSize(); } - vtxDeclarations[item.first] = declaration; - - if (parent != nullptr) - { - parent->AddDeclarationArray(item.first, DeclarationAlignment::None, - item.second.size() * 16, "static Vtx", - StringHelper::Sprintf("%sVtx_%06X", prefix.c_str(), - item.first, item.second.size()), - item.second.size(), declaration); - } + Declaration* decl = parent->AddDeclarationArray( + curAddr, firstVtx.GetDeclarationAlignment(), + item.second.size() * firstVtx.GetRawDataSize(), firstVtx.GetSourceTypeName(), + firstVtx.GetDefaultName(name), item.second.size(), declaration); + decl->isExternal = true; } } - if (Globals::Instance->lastScene != nullptr) - defines += Globals::Instance->lastScene->extDefines; - - if (parent != nullptr) - { - Declaration* decl = DeclareVar("", sourceOutput); - decl->references = references; - // return ""; - // return sourceOutput; - } + Declaration* decl = DeclareVar("", sourceOutput); + decl->references = references; // Iterate through our vertex lists, connect intersecting lists. if (vertices.size() > 0) @@ -1897,9 +1823,6 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) } } - if (Globals::Instance->lastScene == nullptr) // TODO: Bit of a hack but it works for now... - parent->defines += defines; - // Generate Vertex Declarations std::vector vtxKeys; @@ -1911,27 +1834,16 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) { auto& item = vertices[vtxKeys[i]]; - std::string declaration = ""; - - int32_t curAddr = vtxKeys[i]; + std::string declaration; for (auto& vtx : item) - { - if (curAddr != vtxKeys[i]) - declaration += "\n"; - - declaration += StringHelper::Sprintf("\t%s,", vtx.GetBodySourceCode().c_str()); - - curAddr += 16; - } + declaration += StringHelper::Sprintf("\t%s,\n", vtx.GetBodySourceCode().c_str()); // 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. declaration += "\n"; - vtxDeclarations[vtxKeys[i]] = declaration; - if (parent != nullptr) { std::string vtxName; @@ -1945,12 +1857,8 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) auto filepath = Globals::Instance->outputPath / vtxName; std::string incStr = StringHelper::Sprintf("%s.%s.inc", filepath.c_str(), "vtx"); - parent->AddDeclarationArray(vtxKeys[i], DeclarationAlignment::None, - item.size() * 16, "static Vtx", vtxName, item.size(), - declaration); - Declaration* vtxDecl = parent->AddDeclarationIncludeArray( - vtxKeys[i], incStr, item.size() * 16, "static Vtx", vtxName, item.size()); + vtxKeys[i], incStr, item.size() * 16, "Vtx", vtxName, item.size()); vtxDecl->isExternal = true; } } @@ -1965,7 +1873,7 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) std::string ZDisplayList::ProcessLegacy(const std::string& prefix) { char line[4096]; - std::string sourceOutput = ""; + std::string sourceOutput; for (size_t i = 0; i < instructions.size(); i++) { @@ -2005,9 +1913,9 @@ std::string ZDisplayList::ProcessLegacy(const std::string& prefix) return sourceOutput; } -std::string ZDisplayList::ProcessGfxDis(const std::string& prefix) +std::string ZDisplayList::ProcessGfxDis([[maybe_unused]] const std::string& prefix) { - std::string sourceOutput = ""; + std::string sourceOutput; OutputFormatter outputformatter; int32_t dListSize = instructions.size() * sizeof(instructions[0]); @@ -2032,7 +1940,6 @@ std::string ZDisplayList::ProcessGfxDis(const std::string& prefix) else gfxd_target(gfxd_f3dex); - this->curPrefix = prefix; gfxd_udata_set(this); gfxd_execute(); // generate display list sourceOutput += outputformatter.GetOutput(); // write formatted display list @@ -2040,10 +1947,10 @@ std::string ZDisplayList::ProcessGfxDis(const std::string& prefix) return sourceOutput; } -void ZDisplayList::TextureGenCheck(std::string prefix) +void ZDisplayList::TextureGenCheck() { - if (TextureGenCheck(parent, prefix, lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg, - lastTexFmt, lastTexSiz, lastTexLoaded, lastTexIsPalette, this)) + if (TextureGenCheck(lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg, lastTexFmt, + lastTexSiz, lastTexLoaded, lastTexIsPalette, this)) { lastTexAddr = 0; lastTexLoaded = false; @@ -2051,12 +1958,11 @@ void ZDisplayList::TextureGenCheck(std::string prefix) } } -bool ZDisplayList::TextureGenCheck(ZFile* parent, [[maybe_unused]] std::string prefix, - int32_t texWidth, int32_t texHeight, uint32_t texAddr, +bool ZDisplayList::TextureGenCheck(int32_t texWidth, int32_t texHeight, uint32_t texAddr, uint32_t texSeg, F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz, bool texLoaded, bool texIsPalette, ZDisplayList* self) { - int32_t segmentNumber = GETSEGNUM(texSeg); + uint32_t segmentNumber = GETSEGNUM(texSeg); if (!texIsPalette) self->lastTexture = nullptr; @@ -2070,58 +1976,53 @@ bool ZDisplayList::TextureGenCheck(ZFile* parent, [[maybe_unused]] std::string p if ((texSeg != 0 || texAddr != 0) && texWidth > 0 && texHeight > 0 && texLoaded && Globals::Instance->HasSegment(segmentNumber)) { - if (segmentNumber != SEGMENT_SCENE) + ZFile* auxParent = nullptr; + if (segmentNumber == self->parent->segment) { - if (texAddr < parent->GetRawData().size()) + auxParent = self->parent; + } + else + { + // Try to find a non-external file (ie, one we are actually extracting) + // which has the same segment number we are looking for. + for (auto& otherFile : Globals::Instance->cfg.segmentRefFiles[segmentNumber]) { - ZTexture* tex = parent->GetTextureResource(texAddr); - if (tex != nullptr) - tex->isPalette = texIsPalette; - else + if (!otherFile->isExternalFile) { - tex = new ZTexture(parent); - tex->FromBinary(texAddr, texWidth, texHeight, - TexFormatToTexType(texFmt, texSiz), texIsPalette); - parent->AddTextureResource(texAddr, tex); + auxParent = otherFile; } - - if (!texIsPalette) - self->lastTexture = tex; - else - self->lastTlut = tex; - - return true; } } - else if (Globals::Instance->lastScene != nullptr) + + if (auxParent == nullptr) { - if (Globals::Instance->lastScene->parent->GetDeclaration(texAddr) == nullptr) + // We can't declare the texture in any of the files we are extracting. + return false; + } + + if (auxParent->IsOffsetInFileRange(texAddr)) + { + ZTexture* tex = auxParent->GetTextureResource(texAddr); + if (tex != nullptr) + tex->isPalette = texIsPalette; + else { - ZTexture* tex = Globals::Instance->lastScene->parent->GetTextureResource(texAddr); - if (tex != nullptr) - tex->isPalette = texIsPalette; - else - { - tex = new ZTexture(Globals::Instance->lastScene->parent); - tex->FromBinary(texAddr, texWidth, texHeight, - TexFormatToTexType(texFmt, texSiz), texIsPalette); - - Globals::Instance->lastScene->parent->AddTextureResource(texAddr, tex); - } - - if (!texIsPalette) - self->lastTexture = tex; - else - self->lastTlut = tex; - - auto filepath = Globals::Instance->outputPath / - Path::GetFileNameWithoutExtension(tex->GetName()); - auto filename = StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), - tex->GetExternalExtension().c_str()); - Globals::Instance->lastScene->parent->AddDeclarationIncludeArray( - texAddr, filename, tex->GetRawDataSize(), tex->GetSourceTypeName(), - tex->GetName(), 0); + tex = new ZTexture(auxParent); + tex->ExtractFromBinary(texAddr, texWidth, texHeight, + TexFormatToTexType(texFmt, texSiz), texIsPalette); + auxParent->AddTextureResource(texAddr, tex); } + + if (!texIsPalette) + self->lastTexture = tex; + else + self->lastTlut = tex; + + if (auxParent->GetDeclaration(texAddr) == nullptr) + { + tex->DeclareVar(self->GetName(), ""); + } + return true; } } @@ -2196,3 +2097,8 @@ size_t ZDisplayList::GetRawDataSize() const { return instructions.size() * 8; } + +DeclarationAlignment ZDisplayList::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align8; +} diff --git a/tools/ZAPD/ZAPD/ZDisplayList.h b/tools/ZAPD/ZAPD/ZDisplayList.h index 4098b97128..d538666750 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.h +++ b/tools/ZAPD/ZAPD/ZDisplayList.h @@ -288,14 +288,15 @@ class ZDisplayList : public ZResource protected: static TextureType TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSizes siz); - void ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, std::string prefix, char* line); - void ParseF3DEX(F3DEXOpcode opcode, uint64_t data, std::string prefix, char* line); + 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 sequence, int32_t startIndex); - int32_t OptimizationChecks(int32_t startIndex, std::string& output, std::string prefix); + int32_t OptimizationChecks(int32_t startIndex, std::string& output, const std::string& prefix); int32_t OptimizationCheck_LoadTextureBlock(int32_t startIndex, std::string& output, - std::string prefix); + const std::string& prefix); // int32_t OptimizationCheck_LoadMultiBlock(int32_t startIndex, std::string& output, std::string // prefix); @@ -303,7 +304,7 @@ protected: void Opcode_F3DEX_G_SETOTHERMODE_L(uint64_t data, char* line); // Shared Opcodes between F3DZEX and F3DEX - void Opcode_G_DL(uint64_t data, std::string prefix, char* line); + 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); @@ -311,21 +312,19 @@ protected: 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, std::string prefix, 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, std::string prefix, 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, std::string prefix, char* line); - void Opcode_G_ENDDL(std::string prefix, 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::string sceneSegName; std::vector instructions; - std::string curPrefix; int32_t lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg; F3DZEXTexFormats lastTexFmt; @@ -336,36 +335,34 @@ public: DListType dListType; std::map> vertices; - std::map vtxDeclarations; std::vector otherDLists; ZTexture* lastTexture = nullptr; ZTexture* lastTlut = nullptr; - std::vector references; - - std::string defines; // Hack for special cases where vertex arrays intersect... + std::vector references; std::vector mtxList; ZDisplayList(ZFile* nParent); - ZDisplayList(uint32_t rawDataIndex, int32_t rawDataSize, 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); + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; + std::string GetDefaultName(const std::string& prefix) const override; - void TextureGenCheck(std::string prefix); - static bool TextureGenCheck(ZFile* parent, std::string prefix, int32_t texWidth, - int32_t texHeight, uint32_t texAddr, uint32_t texSeg, - F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz, bool texLoaded, - bool texIsPalette, ZDisplayList* self); + 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& rawData, uint32_t rawDataIndex, DListType dListType); size_t GetRawDataSize() const override; + DeclarationAlignment GetDeclarationAlignment() const override; std::string GetSourceOutputHeader(const std::string& prefix) override; std::string GetSourceOutputCode(const std::string& prefix) override; std::string ProcessLegacy(const std::string& prefix); diff --git a/tools/ZAPD/ZAPD/ZFile.cpp b/tools/ZAPD/ZAPD/ZFile.cpp index 3709771b8e..7cbfeba886 100644 --- a/tools/ZAPD/ZAPD/ZFile.cpp +++ b/tools/ZAPD/ZAPD/ZFile.cpp @@ -1,14 +1,18 @@ #include "ZFile.h" -#include -#include + #include #include +#include #include + #include "Globals.h" #include "OutputFormatter.h" +#include "Utils/BinaryWriter.h" #include "Utils/Directory.h" #include "Utils/File.h" +#include "Utils/MemoryStream.h" #include "Utils/Path.h" +#include "Utils/StringHelper.h" #include "ZAnimation.h" #include "ZArray.h" #include "ZBackground.h" @@ -26,8 +30,6 @@ #include "ZVector.h" #include "ZVtx.h" -using namespace tinyxml2; - ZFile::ZFile() { resources = std::vector(); @@ -39,13 +41,15 @@ ZFile::ZFile() rangeEnd = 0xFFFFFFFF; } -ZFile::ZFile(std::string nName) : ZFile() +ZFile::ZFile(const fs::path& nOutPath, const std::string& nName) : ZFile() { name = nName; + outName = nName; + outputPath = nOutPath; } -ZFile::ZFile(ZFileMode mode, tinyxml2::XMLElement* reader, const fs::path& nBasePath, - std::string filename, const fs::path& nXmlFilePath, bool placeholderMode) +ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBasePath, + const fs::path& nOutPath, const std::string& filename, const fs::path& nXmlFilePath) : ZFile() { xmlFilePath = nXmlFilePath; @@ -54,8 +58,16 @@ ZFile::ZFile(ZFileMode mode, tinyxml2::XMLElement* reader, const fs::path& nBase else basePath = nBasePath; - ParseXML(mode, reader, filename, placeholderMode); - DeclareResourceSubReferences(); + if (nOutPath == "") + outputPath = Directory::GetCurrentDirectory(); + else + outputPath = nOutPath; + + mode = nMode; + + ParseXML(reader, filename); + if (mode != ZFileMode::ExternalFile) + DeclareResourceSubReferences(); } ZFile::~ZFile() @@ -69,11 +81,17 @@ ZFile::~ZFile() { delete d.second; } + + for (auto sym : symbolResources) + { + delete sym.second; + } } -void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, - [[maybe_unused]] bool placeholderMode) +void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) { + assert(mode != ZFileMode::Invalid); + if (filename == "") name = reader->Attribute("Name"); else @@ -89,11 +107,11 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, const char* gameStr = reader->Attribute("Game"); if (reader->Attribute("Game") != nullptr) { - if (std::string(gameStr) == "MM") + if (std::string_view(gameStr) == "MM") Globals::Instance->game = ZGame::MM_RETAIL; - else if (std::string(gameStr) == "SW97" || std::string(gameStr) == "OOTSW97") + else if (std::string_view(gameStr) == "SW97" || std::string_view(gameStr) == "OOTSW97") Globals::Instance->game = ZGame::OOT_SW97; - else if (std::string(gameStr) == "OOT") + else if (std::string_view(gameStr) == "OOT") Globals::Instance->game = ZGame::OOT_RETAIL; else throw std::runtime_error( @@ -109,28 +127,67 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, if (reader->Attribute("RangeEnd") != nullptr) rangeEnd = StringHelper::StrToL(reader->Attribute("RangeEnd"), 16); - // Commented until ZArray doesn't use a ZFile to parse it's contents anymore. - /* - if (reader->Attribute("Segment") == nullptr) - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n" - "\t Missing 'Segment' attribute in File node. \n", - name.c_str())); - */ + if (rangeStart > rangeEnd) + throw std::runtime_error("Error: RangeStart must be before than RangeEnd."); - if (reader->Attribute("Segment") != nullptr) + const char* segmentXml = reader->Attribute("Segment"); + if (segmentXml != nullptr) { - segment = StringHelper::StrToL(reader->Attribute("Segment"), 10); - Globals::Instance->AddSegment(segment, this); + if (!StringHelper::HasOnlyDigits(segmentXml)) + { + throw std::runtime_error(StringHelper::Sprintf( + "error: Invalid segment value '%s': must be a decimal between 0 and 15 inclusive", + segmentXml)); + } + + segment = StringHelper::StrToL(segmentXml, 10); + if (segment > 15) + { + if (segment == 128) + { +#ifdef DEPRECATION_ON + fprintf(stderr, "warning: segment 128 is deprecated.\n\tRemove " + "'Segment=\"128\"' from the xml to use virtual addresses\n"); +#endif + } + else + { + throw std::runtime_error( + StringHelper::Sprintf("error: invalid segment value '%s': must be a decimal " + "number between 0 and 15 inclusive", + segmentXml)); + } + } + } + Globals::Instance->AddSegment(segment, this); + + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + { + if (segment == 0x80) + { + printf("File '%s' using virtual addresses.\n", GetName().c_str()); + } + else + { + printf("File '%s' using segment %X.\n", GetName().c_str(), segment); + } } - if (mode == ZFileMode::Extract) + if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile) { if (!File::Exists((basePath / name).string())) throw std::runtime_error( StringHelper::Sprintf("Error! File %s does not exist.", (basePath / name).c_str())); rawData = File::ReadAllBytes((basePath / name).string()); + + /* + * TODO: In OoT repo ovl_Boss_Sst has a wrong RangeEnd (0xAD40 instead of 0xAD70), + * so uncommenting the following produces wrong behavior. + * If somebody fixes that in OoT repo, uncomment this. I'm too tired of fixing XMLs. + */ + // if (reader->Attribute("RangeEnd") == nullptr) + // rangeEnd = rawData.size(); } std::unordered_set nameSet; @@ -140,16 +197,13 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, auto nodeMap = *GetNodeMap(); uint32_t rawDataIndex = 0; - for (XMLElement* child = reader->FirstChildElement(); child != nullptr; + for (tinyxml2::XMLElement* child = reader->FirstChildElement(); child != nullptr; child = child->NextSiblingElement()) { const char* nameXml = child->Attribute("Name"); const char* outNameXml = child->Attribute("OutName"); const char* offsetXml = child->Attribute("Offset"); - if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) - printf("%s: 0x%06X\n", nameXml, rawDataIndex); - // Check for repeated attributes. if (offsetXml != nullptr) { @@ -172,6 +226,10 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, throw std::runtime_error( StringHelper::Sprintf("Error no offset specified for %s", nameXml)); } + + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + printf("%s: 0x%06X\n", nameXml, rawDataIndex); + if (outNameXml != nullptr) { if (outNameSet.find(outNameXml) != outNameSet.end()) @@ -199,18 +257,27 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, { ZResource* nRes = nodeMap[nodeName](this); - if (mode == ZFileMode::Extract) + if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile) nRes->ExtractFromXML(child, rawDataIndex); - auto resType = nRes->GetResourceType(); - if (resType == ZResourceType::Texture) + switch (nRes->GetResourceType()) + { + case ZResourceType::Texture: AddTextureResource(rawDataIndex, static_cast(nRes)); - else - resources.push_back(nRes); + break; + + case ZResourceType::Symbol: + AddSymbolResource(rawDataIndex, static_cast(nRes)); + break; + + default: + AddResource(nRes); + break; + } rawDataIndex += nRes->GetRawDataSize(); } - else if (std::string(child->Name()) == "File") + else if (std::string_view(child->Name()) == "File") { throw std::runtime_error(StringHelper::Sprintf( "ZFile::ParseXML: Error in '%s'.\n\t Can't declare a File inside a File.\n", @@ -236,21 +303,13 @@ void ZFile::DeclareResourceSubReferences() void ZFile::BuildSourceFile() { - if (!Directory::Exists(Globals::Instance->outputPath)) - Directory::CreateDirectory(Globals::Instance->outputPath.string()); + if (mode == ZFileMode::ExternalFile) + return; - GenerateSourceFiles(Globals::Instance->outputPath); -} + if (!Directory::Exists(outputPath)) + Directory::CreateDirectory(outputPath); -std::string ZFile::GetVarName(uint32_t address) -{ - for (std::pair pair : declarations) - { - if (pair.first == address) - return pair.second->varName; - } - - return ""; + GenerateSourceFiles(); } std::string ZFile::GetName() const @@ -258,6 +317,11 @@ std::string ZFile::GetName() const return name; } +ZFileMode ZFile::GetMode() const +{ + return mode; +} + const fs::path& ZFile::GetXmlFilePath() const { return xmlFilePath; @@ -270,11 +334,14 @@ const std::vector& ZFile::GetRawData() const void ZFile::ExtractResources() { - if (!Directory::Exists(Globals::Instance->outputPath)) - Directory::CreateDirectory(Globals::Instance->outputPath.string()); + if (mode == ZFileMode::ExternalFile) + return; - if (!Directory::Exists(GetSourceOutputFolderPath().string())) - Directory::CreateDirectory(GetSourceOutputFolderPath().string()); + if (!Directory::Exists(outputPath)) + Directory::CreateDirectory(outputPath); + + if (!Directory::Exists(GetSourceOutputFolderPath())) + Directory::CreateDirectory(GetSourceOutputFolderPath()); for (size_t i = 0; i < resources.size(); i++) resources[i]->ParseRawDataLate(); @@ -282,7 +349,7 @@ void ZFile::ExtractResources() resources[i]->DeclareReferencesLate(name); if (Globals::Instance->genSourceFile) - GenerateSourceFiles(Globals::Instance->outputPath); + GenerateSourceFiles(); MemoryStream* memStream = new MemoryStream(); BinaryWriter writer = BinaryWriter(memStream); @@ -297,12 +364,10 @@ void ZFile::ExtractResources() if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) printf("Saving resource %s\n", res->GetName().c_str()); - res->CalcHash(); - res->Save(Globals::Instance->outputPath.string()); + res->Save(outputPath); // Check if we have an exporter "registered" for this resource type ZResourceExporter* exporter = Globals::Instance->GetExporter(res->GetResourceType()); - if (exporter != nullptr) exporter->Save(res, Globals::Instance->outputPath.string(), &writer); } @@ -350,62 +415,45 @@ std::vector ZFile::GetResourcesOfType(ZResourceType resType) return resList; } -Declaration* ZFile::AddDeclaration(uint32_t address, DeclarationAlignment alignment, size_t size, - std::string varType, std::string varName, std::string body) +Declaration* ZFile::AddDeclaration(offset_t address, DeclarationAlignment alignment, size_t size, + const std::string& varType, const std::string& varName, + const std::string& body) { - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); + bool validOffset = AddDeclarationChecks(address, varName); + if (!validOffset) + return nullptr; - Declaration* decl = new Declaration(alignment, size, varType, varName, false, body); - declarations[address] = decl; + Declaration* decl = GetDeclaration(address); + if (decl == nullptr) + { + decl = new Declaration(address, alignment, size, varType, varName, false, body); + declarations[address] = decl; + } + else + { + decl->alignment = alignment; + decl->size = size; + decl->varType = varType; + decl->varName = varName; + decl->text = body; + } return decl; } -Declaration* ZFile::AddDeclaration(uint32_t address, DeclarationAlignment alignment, - DeclarationPadding padding, size_t size, std::string varType, - std::string varName, std::string body) +Declaration* ZFile::AddDeclarationArray(offset_t address, DeclarationAlignment alignment, + size_t size, const std::string& varType, + const std::string& varName, size_t arrayItemCnt, + const std::string& body) { - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); - - declarations[address] = - new Declaration(alignment, padding, size, varType, varName, false, body); - return declarations[address]; -} - -Declaration* ZFile::AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, - size_t size, std::string varType, std::string varName, - size_t arrayItemCnt, std::string body) -{ - return AddDeclarationArray(address, alignment, DeclarationPadding::None, size, varType, varName, - arrayItemCnt, body); -} - -Declaration* ZFile::AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, - size_t size, std::string varType, std::string varName, - std::string arrayItemCntStr, std::string body) -{ - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); - - declarations[address] = - new Declaration(alignment, size, varType, varName, true, arrayItemCntStr, body); - return declarations[address]; -} - -Declaration* ZFile::AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, - DeclarationPadding padding, size_t size, - std::string varType, std::string varName, - size_t arrayItemCnt, std::string body) -{ - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); + bool validOffset = AddDeclarationChecks(address, varName); + if (!validOffset) + return nullptr; Declaration* decl = GetDeclaration(address); if (decl == nullptr) { decl = - new Declaration(alignment, padding, size, varType, varName, true, arrayItemCnt, body); + new Declaration(address, alignment, size, varType, varName, true, arrayItemCnt, body); declarations[address] = decl; } else @@ -413,27 +461,55 @@ Declaration* ZFile::AddDeclarationArray(uint32_t address, DeclarationAlignment a if (decl->isPlaceholder) decl->varName = varName; decl->alignment = alignment; - decl->padding = padding; decl->size = size; decl->varType = varType; decl->isArray = true; decl->arrayItemCnt = arrayItemCnt; - if (body != "" && decl->text == "") - decl->text = body; + decl->text = body; } return decl; } -Declaration* ZFile::AddDeclarationPlaceholder(uint32_t address) +Declaration* ZFile::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) { - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); - Declaration* decl; + bool validOffset = AddDeclarationChecks(address, varName); + if (!validOffset) + return nullptr; + Declaration* decl = GetDeclaration(address); + if (decl == nullptr) + { + decl = new Declaration(address, alignment, size, varType, varName, true, arrayItemCntStr, + body); + declarations[address] = decl; + } + else + { + decl->alignment = alignment; + decl->size = size; + decl->varType = varType; + decl->varName = varName; + decl->isArray = true; + decl->arrayItemCntStr = arrayItemCntStr; + decl->text = body; + } + return decl; +} + +Declaration* ZFile::AddDeclarationPlaceholder(offset_t address, const std::string& varName) +{ + bool validOffset = AddDeclarationChecks(address, varName); + if (!validOffset) + return nullptr; + + Declaration* decl; if (declarations.find(address) == declarations.end()) { - decl = new Declaration(DeclarationAlignment::None, 0, "", "", false, ""); + decl = new Declaration(address, DeclarationAlignment::Align4, 0, "", varName, false, ""); decl->isPlaceholder = true; declarations[address] = decl; } @@ -443,114 +519,165 @@ Declaration* ZFile::AddDeclarationPlaceholder(uint32_t address) return decl; } -Declaration* ZFile::AddDeclarationPlaceholder(uint32_t address, std::string varName) +Declaration* ZFile::AddDeclarationInclude(offset_t address, const std::string& includePath, + size_t size, const std::string& varType, + const std::string& varName) { - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); - Declaration* decl; + bool validOffset = AddDeclarationChecks(address, varName); + if (!validOffset) + return nullptr; - if (declarations.find(address) == declarations.end()) + Declaration* decl = GetDeclaration(address); + if (decl == nullptr) { - decl = new Declaration(DeclarationAlignment::None, 0, "", varName, false, ""); - decl->isPlaceholder = true; + decl = new Declaration(address, includePath, size, varType, varName); declarations[address] = decl; } else - decl = declarations[address]; - + { + decl->includePath = includePath; + decl->size = size; + decl->varType = varType; + decl->varName = varName; + } return decl; } -Declaration* ZFile::AddDeclarationInclude(uint32_t address, std::string includePath, size_t size, - std::string varType, std::string varName) +Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& includePath, + size_t size, const std::string& varType, + const std::string& varName, size_t arrayItemCnt) { - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); - - if (declarations.find(address) == declarations.end()) - declarations[address] = new Declaration(includePath, size, varType, varName); - - return declarations[address]; -} - -Declaration* ZFile::AddDeclarationIncludeArray(uint32_t address, std::string includePath, - size_t size, std::string varType, - std::string varName, size_t arrayItemCnt) -{ - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); + bool validOffset = AddDeclarationChecks(address, varName); + if (!validOffset) + return nullptr; if (StringHelper::StartsWith(includePath, "assets/extracted/")) includePath = "assets/" + StringHelper::Split(includePath, "assets/extracted/")[1]; if (StringHelper::StartsWith(includePath, "assets/custom/")) includePath = "assets/" + StringHelper::Split(includePath, "assets/custom/")[1]; - auto declCheck = declarations.find(address); - - if (declCheck != declarations.end()) + Declaration* decl = GetDeclaration(address); + if (decl == nullptr) { - declCheck->second->includePath = includePath; - declCheck->second->varType = varType; - declCheck->second->varName = varName; - declCheck->second->size = size; - declCheck->second->isArray = true; - declCheck->second->arrayItemCnt = arrayItemCnt; - - return declCheck->second; - } - else - { - Declaration* decl = new Declaration(includePath, size, varType, varName); + decl = new Declaration(address, includePath, size, varType, varName); decl->isArray = true; decl->arrayItemCnt = arrayItemCnt; declarations[address] = decl; - return declarations[address]; } + else + { + decl->includePath = includePath; + decl->varType = varType; + decl->varName = varName; + decl->size = size; + decl->isArray = true; + decl->arrayItemCnt = arrayItemCnt; + } + return decl; } -void ZFile::AddDeclarationDebugChecks(uint32_t address) +bool ZFile::AddDeclarationChecks(uint32_t address, const std::string& varName) { assert(GETSEGNUM(address) == 0); -#ifdef _DEBUG + assert(varName != ""); +#ifdef DEVELOPMENT if (address == 0x0000) { - int32_t bp = 0; + [[maybe_unused]] int32_t bp = 0; } #endif + + if (!IsOffsetInFileRange(address)) + { + fprintf(stderr, + "%s: Warning in %s\n" + "\t Tried to declare a variable outside of this file's range. Ignoring...\n" + "\t\t Variable's name: %s\n" + "\t\t Variable's offset: 0x%06X\n", + __PRETTY_FUNCTION__, name.c_str(), varName.c_str(), address); + return false; + } + + return true; } -std::string ZFile::GetDeclarationName(uint32_t address) const -{ - return GetDeclarationName(address, - "ERROR_COULD_NOT_FIND_DECLARATION"); // Note: For now that default - // message is just for testing -} - -std::string ZFile::GetDeclarationName(uint32_t address, std::string defaultResult) const -{ - Declaration* decl = GetDeclaration(address); - if (decl != nullptr) - return decl->varName; - - return defaultResult; -} - -std::string ZFile::GetDeclarationPtrName(segptr_t segAddress) const +bool ZFile::GetDeclarationPtrName(segptr_t segAddress, const std::string& expectedType, + std::string& declName) const { if (segAddress == 0) - return "NULL"; + { + declName = "NULL"; + return true; + } - Declaration* decl = GetDeclaration(Seg2Filespace(segAddress, baseAddress)); + uint32_t offset = Seg2Filespace(segAddress, baseAddress); + Declaration* decl = GetDeclaration(offset); + if (GETSEGNUM(segAddress) != segment || decl == nullptr) + { + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; + } - if (!Globals::Instance->HasSegment(GETSEGNUM(segAddress)) || decl == nullptr) - return StringHelper::Sprintf("0x%08X", segAddress); + if (expectedType != "" && expectedType != "void*") + { + if (expectedType != decl->varType && "static " + expectedType != decl->varType) + { + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; + } + } if (!decl->isArray) - return "&" + decl->varName; + declName = "&" + decl->varName; + else + declName = decl->varName; + return true; +} - return decl->varName; +bool ZFile::GetDeclarationArrayIndexedName(segptr_t segAddress, size_t elementSize, + const std::string& expectedType, + std::string& declName) const +{ + if (segAddress == 0) + { + declName = "NULL"; + return true; + } + + uint32_t address = Seg2Filespace(segAddress, baseAddress); + Declaration* decl = GetDeclarationRanged(address); + if (GETSEGNUM(segAddress) != segment || decl == nullptr || !decl->isArray) + { + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; + } + + if (expectedType != "" && expectedType != "void*") + { + if (expectedType != decl->varType && "static " + expectedType != decl->varType) + { + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; + } + } + + if (decl->address == address) + { + declName = decl->varName; + return true; + } + + if ((address - decl->address) % elementSize != 0 || !(address < decl->address + decl->size)) + { + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; + } + + uint32_t index = (address - decl->address) / elementSize; + declName = StringHelper::Sprintf("&%s[%u]", decl->varName.c_str(), index); + return true; } Declaration* ZFile::GetDeclaration(uint32_t address) const @@ -572,86 +699,47 @@ Declaration* ZFile::GetDeclarationRanged(uint32_t address) const return nullptr; } -uint32_t ZFile::GetDeclarationRangedAddress(uint32_t address) const -{ - for (const auto decl : declarations) - { - if (address >= decl.first && address < decl.first + decl.second->size) - return decl.first; - } - - return 0xFFFFFFFF; -} - bool ZFile::HasDeclaration(uint32_t address) { assert(GETSEGNUM(address) == 0); return declarations.find(address) != declarations.end(); } -void ZFile::GenerateSourceFiles(fs::path outputDir) +void ZFile::GenerateSourceFiles() { - std::string sourceOutput = ""; + std::string sourceOutput; sourceOutput += "#include \"ultra64.h\"\n"; sourceOutput += "#include \"z64.h\"\n"; sourceOutput += "#include \"macros.h\"\n"; sourceOutput += GetHeaderInclude(); + bool hasZRoom = false; + for (const auto& res : resources) + { + ZResourceType resType = res->GetResourceType(); + if (resType == ZResourceType::Room || resType == ZResourceType::Scene || + resType == ZResourceType::AltHeader) + { + hasZRoom = true; + break; + } + } + + if (hasZRoom) + { + sourceOutput += GetZRoomHeaderInclude(); + } + + sourceOutput += GetExternalFileHeaderInclude(); + GeneratePlaceholderDeclarations(); // Generate Code for (size_t i = 0; i < resources.size(); i++) { ZResource* res = resources.at(i); - std::string resSrc = res->GetSourceOutputCode(name); - - if (res->IsExternalResource()) - { - std::string path = Path::GetFileNameWithoutExtension(res->GetName()).c_str(); - - std::string assetOutDir = - (outputDir / Path::GetFileNameWithoutExtension(res->GetOutName())).string(); - std::string declType = res->GetSourceTypeName(); - - std::string incStr = StringHelper::Sprintf("%s.%s.inc", assetOutDir.c_str(), - res->GetExternalExtension().c_str()); - - if (res->GetResourceType() == ZResourceType::Texture) - { - ZTexture* tex = static_cast(res); - - if (!Globals::Instance->cfg.texturePool.empty()) - { - tex->CalcHash(); - - // TEXTURE POOL CHECK - if (Globals::Instance->cfg.texturePool.find(tex->hash) != - Globals::Instance->cfg.texturePool.end()) - { - incStr = Globals::Instance->cfg.texturePool[tex->hash].path.string() + "." + - res->GetExternalExtension() + ".inc"; - } - } - - incStr += ".c"; - } - else if (res->GetResourceType() == ZResourceType::Blob || - res->GetResourceType() == ZResourceType::Background) - { - incStr += ".c"; - } - - AddDeclarationIncludeArray(res->GetRawDataIndex(), incStr, res->GetRawDataSize(), - declType, res->GetName(), 0); - } - else - { - sourceOutput += resSrc; - } - - if (resSrc != "" && !res->IsExternalResource()) - sourceOutput += "\n"; + res->GetSourceOutputCode(name); } sourceOutput += ProcessDeclarations(); @@ -682,6 +770,11 @@ void ZFile::GenerateSourceHeaderFiles() formatter.Write("\n"); } + for (auto& sym : symbolResources) + { + formatter.Write(sym.second->GetSourceOutputHeader("")); + } + formatter.Write(ProcessExterns()); fs::path headerFilename = GetSourceOutputFolderPath() / outName.stem().concat(".h"); @@ -692,10 +785,48 @@ void ZFile::GenerateSourceHeaderFiles() File::WriteAllText(headerFilename, formatter.GetOutput()); } -std::string ZFile::GetHeaderInclude() +std::string ZFile::GetHeaderInclude() const { - return StringHelper::Sprintf("#include \"%s\"\n\n", - (outName.parent_path() / outName.stem().concat(".h")).c_str()); + std::string headers = StringHelper::Sprintf("#include \"%s.h\"\n", + (outName.parent_path() / outName.stem()).c_str()); + + return headers; +} + +std::string ZFile::GetZRoomHeaderInclude() const +{ + std::string headers; + headers += "#include \"segment_symbols.h\"\n"; + headers += "#include \"command_macros_base.h\"\n"; + headers += "#include \"z64cutscene_commands.h\"\n"; + headers += "#include \"variables.h\"\n"; + return headers; +} + +std::string ZFile::GetExternalFileHeaderInclude() const +{ + std::string externalFilesIncludes = ""; + + for (ZFile* externalFile : Globals::Instance->files) + { + if (externalFile != this) + { + fs::path outputFolderPath = externalFile->GetSourceOutputFolderPath(); + if (outputFolderPath == this->GetSourceOutputFolderPath()) + { + outputFolderPath = externalFile->outName.stem(); + } + else + { + outputFolderPath /= externalFile->outName.stem(); + } + + externalFilesIncludes += + StringHelper::Sprintf("#include \"%s.h\"\n", outputFolderPath.c_str()); + } + } + + return externalFilesIncludes; } void ZFile::GeneratePlaceholderDeclarations() @@ -703,8 +834,17 @@ void ZFile::GeneratePlaceholderDeclarations() // Generate placeholder declarations for (ZResource* res : resources) { - if (GetDeclaration(res->GetRawDataIndex()) == nullptr) - AddDeclarationPlaceholder(res->GetRawDataIndex(), res->GetName()); + if (GetDeclaration(res->GetRawDataIndex()) != nullptr) + { + continue; + } + + Declaration* decl = res->DeclareVar(GetName(), ""); + decl->staticConf = res->GetStaticConf(); + if (res->GetResourceType() == ZResourceType::Symbol) + { + decl->staticConf = StaticConfig::Off; + } } } @@ -726,9 +866,52 @@ ZTexture* ZFile::GetTextureResource(uint32_t offset) const return nullptr; } +void ZFile::AddSymbolResource(uint32_t offset, ZSymbol* sym) +{ + symbolResources[offset] = sym; +} + +ZSymbol* ZFile::GetSymbolResource(uint32_t offset) const +{ + auto sym = symbolResources.find(offset); + if (sym != symbolResources.end()) + return sym->second; + + return nullptr; +} + +ZSymbol* ZFile::GetSymbolResourceRanged(uint32_t offset) const +{ + for (const auto decl : symbolResources) + { + if (offset >= decl.first && offset < decl.first + decl.second->GetRawDataSize()) + return decl.second; + } + + return nullptr; +} + fs::path ZFile::GetSourceOutputFolderPath() const { - return Globals::Instance->sourceOutputPath / outName.parent_path(); + return outputPath / outName.parent_path(); +} + +bool ZFile::IsOffsetInFileRange(uint32_t offset) const +{ + if (!(offset < rawData.size())) + return false; + + return rangeStart <= offset && offset < rangeEnd; +} +bool ZFile::IsSegmentedInFilespaceRange(segptr_t segAddress) const +{ + uint8_t segnum = GETSEGNUM(segAddress); + uint32_t offset = Seg2Filespace(segAddress, baseAddress); + + if (segment != segnum) + return false; + + return IsOffsetInFileRange(offset); } std::map* ZFile::GetNodeMap() @@ -745,7 +928,7 @@ void ZFile::RegisterNode(std::string nodeName, ZResourceFactoryFunc* nodeFunc) std::string ZFile::ProcessDeclarations() { - std::string output = ""; + std::string output; if (declarations.size() == 0) return output; @@ -754,7 +937,6 @@ std::string ZFile::ProcessDeclarations() // Account for padding/alignment uint32_t lastAddr = 0; - uint32_t lastSize = 0; // printf("RANGE START: 0x%06X - RANGE END: 0x%06X\n", rangeStart, rangeEnd); @@ -772,21 +954,25 @@ std::string ZFile::ProcessDeclarations() { if (curItem.second->varType == lastItem.second->varType) { - // TEST: For now just do Vtx declarations... - if (lastItem.second->varType == "static Vtx") + if (!curItem.second->declaredInXml && !lastItem.second->declaredInXml) { - int32_t sizeDiff = curItem.first - (lastItem.first + lastItem.second->size); - - // Make sure there isn't an unaccounted inbetween these two - if (sizeDiff == 0) + // TEST: For now just do Vtx declarations... + if (lastItem.second->varType == "Vtx") { - lastItem.second->size += curItem.second->size; - lastItem.second->arrayItemCnt += curItem.second->arrayItemCnt; - lastItem.second->text += "\n" + curItem.second->text; - declarations.erase(curItem.first); - declarationKeys.erase(declarationKeys.begin() + i); - i--; - continue; + int32_t sizeDiff = curItem.first - (lastItem.first + lastItem.second->size); + + // Make sure there isn't an unaccounted inbetween these two + if (sizeDiff == 0) + { + lastItem.second->size += curItem.second->size; + lastItem.second->arrayItemCnt += curItem.second->arrayItemCnt; + lastItem.second->text += "\n" + curItem.second->text; + declarations.erase(curItem.first); + declarationKeys.erase(declarationKeys.begin() + i); + delete curItem.second; + i--; + continue; + } } } } @@ -807,35 +993,21 @@ std::string ZFile::ProcessDeclarations() { if (item.second->alignment == DeclarationAlignment::Align16) { - // int32_t lastAddrSizeTest = declarations[lastAddr]->size; int32_t curPtr = lastAddr + declarations[lastAddr]->size; while (curPtr % 4 != 0) { declarations[lastAddr]->size++; - // item.second->size++; curPtr++; } - - /*while (curPtr % 16 != 0) - { - char buffer[2048]; - - sprintf(buffer, "static u32 align%02X = 0;\n", curPtr); - item.second->text = buffer + item.second->text; - - declarations[lastAddr]->size += 4; - curPtr += 4; - }*/ } else if (item.second->alignment == DeclarationAlignment::Align8) { - int32_t curPtr = lastAddr + declarations[lastAddr]->size; + size_t curPtr = lastAddr + declarations[lastAddr]->size; while (curPtr % 4 != 0) { declarations[lastAddr]->size++; - // item.second->size++; curPtr++; } @@ -843,208 +1015,33 @@ std::string ZFile::ProcessDeclarations() { char buffer[2048]; - sprintf(buffer, "static u32 align%02X = 0;\n", curPtr); + sprintf(buffer, "u32 %s_align%02zX = 0;\n", name.c_str(), curPtr); item.second->preText = buffer + item.second->preText; declarations[lastAddr]->size += 4; - // item.second->size += 4; curPtr += 4; } } } - if (item.second->padding == DeclarationPadding::Pad16) - { - int32_t curPtr = item.first + item.second->size; - - while (curPtr % 4 != 0) - { - item.second->size++; - curPtr++; - } - - while (curPtr % 16 != 0) - { - item.second->postText += StringHelper::Sprintf("static u32 pad%02X = 0;\n", curPtr); - - item.second->size += 4; - curPtr += 4; - } - } - lastAddr = item.first; } - // Handle unaccounted data - lastAddr = 0; - lastSize = 0; - std::vector declsAddresses; - for (const auto& item : declarations) - { - declsAddresses.push_back(item.first); - } - declsAddresses.push_back(rawData.size()); - - for (uint32_t currentAddress : declsAddresses) - { - if (currentAddress >= rangeEnd) - { - break; - } - - if (currentAddress < rangeStart) - { - lastAddr = currentAddress; - continue; - } - - if (currentAddress != lastAddr && declarations.find(lastAddr) != declarations.end()) - { - Declaration* lastDecl = declarations.at(lastAddr); - lastSize = lastDecl->size; - - if (lastAddr + lastSize > currentAddress) - { - Declaration* currentDecl = declarations.at(currentAddress); - - fprintf(stderr, - "WARNING: Intersection detected from 0x%06X:0x%06X (%s), conflicts with " - "0x%06X (%s)\n", - lastAddr, lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress, - currentDecl->varName.c_str()); - } - } - - uint32_t unaccountedAddress = lastAddr + lastSize; - - if (unaccountedAddress != currentAddress && lastAddr >= rangeStart && - unaccountedAddress < rangeEnd) - { - int diff = currentAddress - unaccountedAddress; - bool nonZeroUnaccounted = false; - - std::string src = " "; - - for (int i = 0; i < diff; i++) - { - uint8_t val = rawData.at(unaccountedAddress + i); - src += StringHelper::Sprintf("0x%02X, ", val); - if (val != 0x00) - { - nonZeroUnaccounted = true; - } - - if (Globals::Instance->verboseUnaccounted) - { - if ((i % 4 == 3)) - { - src += StringHelper::Sprintf(" // 0x%06X", unaccountedAddress + i - 3); - if (i != (diff - 1)) - { - src += "\n\t"; - } - } - } - else - { - if ((i % 16 == 15) && (i != (diff - 1))) - src += "\n "; - } - } - - if (declarations.find(unaccountedAddress) == declarations.end()) - { - if (diff > 0) - { - std::string unaccountedPrefix = "unaccounted"; - - if (diff < 16 && !nonZeroUnaccounted) - { - unaccountedPrefix = "possiblePadding"; - - // Strip unnecessary padding at the end of the file. - if (unaccountedAddress + diff >= rawData.size()) - break; - } - - Declaration* decl = AddDeclarationArray( - unaccountedAddress, DeclarationAlignment::None, diff, "static u8", - StringHelper::Sprintf("%s_%06X", unaccountedPrefix.c_str(), - unaccountedAddress), - diff, src); - decl->isUnaccounted = true; - - if (Globals::Instance->warnUnaccounted) - { - if (nonZeroUnaccounted) - { - fprintf( - stderr, - "Warning in file: %s (%s)\n" - "\t A non-zero unaccounted block was found at address '0x%06X'.\n" - "\t Block size: '0x%X'.\n", - xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); - } - else if (diff >= 16) - { - fprintf(stderr, - "Warning in file: %s (%s)\n" - "\t A big (size>=0x10) zero-only unaccounted block was found " - "at address '0x%06X'.\n" - "\t Block size: '0x%X'.\n", - xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); - } - } - } - } - } - - lastAddr = currentAddress; - } + HandleUnaccountedData(); // Go through include declarations // First, handle the prototypes (static only for now) - int32_t protoCnt = 0; for (std::pair item : declarations) { - if (StringHelper::StartsWith(item.second->varType, "static ") && - !item.second->isUnaccounted) - { - if (item.second->isArray) - { - if (item.second->arrayItemCntStr != "") - { - output += StringHelper::Sprintf("%s %s[%s];\n", item.second->varType.c_str(), - item.second->varName.c_str(), - item.second->arrayItemCntStr.c_str()); - } - else if (item.second->arrayItemCnt == 0) - { - output += StringHelper::Sprintf("%s %s[];\n", item.second->varType.c_str(), - item.second->varName.c_str()); - } - else - { - output += StringHelper::Sprintf("%s %s[%i];\n", item.second->varType.c_str(), - item.second->varName.c_str(), - item.second->arrayItemCnt); - } - } - else - output += StringHelper::Sprintf("%s %s;\n", item.second->varType.c_str(), - item.second->varName.c_str()); - - protoCnt++; - } + output += item.second->GetStaticForwardDeclarationStr(); } - if (protoCnt > 0) - output += "\n"; + output += "\n"; // Next, output the actual declarations - for (std::pair item : declarations) + for (const auto& item : declarations) { - if (item.first < rangeStart || item.first >= rangeEnd) + if (!IsOffsetInFileRange(item.first)) continue; if (item.second->includePath != "") @@ -1052,88 +1049,24 @@ std::string ZFile::ProcessDeclarations() if (item.second->isExternal) { // HACK - std::string extType = ""; + std::string extType; if (item.second->varType == "Gfx") extType = "dlist"; - else if (item.second->varType == "Vtx" || item.second->varType == "static Vtx") + else if (item.second->varType == "Vtx") extType = "vtx"; - auto filepath = Globals::Instance->outputPath / item.second->varName; + auto filepath = outputPath / item.second->varName; File::WriteAllText( StringHelper::Sprintf("%s.%s.inc", filepath.c_str(), extType.c_str()), item.second->text); } - // Do not asm_process vertex arrays. They have no practical use being overridden. - // if (item.second->varType == "Vtx" || item.second->varType == "static Vtx") - if (item.second->varType != "u64" && item.second->varType != "static u64" && - item.second->varType != "u8" && item.second->varType != "static u8") - { - output += StringHelper::Sprintf( - "%s %s[] = {\n #include \"%s\"\n};\n\n", item.second->varType.c_str(), - item.second->varName.c_str(), - StringHelper::Replace(item.second->includePath, "assets/", "../assets/") - .c_str()); - } - else - { - if (item.second->arrayItemCntStr != "") - output += StringHelper::Sprintf( - "%s %s[%s] = {\n #include \"%s\"\n};\n\n", item.second->varType.c_str(), - item.second->varName.c_str(), item.second->arrayItemCntStr.c_str(), - item.second->includePath.c_str()); - else - output += StringHelper::Sprintf( - "%s %s[] = {\n #include \"%s\"\n};\n\n", item.second->varType.c_str(), - item.second->varName.c_str(), item.second->includePath.c_str()); - } + output += item.second->GetExternalDeclarationStr(); } else if (item.second->varType != "") { - if (item.second->preText != "") - output += item.second->preText + "\n"; - - { - if (item.second->isArray) - { - if (item.second->arrayItemCntStr != "") - { - output += StringHelper::Sprintf( - "%s %s[%s];\n", item.second->varType.c_str(), - item.second->varName.c_str(), item.second->arrayItemCntStr.c_str()); - } - else - { - if (item.second->arrayItemCnt == 0) - output += - StringHelper::Sprintf("%s %s[] = {\n", item.second->varType.c_str(), - item.second->varName.c_str()); - else - output += StringHelper::Sprintf( - "%s %s[%i] = {\n", item.second->varType.c_str(), - item.second->varName.c_str(), item.second->arrayItemCnt); - } - - output += item.second->text + "\n"; - } - else - { - output += StringHelper::Sprintf("%s %s = { ", item.second->varType.c_str(), - item.second->varName.c_str()); - output += item.second->text; - } - - if (output.back() == '\n') - output += "};"; - else - output += " };"; - } - - output += " " + item.second->rightText + "\n\n"; - - if (item.second->postText != "") - output += item.second->postText + "\n"; + output += item.second->GetNormalDeclarationStr(); } } @@ -1146,84 +1079,41 @@ void ZFile::ProcessDeclarationText(Declaration* decl) { size_t refIndex = 0; - if (decl->references.size() > 0) + if (!(decl->references.size() > 0)) + return; + + for (size_t i = 0; i < decl->text.size() - 1; i++) { - for (size_t i = 0; i < decl->text.size() - 1; i++) + char c = decl->text[i]; + char c2 = decl->text[i + 1]; + + if (c == '@' && c2 == 'r') { - char c = decl->text[i]; - char c2 = decl->text[i + 1]; + std::string vtxName; + Globals::Instance->GetSegmentedArrayIndexedName(decl->references[refIndex], 0x10, this, + "Vtx", vtxName); + decl->text.replace(i, 2, vtxName); - if (c == '@' && c2 == 'r') - { - if (refIndex >= decl->references.size()) - break; + refIndex++; - Declaration* refDecl = GetDeclarationRanged(decl->references[refIndex]); - uint32_t refDeclAddr = GetDeclarationRangedAddress(decl->references[refIndex]); - - if (refDecl != nullptr) - { - if (refDecl->isArray) - { - if (refDecl->arrayItemCnt != 0) - { - int32_t itemSize = refDecl->size / refDecl->arrayItemCnt; - int32_t itemIndex = - (decl->references[refIndex] - refDeclAddr) / itemSize; - - decl->text.replace(i, 2, - StringHelper::Sprintf( - "&%s[%i]", refDecl->varName.c_str(), itemIndex)); - } - else - { - decl->text.replace(i, 2, - StringHelper::Sprintf("ERROR ARRAYITEMCNT = 0")); - } - } - else - { - decl->text.replace(i, 2, refDecl->varName); - } - } - else - decl->text.replace(i, 2, "ERROR"); - - refIndex++; - } + if (refIndex >= decl->references.size()) + break; } } } std::string ZFile::ProcessExterns() { - std::string output = ""; + std::string output; - for (std::pair item : declarations) + for (const auto& item : declarations) { - if (item.first < rangeStart || item.first >= rangeEnd) + if (!IsOffsetInFileRange(item.first)) { continue; } - if (!StringHelper::StartsWith(item.second->varType, "static ") && - item.second->varType != "") // && item.second->includePath == "") - { - if (item.second->isArray) - { - if (item.second->arrayItemCnt == 0) - output += - StringHelper::Sprintf("extern %s %s[];\n", item.second->varType.c_str(), - item.second->varName.c_str()); - else - output += StringHelper::Sprintf( - "extern %s %s[%i];\n", item.second->varType.c_str(), - item.second->varName.c_str(), item.second->arrayItemCnt); - } - else - output += StringHelper::Sprintf("extern %s %s;\n", item.second->varType.c_str(), - item.second->varName.c_str()); - } + output += item.second->GetExternStr(); } output += "\n"; @@ -1233,12 +1123,12 @@ std::string ZFile::ProcessExterns() return output; } -std::string ZFile::ProcessTextureIntersections([[maybe_unused]] std::string prefix) +std::string ZFile::ProcessTextureIntersections([[maybe_unused]] const std::string& prefix) { if (texturesResources.empty()) return ""; - std::string defines = ""; + std::string defines; std::vector> texturesSorted(texturesResources.begin(), texturesResources.end()); @@ -1263,11 +1153,13 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] std::string pref // Shrink palette so it doesn't overlap currentTex->SetDimensions(offsetDiff / currentTex->GetPixelMultiplyer(), 1); declarations.at(currentOffset)->size = currentTex->GetRawDataSize(); + currentTex->DeclareVar(GetName(), ""); } else { - std::string texName = GetDeclarationPtrName(currentOffset); + std::string texName; std::string texNextName; + GetDeclarationPtrName(currentOffset, "", texName); Declaration* nextDecl = GetDeclaration(nextOffset); if (nextDecl == nullptr) @@ -1278,6 +1170,7 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] std::string pref defines += StringHelper::Sprintf("#define %s ((u32)%s + 0x%06X)\n", texNextName.c_str(), texName.c_str(), offsetDiff); + delete declarations[nextOffset]; declarations.erase(nextOffset); texturesResources.erase(nextOffset); texturesSorted.erase(texturesSorted.begin() + i + 1); @@ -1289,3 +1182,155 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] std::string pref return defines; } + +void ZFile::HandleUnaccountedData() +{ + uint32_t lastAddr = 0; + uint32_t lastSize = 0; + std::vector declsAddresses; + for (const auto& item : declarations) + { + declsAddresses.push_back(item.first); + } + + bool breakLoop = false; + for (uint32_t currentAddress : declsAddresses) + { + if (currentAddress >= rangeEnd) + { + breakLoop = true; + break; + } + + if (currentAddress < rangeStart) + { + lastAddr = currentAddress; + continue; + } + + breakLoop = HandleUnaccountedAddress(currentAddress, lastAddr, lastSize); + if (breakLoop) + break; + + lastAddr = currentAddress; + } + + if (!breakLoop) + { + // TODO: change rawData.size() to rangeEnd + // HandleUnaccountedAddress(rangeEnd, lastAddr, lastSize); + HandleUnaccountedAddress(rawData.size(), lastAddr, lastSize); + } +} + +bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, uint32_t& lastSize) +{ + if (currentAddress != lastAddr && declarations.find(lastAddr) != declarations.end()) + { + Declaration* lastDecl = declarations.at(lastAddr); + lastSize = lastDecl->size; + + if (lastAddr + lastSize > currentAddress) + { + Declaration* currentDecl = declarations.at(currentAddress); + + fprintf(stderr, + "WARNING: Intersection detected from 0x%06X:0x%06X (%s), conflicts with " + "0x%06X (%s)\n", + lastAddr, lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress, + currentDecl->varName.c_str()); + } + } + + uint32_t unaccountedAddress = lastAddr + lastSize; + + if (unaccountedAddress != currentAddress && lastAddr >= rangeStart && + unaccountedAddress < rangeEnd) + { + int diff = currentAddress - unaccountedAddress; + bool nonZeroUnaccounted = false; + + std::string src = " "; + + if (currentAddress > rawData.size()) + { + throw std::runtime_error(StringHelper::Sprintf( + "ZFile::ProcessDeclarations(): Fatal error while processing XML '%s'.\n" + "\t Offset '0x%X' is outside of the limits of file '%s', which has a size of " + "'0x%X'.\n" + "\t Aborting...", + xmlFilePath.c_str(), currentAddress, name.c_str(), rawData.size())); + } + + for (int i = 0; i < diff; i++) + { + uint8_t val = rawData.at(unaccountedAddress + i); + src += StringHelper::Sprintf("0x%02X, ", val); + if (val != 0x00) + { + nonZeroUnaccounted = true; + } + + if (Globals::Instance->verboseUnaccounted) + { + if ((i % 4 == 3)) + { + src += StringHelper::Sprintf(" // 0x%06X", unaccountedAddress + i - 3); + if (i != (diff - 1)) + { + src += "\n\t"; + } + } + } + else + { + if ((i % 16 == 15) && (i != (diff - 1))) + src += "\n "; + } + } + + if (declarations.find(unaccountedAddress) == declarations.end() && diff > 0) + { + std::string unaccountedPrefix = "unaccounted"; + + if (diff < 16 && !nonZeroUnaccounted) + { + unaccountedPrefix = "possiblePadding"; + + // Strip unnecessary padding at the end of the file. + if (unaccountedAddress + diff >= rawData.size()) + return true; + } + + Declaration* decl = AddDeclarationArray( + unaccountedAddress, DeclarationAlignment::Align4, diff, "u8", + StringHelper::Sprintf("%s_%s_%06X", name.c_str(), unaccountedPrefix.c_str(), + unaccountedAddress), + diff, src); + decl->isUnaccounted = true; + + if (Globals::Instance->warnUnaccounted) + { + if (nonZeroUnaccounted) + { + fprintf(stderr, + "Warning in file: %s (%s)\n" + "\t A non-zero unaccounted block was found at offset '0x%06X'.\n" + "\t Block size: '0x%X'.\n", + xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); + } + else if (diff >= 16) + { + fprintf(stderr, + "Warning in file: %s (%s)\n" + "\t A big (size>=0x10) zero-only unaccounted block was found " + "at offset '0x%06X'.\n" + "\t Block size: '0x%X'.\n", + xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); + } + } + } + } + + return false; +} diff --git a/tools/ZAPD/ZAPD/ZFile.h b/tools/ZAPD/ZAPD/ZFile.h index 0ca0de8379..9de6950e4a 100644 --- a/tools/ZAPD/ZAPD/ZFile.h +++ b/tools/ZAPD/ZAPD/ZFile.h @@ -3,6 +3,8 @@ #include #include #include + +#include "ZSymbol.h" #include "ZTexture.h" #include "tinyxml2.h" @@ -14,8 +16,9 @@ enum class ZFileMode BuildSourceFile, BuildBackground, Extract, + ExternalFile, Invalid, - Custom = 1000 // Used for exporter file modes + Custom = 1000, // Used for exporter file modes }; enum class ZGame @@ -28,19 +31,22 @@ enum class ZGame class ZFile { public: - std::map declarations; + std::map declarations; std::string defines; std::vector resources; - uint32_t segment; - uint32_t baseAddress, rangeStart, rangeEnd; - ZFile(std::string nName); - ZFile(ZFileMode mode, tinyxml2::XMLElement* reader, const fs::path& nBasePath, - std::string filename, const fs::path& nXmlFilePath, bool placeholderMode); + // Default to using virtual addresses + uint32_t segment = 0x80; + uint32_t baseAddress, rangeStart, rangeEnd; + bool isExternalFile = false; + + ZFile(const fs::path& nOutPath, const std::string& nName); + ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBasePath, + const fs::path& nOutPath, const std::string& filename, const fs::path& nXmlFilePath); ~ZFile(); - std::string GetVarName(uint32_t address); std::string GetName() const; + ZFileMode GetMode() const; const fs::path& GetXmlFilePath() const; const std::vector& GetRawData() const; void ExtractResources(); @@ -49,42 +55,54 @@ public: ZResource* FindResource(uint32_t rawDataIndex); std::vector GetResourcesOfType(ZResourceType resType); - Declaration* AddDeclaration(uint32_t address, DeclarationAlignment alignment, size_t size, - std::string varType, std::string varName, std::string body); - Declaration* AddDeclaration(uint32_t address, DeclarationAlignment alignment, - DeclarationPadding padding, size_t size, std::string varType, - std::string varName, std::string body); - Declaration* AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, size_t size, - std::string varType, std::string varName, size_t arrayItemCnt, - std::string body); - Declaration* AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, size_t size, - std::string varType, std::string varName, - std::string arrayItemCntStr, std::string body); - Declaration* AddDeclarationArray(uint32_t address, DeclarationAlignment alignment, - DeclarationPadding padding, size_t size, std::string varType, - std::string varName, size_t arrayItemCnt, std::string body); - Declaration* AddDeclarationPlaceholder(uint32_t address); - Declaration* AddDeclarationPlaceholder(uint32_t address, std::string varName); - Declaration* AddDeclarationInclude(uint32_t address, std::string includePath, size_t size, - std::string varType, std::string varName); - Declaration* AddDeclarationIncludeArray(uint32_t address, std::string includePath, size_t size, - std::string varType, std::string varName, + 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); - std::string GetDeclarationName(uint32_t address) const; - std::string GetDeclarationName(uint32_t address, std::string defaultResult) const; - std::string GetDeclarationPtrName(segptr_t segAddress) const; + + bool GetDeclarationPtrName(segptr_t segAddress, const std::string& expectedType, + std::string& declName) const; + bool GetDeclarationArrayIndexedName(segptr_t segAddress, size_t elementSize, + const std::string& expectedType, + std::string& declName) const; + Declaration* GetDeclaration(uint32_t address) const; Declaration* GetDeclarationRanged(uint32_t address) const; - uint32_t GetDeclarationRangedAddress(uint32_t address) const; bool HasDeclaration(uint32_t address); - std::string GetHeaderInclude(); + + 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* GetNodeMap(); static void RegisterNode(std::string nodeName, ZResourceFactoryFunc* nodeFunc); @@ -93,23 +111,27 @@ protected: std::string name; fs::path outName = ""; fs::path basePath; + fs::path outputPath; fs::path xmlFilePath; // Keep track of every texture of this ZFile. // The pointers declared here are "borrowed" (somebody else is the owner), // so ZFile shouldn't delete/free those textures. std::map texturesResources; + std::map symbolResources; + ZFileMode mode = ZFileMode::Invalid; ZFile(); - void ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, std::string filename, - bool placeholderMode); + void ParseXML(tinyxml2::XMLElement* reader, const std::string& filename); void DeclareResourceSubReferences(); - void GenerateSourceFiles(fs::path outputDir); + void GenerateSourceFiles(); void GenerateSourceHeaderFiles(); - void AddDeclarationDebugChecks(uint32_t address); + bool AddDeclarationChecks(uint32_t address, const std::string& varName); std::string ProcessDeclarations(); void ProcessDeclarationText(Declaration* decl); std::string ProcessExterns(); - std::string ProcessTextureIntersections(std::string prefix); + std::string ProcessTextureIntersections(const std::string& prefix); + void HandleUnaccountedData(); + bool HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, uint32_t& lastSize); }; diff --git a/tools/ZAPD/ZAPD/ZLimb.cpp b/tools/ZAPD/ZAPD/ZLimb.cpp index 4983295687..77c66871fe 100644 --- a/tools/ZAPD/ZAPD/ZLimb.cpp +++ b/tools/ZAPD/ZAPD/ZLimb.cpp @@ -1,379 +1,31 @@ #include "ZLimb.h" + #include + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" REGISTER_ZFILENODE(Limb, ZLimb); -Struct_800A57C0::Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset) +ZLimb::ZLimb(ZFile* nParent) : ZResource(nParent), segmentStruct(nParent) { - unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00); - unk_2 = BitConverter::ToInt16BE(rawData, fileOffset + 0x02); - unk_4 = BitConverter::ToInt16BE(rawData, fileOffset + 0x04); - unk_6 = BitConverter::ToInt8BE(rawData, fileOffset + 0x06); - unk_7 = BitConverter::ToInt8BE(rawData, fileOffset + 0x07); - unk_8 = BitConverter::ToInt8BE(rawData, fileOffset + 0x08); - unk_9 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x09); -} -Struct_800A57C0::Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset, - size_t index) - : Struct_800A57C0(rawData, fileOffset + index * GetRawDataSize()) -{ -} - -std::string Struct_800A57C0::GetSourceOutputCode() 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); -} - -size_t Struct_800A57C0::GetRawDataSize() -{ - return 0x0A; -} - -std::string Struct_800A57C0::GetSourceTypeName() -{ - return "Struct_800A57C0"; -} - -Struct_800A598C_2::Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset) -{ - unk_0 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x00); - x = BitConverter::ToInt16BE(rawData, fileOffset + 0x02); - y = BitConverter::ToInt16BE(rawData, fileOffset + 0x04); - z = BitConverter::ToInt16BE(rawData, fileOffset + 0x06); - unk_8 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x08); -} -Struct_800A598C_2::Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset, - size_t index) - : Struct_800A598C_2(rawData, fileOffset + index * GetRawDataSize()) -{ -} - -std::string Struct_800A598C_2::GetSourceOutputCode() const -{ - return StringHelper::Sprintf("0x%02X, %i, %i, %i, 0x%02X", unk_0, x, y, z, unk_8); -} - -size_t Struct_800A598C_2::GetRawDataSize() -{ - return 0x0A; -} - -std::string Struct_800A598C_2::GetSourceTypeName() -{ - return "Struct_800A598C_2"; -} - -Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector& rawData, - uint32_t fileOffset) - : parent(parent) -{ - unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00); - unk_2 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x02); - unk_4 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x04); - unk_8 = BitConverter::ToUInt32BE(rawData, fileOffset + 0x08); - unk_C = BitConverter::ToUInt32BE(rawData, fileOffset + 0x0C); - - if (unk_8 != 0) - { - uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); - for (size_t i = 0; i < unk_0; i++) - { - unk_8_arr.emplace_back(rawData, unk_8_Offset, i); - } - } - - if (unk_C != 0) - { - uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); - for (size_t i = 0; i < unk_2; i++) - { - unk_C_arr.emplace_back(rawData, unk_C_Offset, i); - } - } -} -Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector& rawData, - uint32_t fileOffset, size_t index) - : Struct_800A598C(parent, rawData, fileOffset + index * GetRawDataSize()) -{ -} - -void Struct_800A598C::DeclareReferences(const std::string& prefix) -{ - std::string entryStr; - - if (unk_8 != 0) - { - uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); - std::string unk_8_Str = - StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), - Struct_800A57C0::GetSourceTypeName().c_str(), unk_8_Offset); - - size_t arrayItemCnt = unk_8_arr.size(); - entryStr = ""; - size_t i = 0; - - for (auto& child : unk_8_arr) - { - entryStr += StringHelper::Sprintf(" { %s },%s", child.GetSourceOutputCode().c_str(), - (++i < arrayItemCnt) ? "\n" : ""); - } - - Declaration* decl = parent->GetDeclaration(unk_8_Offset); - - if (decl == nullptr) - { - parent->AddDeclarationArray(unk_8_Offset, DeclarationAlignment::None, - arrayItemCnt * Struct_800A57C0::GetRawDataSize(), - Struct_800A57C0::GetSourceTypeName(), unk_8_Str, - arrayItemCnt, entryStr); - } - else - { - decl->text = entryStr; - } - } - - if (unk_C != 0) - { - uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); - std::string unk_C_Str = - StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), - Struct_800A598C_2::GetSourceTypeName().c_str(), unk_C_Offset); - - size_t arrayItemCnt = unk_C_arr.size(); - entryStr = ""; - size_t i = 0; - - for (auto& child : unk_C_arr) - { - entryStr += StringHelper::Sprintf(" { %s },%s", child.GetSourceOutputCode().c_str(), - (++i < arrayItemCnt) ? "\n" : ""); - } - - Declaration* decl = parent->GetDeclaration(unk_C_Offset); - if (decl == nullptr) - { - parent->AddDeclarationArray(unk_C_Offset, DeclarationAlignment::None, - arrayItemCnt * Struct_800A598C_2::GetRawDataSize(), - Struct_800A598C_2::GetSourceTypeName(), unk_C_Str, - arrayItemCnt, entryStr); - } - else - { - decl->text = entryStr; - } - } -} - -std::string Struct_800A598C::GetSourceOutputCode(const std::string& prefix) const -{ - std::string entryStr; - - std::string unk_8_Str = "NULL"; - - if (unk_8 != 0) - { - uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); - unk_8_Str = - StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), - Struct_800A57C0::GetSourceTypeName().c_str(), unk_8_Offset); - } - - std::string unk_C_Str = "NULL"; - - if (unk_C != 0) - { - uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); - unk_C_Str = - StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), - Struct_800A598C_2::GetSourceTypeName().c_str(), unk_C_Offset); - } - - entryStr = StringHelper::Sprintf("\n ARRAY_COUNTU(%s), ARRAY_COUNTU(%s),\n", - unk_8_Str.c_str(), unk_C_Str.c_str()); - entryStr += StringHelper::Sprintf(" %i, %s, %s\n ", unk_4, unk_8_Str.c_str(), - unk_C_Str.c_str()); - entryStr = StringHelper::Sprintf("\n ARRAY_COUNTU(%s), ARRAY_COUNTU(%s),\n", - unk_8_Str.c_str(), unk_C_Str.c_str()); - entryStr += StringHelper::Sprintf(" %i, %s, %s\n ", unk_4, unk_8_Str.c_str(), - unk_C_Str.c_str()); - - return entryStr; -} - -size_t Struct_800A598C::GetRawDataSize() -{ - return 0x10; -} - -std::string Struct_800A598C::GetSourceTypeName() -{ - return "Struct_800A598C"; -} - -Struct_800A5E28::Struct_800A5E28(ZFile* parent, const std::vector& nRawData, - uint32_t fileOffset) - : parent(parent) -{ - unk_0 = BitConverter::ToUInt16BE(nRawData, fileOffset + 0x00); - unk_2 = BitConverter::ToUInt16BE(nRawData, fileOffset + 0x02); - unk_4 = BitConverter::ToUInt32BE(nRawData, fileOffset + 0x04); - unk_8 = BitConverter::ToUInt32BE(nRawData, fileOffset + 0x08); - - if (unk_4 != 0) - { - uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); - - for (size_t i = 0; i < unk_2; i++) - { - unk_4_arr.emplace_back(parent, nRawData, unk_4_Offset, i); - } - } -} - -Struct_800A5E28::~Struct_800A5E28() -{ - delete unk_8_dlist; -} - -void Struct_800A5E28::DeclareReferences(const std::string& prefix) -{ - if (unk_4 != 0) - { - uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); - std::string unk_4_Str = - StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), - Struct_800A598C::GetSourceTypeName().c_str(), unk_4_Offset); - - std::string entryStr = ""; - uint16_t arrayItemCnt = unk_4_arr.size(); - - size_t i = 0; - - for (auto& child : unk_4_arr) - { - child.DeclareReferences(prefix); - entryStr += - StringHelper::Sprintf(" { %s },%s", child.GetSourceOutputCode(prefix).c_str(), - (++i < arrayItemCnt) ? "\n" : ""); - } - - Declaration* decl = parent->GetDeclaration(unk_4_Offset); - - if (decl == nullptr) - { - parent->AddDeclarationArray(unk_4_Offset, DeclarationAlignment::None, - arrayItemCnt * Struct_800A598C::GetRawDataSize(), - Struct_800A598C::GetSourceTypeName(), unk_4_Str, - arrayItemCnt, entryStr); - } - else - { - decl->text = entryStr; - } - } - - if (unk_8 != 0) - { - 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(unk_8_Offset, dlistLength, parent); - - std::string dListStr = - StringHelper::Sprintf("%sSkinLimbDL_%06X", prefix.c_str(), unk_8_Offset); - unk_8_dlist->SetName(dListStr); - unk_8_dlist->GetSourceOutputCode(prefix); - } -} - -std::string Struct_800A5E28::GetSourceOutputCode(const std::string& prefix) const -{ - std::string entryStr = ""; - - std::string unk_4_Str = "NULL"; - - if (unk_4 != 0) - { - uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); - Declaration* decl = parent->GetDeclaration(unk_4_Offset); - - if (decl == nullptr) - { - unk_4_Str = - StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), - Struct_800A598C::GetSourceTypeName().c_str(), unk_4_Offset); - } - else - { - unk_4_Str = decl->varName; - } - } - - std::string unk_8_Str = "NULL"; - if (unk_8 != 0) - { - uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); - Declaration* decl = parent->GetDeclaration(unk_8_Offset); - if (decl == nullptr) - { - // Something went wrong... - unk_8_Str = StringHelper::Sprintf("0x%08X", unk_8); - } - else - { - unk_8_Str = decl->varName; - } - } - - return StringHelper::Sprintf("\n %i, ARRAY_COUNTU(%s),\n %s, %s\n", unk_0, - unk_4_Str.c_str(), unk_4_Str.c_str(), unk_8_Str.c_str()); -} - -size_t Struct_800A5E28::GetRawDataSize() -{ - return 0x0C; -} - -std::string Struct_800A5E28::GetSourceTypeName() -{ - return "Struct_800A5E28"; -} - -ZLimb::ZLimb(ZFile* nParent) : ZResource(nParent) -{ - dListPtr = 0; - dList2Ptr = 0; RegisterOptionalAttribute("LimbType"); RegisterOptionalAttribute("Type"); } -ZLimb::ZLimb(ZLimbType limbType, const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent) - : ZLimb(nParent) +void ZLimb::ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nType) { rawDataIndex = nRawDataIndex; - parent = nParent; - type = limbType; + type = nType; - name = StringHelper::Sprintf("%sLimb_%06X", prefix.c_str(), GetFileAddress()); + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; ParseRawData(); } -void ZLimb::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - - parent->AddDeclaration(GetFileAddress(), DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), name, ""); -} - void ZLimb::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); @@ -385,37 +37,29 @@ void ZLimb::ParseXML(tinyxml2::XMLElement* reader) if (limbType == "") { - fprintf(stderr, - "ZLimb::ParseXML: Warning in '%s'.\n" - "\t Missing 'LimbType' attribute in xml.\n" - "\t Defaulting to 'Standard'.\n", - name.c_str()); - type = ZLimbType::Standard; + throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n" + "\t Missing 'LimbType' attribute in xml.\n", + name.c_str())); } - else + + type = GetTypeByAttributeName(limbType); + if (type == ZLimbType::Invalid) { - type = GetTypeByAttributeName(limbType); - if (type == ZLimbType::Invalid) - { - fprintf(stderr, - "ZLimb::ParseXML: Warning in '%s'.\n" - "\t Invalid LimbType found: '%s'.\n" - "\t Defaulting to 'Standard'.\n", - name.c_str(), limbType.c_str()); - type = ZLimbType::Standard; - } + throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n" + "\t Invalid 'LimbType' found: '%s'.\n", + name.c_str(), limbType.c_str())); } } void ZLimb::ParseRawData() { ZResource::ParseRawData(); - const auto& rawData = parent->GetRawData(); + if (type == ZLimbType::Curve) { - childIndex = rawData.at(rawDataIndex + 0); - siblingIndex = rawData.at(rawDataIndex + 1); + childIndex = BitConverter::ToUInt8BE(rawData, rawDataIndex + 0); + siblingIndex = BitConverter::ToUInt8BE(rawData, rawDataIndex + 1); dListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4); dList2Ptr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); @@ -455,12 +99,16 @@ void ZLimb::ParseRawData() skinSegmentType = static_cast(BitConverter::ToInt32BE(rawData, rawDataIndex + 8)); skinSegment = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12); - if (skinSegmentType == ZLimbSkinType::SkinType_4 && skinSegment != 0) + if (skinSegmentType == ZLimbSkinType::SkinType_4) { - uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress); - segmentStruct = Struct_800A5E28(parent, rawData, skinSegmentOffset); + if (skinSegment != 0 && GETSEGNUM(skinSegment) == parent->segment) + { + uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress); + segmentStruct.ExtractFromFile(skinSegmentOffset); + } } break; + default: throw std::runtime_error("Invalid ZLimb type"); break; @@ -469,8 +117,13 @@ void ZLimb::ParseRawData() void ZLimb::DeclareReferences(const std::string& prefix) { - ZResource::DeclareReferences(prefix); + std::string varPrefix = name; + if (varPrefix == "") + varPrefix = prefix; + ZResource::DeclareReferences(varPrefix); + + std::string suffix; switch (type) { case ZLimbType::Legacy: @@ -479,8 +132,10 @@ void ZLimb::DeclareReferences(const std::string& prefix) uint32_t childOffset = Seg2Filespace(childPtr, parent->baseAddress); if (!parent->HasDeclaration(childOffset)) { - ZLimb* child = new ZLimb(ZLimbType::Legacy, prefix, childOffset, parent); - child->GetSourceOutputCode(prefix); + ZLimb* child = new ZLimb(parent); + child->ExtractFromBinary(childOffset, ZLimbType::Legacy); + child->DeclareVar(varPrefix, ""); + child->DeclareReferences(varPrefix); parent->AddResource(child); } } @@ -489,18 +144,47 @@ void ZLimb::DeclareReferences(const std::string& prefix) uint32_t siblingdOffset = Seg2Filespace(siblingPtr, parent->baseAddress); if (!parent->HasDeclaration(siblingdOffset)) { - ZLimb* sibling = new ZLimb(ZLimbType::Legacy, prefix, siblingdOffset, parent); - sibling->GetSourceOutputCode(prefix); + ZLimb* sibling = new ZLimb(parent); + sibling->ExtractFromBinary(siblingdOffset, ZLimbType::Legacy); + sibling->DeclareVar(varPrefix, ""); + sibling->DeclareReferences(varPrefix); parent->AddResource(sibling); } } break; - // TODO - case ZLimbType::Standard: - case ZLimbType::LOD: - case ZLimbType::Skin: 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: @@ -530,18 +214,20 @@ size_t ZLimb::GetRawDataSize() const return 0x0C; } -std::string ZLimb::GetSourceOutputCode(const std::string& prefix) +std::string ZLimb::GetBodySourceCode() const { - std::string limbPrefix = type == ZLimbType::Curve ? "Curve" : ""; - std::string dListStr = GetLimbDListSourceOutputCode(prefix, limbPrefix, dListPtr); - limbPrefix = type == ZLimbType::Curve ? "Curve" : "Far"; - std::string dListStr2 = GetLimbDListSourceOutputCode(prefix, limbPrefix, dList2Ptr); + std::string dListStr; + std::string dListStr2; + Globals::Instance->GetSegmentedArrayIndexedName(dListPtr, 8, parent, "Gfx", dListStr); + Globals::Instance->GetSegmentedArrayIndexedName(dList2Ptr, 8, parent, "Gfx", dListStr2); std::string entryStr = "\n\t"; if (type == ZLimbType::Legacy) { - std::string childName = parent->GetDeclarationPtrName(childPtr); - std::string siblingName = parent->GetDeclarationPtrName(siblingPtr); + std::string childName; + std::string siblingName; + Globals::Instance->GetSegmentedPtrName(childPtr, parent, "Gfx", childName); + Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "Gfx", siblingName); entryStr += StringHelper::Sprintf("%s,\n", dListStr.c_str()); entryStr += @@ -556,24 +242,28 @@ std::string ZLimb::GetSourceOutputCode(const std::string& prefix) { entryStr += StringHelper::Sprintf("{ %i, %i, %i }, ", transX, transY, transZ); } - entryStr += StringHelper::Sprintf("0x%02X, 0x%02X,\n", childIndex, siblingIndex); switch (type) { case ZLimbType::Standard: - entryStr += StringHelper::Sprintf(" %s\n", dListStr.c_str()); + entryStr += StringHelper::Sprintf("\t%s\n", dListStr.c_str()); break; case ZLimbType::LOD: case ZLimbType::Curve: entryStr += - StringHelper::Sprintf(" { %s, %s }\n", dListStr.c_str(), dListStr2.c_str()); + StringHelper::Sprintf("\t{ %s, %s }\n", dListStr.c_str(), dListStr2.c_str()); break; case ZLimbType::Skin: - entryStr += GetSourceOutputCodeSkin(prefix); - break; + { + std::string skinSegmentStr; + Globals::Instance->GetSegmentedPtrName(skinSegment, parent, "", skinSegmentStr); + entryStr += + StringHelper::Sprintf("\t0x%02X, %s\n", skinSegmentType, skinSegmentStr.c_str()); + } + break; case ZLimbType::Legacy: break; @@ -583,15 +273,12 @@ std::string ZLimb::GetSourceOutputCode(const std::string& prefix) } } - Declaration* decl = parent->GetDeclaration(GetFileAddress()); + return entryStr; +} - if (decl == nullptr) - parent->AddDeclaration(GetFileAddress(), DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), name, entryStr); - else - decl->text = entryStr; - - return ""; +std::string ZLimb::GetDefaultName(const std::string& prefix) const +{ + return StringHelper::Sprintf("%sLimb_%06X", prefix.c_str(), rawDataIndex); } std::string ZLimb::GetSourceTypeName() const @@ -663,126 +350,34 @@ ZLimbType ZLimb::GetTypeByAttributeName(const std::string& attrName) return ZLimbType::Invalid; } -uint32_t ZLimb::GetFileAddress() +void ZLimb::DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix, + const std::string& limbSuffix) { - return Seg2Filespace(rawDataIndex, parent->baseAddress); -} + if (dListSegmentedPtr == 0 || GETSEGNUM(dListSegmentedPtr) != parent->segment) + return; -// Returns the ptrname of a dlist. Declares it if it has not been declared yet. -std::string ZLimb::GetLimbDListSourceOutputCode(const std::string& prefix, - const std::string& limbPrefix, segptr_t dListPtr) -{ - if (dListPtr == 0) - return "NULL"; + uint32_t dlistOffset = Seg2Filespace(dListSegmentedPtr, parent->baseAddress); + if (parent->HasDeclaration(dlistOffset)) + return; - uint32_t dListOffset = Seg2Filespace(dListPtr, parent->baseAddress); + if (!parent->IsOffsetInFileRange(dlistOffset) || dlistOffset >= parent->GetRawData().size()) + return; - // Check if pointing past the object's size - if (dListOffset > parent->GetRawData().size()) - return StringHelper::Sprintf("0x%08X", dListPtr); - - // Check if it is already declared - Declaration* decl = parent->GetDeclaration(dListOffset); - if (decl != nullptr) - return decl->varName; - - // Check if it points to the middle of a DList - decl = parent->GetDeclarationRanged(dListOffset); - if (decl != nullptr) - { - // TODO: Figure out a way to not hardcode the "Gfx" type. - if (decl->varType == "Gfx") - { - uint32_t declAddress = parent->GetDeclarationRangedAddress(dListOffset); - if (dListOffset < declAddress + decl->size) - { - uint32_t index = (dListOffset - declAddress) / 8; - return StringHelper::Sprintf("&%s[%u]", decl->varName.c_str(), index); - } - } - } - - // Create the DList - std::string dListStr = - StringHelper::Sprintf("%s%sLimbDL_%06X", prefix.c_str(), limbPrefix.c_str(), dListOffset); + std::string dlistName; + bool declFound = Globals::Instance->GetSegmentedArrayIndexedName(dListSegmentedPtr, 8, parent, + "Gfx", dlistName); + if (declFound) + return; int32_t dlistLength = ZDisplayList::GetDListLength( - parent->GetRawData(), dListOffset, + parent->GetRawData(), dlistOffset, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); - auto dList = new ZDisplayList(dListOffset, dlistLength, parent); - dList->SetName(dListStr); - dList->GetSourceOutputCode(prefix); - return dListStr; -} - -std::string ZLimb::GetSourceOutputCodeSkin_Type_4(const std::string& prefix) -{ - assert(type == ZLimbType::Skin); - assert(skinSegmentType == ZLimbSkinType::SkinType_4); - - if (skinSegment == 0) - return "NULL"; - - uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress); - - std::string struct_800A5E28_Str; - Declaration* decl = parent->GetDeclaration(skinSegmentOffset); - if (decl == nullptr) - { - struct_800A5E28_Str = - StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), - Struct_800A5E28::GetSourceTypeName().c_str(), skinSegmentOffset); - - segmentStruct.DeclareReferences(prefix); - std::string entryStr = segmentStruct.GetSourceOutputCode(prefix); - - parent->AddDeclaration(skinSegmentOffset, DeclarationAlignment::None, - Struct_800A5E28::GetRawDataSize(), - Struct_800A5E28::GetSourceTypeName(), struct_800A5E28_Str, entryStr); - } - else - { - struct_800A5E28_Str = decl->varName; - } - - return struct_800A5E28_Str; -} - -std::string ZLimb::GetSourceOutputCodeSkin(const std::string& prefix) -{ - assert(type == ZLimbType::Skin); - - std::string skinSegmentStr = "NULL"; - - if (skinSegment != 0) - { - switch (skinSegmentType) - { - case ZLimbSkinType::SkinType_4: - skinSegmentStr = "&" + GetSourceOutputCodeSkin_Type_4(prefix); - break; - case ZLimbSkinType::SkinType_DList: - skinSegmentStr = GetLimbDListSourceOutputCode(prefix, "Skin", skinSegment); - break; - default: - fprintf(stderr, - "ZLimb::GetSourceOutputCodeSkinType: Error in '%s'.\n\t Unknown segment type " - "for SkinLimb: '%i'. \n\tPlease report this.\n", - name.c_str(), static_cast(skinSegmentType)); - break; - case ZLimbSkinType::SkinType_0: - case ZLimbSkinType::SkinType_5: - fprintf(stderr, - "ZLimb::GetSourceOutputCodeSkinType: Error in '%s'.\n\t Segment type for " - "SkinLimb not implemented: '%i'.\n", - name.c_str(), static_cast(skinSegmentType)); - skinSegmentStr = StringHelper::Sprintf("0x%08X", skinSegment); - break; - } - } - - std::string entryStr = - StringHelper::Sprintf(" 0x%02X, %s\n", skinSegmentType, skinSegmentStr.c_str()); - - return entryStr; + 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); } diff --git a/tools/ZAPD/ZAPD/ZLimb.h b/tools/ZAPD/ZAPD/ZLimb.h index affc7b49da..53a4143292 100644 --- a/tools/ZAPD/ZAPD/ZLimb.h +++ b/tools/ZAPD/ZAPD/ZLimb.h @@ -3,6 +3,8 @@ #include #include #include + +#include "OtherStructs/SkinLimbStructs.h" #include "ZDisplayList.h" #include "ZFile.h" @@ -16,117 +18,14 @@ enum class ZLimbType Legacy, }; -// 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 -{ -protected: - 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; - -public: - Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset); - Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset, size_t index); - - [[nodiscard]] std::string GetSourceOutputCode() const; - - static size_t GetRawDataSize(); - static std::string GetSourceTypeName(); -}; - -class Struct_800A598C_2 -{ -protected: - uint8_t unk_0; - int16_t x; - int16_t y; - int16_t z; - uint8_t unk_8; - -public: - Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset); - Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset, size_t index); - - [[nodiscard]] std::string GetSourceOutputCode() const; - - static size_t GetRawDataSize(); - static std::string GetSourceTypeName(); -}; - -class Struct_800A598C -{ -protected: - ZFile* parent; - - 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 unk_8_arr; - std::vector unk_C_arr; - -public: - Struct_800A598C(ZFile* parent, const std::vector& rawData, uint32_t fileOffset); - Struct_800A598C(ZFile* parent, const std::vector& rawData, uint32_t fileOffset, - size_t index); - - void DeclareReferences(const std::string& prefix); - [[nodiscard]] std::string GetSourceOutputCode(const std::string& prefix) const; - - static size_t GetRawDataSize(); - static std::string GetSourceTypeName(); -}; - -class Struct_800A5E28 -{ -protected: - ZFile* parent; - - 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 unk_4_arr; - ZDisplayList* unk_8_dlist = nullptr; - -public: - Struct_800A5E28() = default; - Struct_800A5E28(ZFile* parent, const std::vector& rawData, uint32_t fileOffset); - Struct_800A5E28(ZFile* parent, const std::vector& rawData, uint32_t fileOffset, - size_t index); - ~Struct_800A5E28(); - - void DeclareReferences(const std::string& prefix); - [[nodiscard]] std::string GetSourceOutputCode(const std::string& prefix) const; - - static size_t GetRawDataSize(); - static std::string GetSourceTypeName(); -}; - class ZLimb : public ZResource { -protected: +public: ZLimbType type = ZLimbType::Standard; ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only segptr_t skinSegment = 0; // Skin only Struct_800A5E28 segmentStruct; // Skin only - segptr_t dList2Ptr; // LOD and Curve Only // Legacy only float legTransX, legTransY, legTransZ; // Vec3f @@ -134,29 +33,24 @@ protected: segptr_t childPtr; // LegacyLimb* segptr_t siblingPtr; // LegacyLimb* - std::string GetLimbDListSourceOutputCode(const std::string& prefix, - const std::string& limbPrefix, segptr_t dListPtr); - - std::string GetSourceOutputCodeSkin(const std::string& prefix); - std::string GetSourceOutputCodeSkin_Type_4(const std::string& prefix); - -public: segptr_t dListPtr = 0; - segptr_t farDListPtr = 0; // LOD only + segptr_t dList2Ptr = 0; // LOD and Curve Only + int16_t transX, transY, transZ; uint8_t childIndex, siblingIndex; ZLimb(ZFile* nParent); - ZLimb(ZLimbType limbType, const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent); - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; + 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 GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; @@ -165,6 +59,7 @@ public: static const char* GetSourceTypeName(ZLimbType limbType); static ZLimbType GetTypeByAttributeName(const std::string& attrName); - uint32_t GetFileAddress(); - void SetFileAddress(uint32_t nAddress); +protected: + void DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix, + const std::string& limbSuffix); }; diff --git a/tools/ZAPD/ZAPD/ZMtx.cpp b/tools/ZAPD/ZAPD/ZMtx.cpp index 87918b8ce7..b9ca3f22d2 100644 --- a/tools/ZAPD/ZAPD/ZMtx.cpp +++ b/tools/ZAPD/ZAPD/ZMtx.cpp @@ -1,4 +1,5 @@ #include "ZMtx.h" + #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -9,13 +10,6 @@ ZMtx::ZMtx(ZFile* nParent) : ZResource(nParent) { } -ZMtx::ZMtx(const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent) : ZResource(nParent) -{ - name = GetDefaultName(prefix.c_str(), rawDataIndex); - ExtractFromFile(nRawDataIndex); - DeclareVar("", ""); -} - void ZMtx::ParseRawData() { ZResource::ParseRawData(); @@ -26,28 +20,11 @@ void ZMtx::ParseRawData() mtx[i][j] = BitConverter::ToInt32BE(rawData, rawDataIndex + (i * 4 + j) * 4); } -void ZMtx::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - DeclareVar("", ""); -} - size_t ZMtx::GetRawDataSize() const { return 64; } -void ZMtx::DeclareVar(const std::string& prefix, const std::string& bodyStr) const -{ - std::string auxName = name; - - if (name == "") - auxName = GetDefaultName(prefix, rawDataIndex); - - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align8, GetRawDataSize(), - GetSourceTypeName(), auxName, bodyStr); -} - std::string ZMtx::GetBodySourceCode() const { std::string bodyStr = "\n"; @@ -65,25 +42,6 @@ std::string ZMtx::GetBodySourceCode() const return bodyStr; } -std::string ZMtx::GetSourceOutputCode(const std::string& prefix) -{ - std::string bodyStr = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - - if (decl == nullptr) - DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - - return ""; -} - -std::string ZMtx::GetDefaultName(const std::string& prefix, uint32_t address) -{ - return StringHelper::Sprintf("%sMtx_%06X", prefix.c_str(), address); -} - std::string ZMtx::GetSourceTypeName() const { return "Mtx"; @@ -93,3 +51,8 @@ ZResourceType ZMtx::GetResourceType() const { return ZResourceType::Mtx; } + +DeclarationAlignment ZMtx::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align8; +} diff --git a/tools/ZAPD/ZAPD/ZMtx.h b/tools/ZAPD/ZAPD/ZMtx.h index 5a4d1efe6a..eed502374b 100644 --- a/tools/ZAPD/ZAPD/ZMtx.h +++ b/tools/ZAPD/ZAPD/ZMtx.h @@ -8,22 +8,17 @@ class ZMtx : public ZResource { public: ZMtx(ZFile* nParent); - ZMtx(const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent); void ParseRawData() override; - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; - - size_t GetRawDataSize() const override; - - void DeclareVar(const std::string& prefix, const std::string& bodyStr) const; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; - static std::string GetDefaultName(const std::string& prefix, uint32_t address); std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; + size_t GetRawDataSize() const override; + DeclarationAlignment GetDeclarationAlignment() const override; + protected: std::array, 4> mtx; }; diff --git a/tools/ZAPD/ZAPD/ZPath.cpp b/tools/ZAPD/ZAPD/ZPath.cpp index c7be85268c..4a95c5b91e 100644 --- a/tools/ZAPD/ZAPD/ZPath.cpp +++ b/tools/ZAPD/ZAPD/ZPath.cpp @@ -13,14 +13,6 @@ ZPath::ZPath(ZFile* nParent) : ZResource(nParent) RegisterOptionalAttribute("NumPaths", "1"); } -void ZPath::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, pathways.size() * 8, - GetSourceTypeName(), name, pathways.size(), ""); -} - void ZPath::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); @@ -43,8 +35,7 @@ void ZPath::ParseRawData() for (size_t pathIndex = 0; pathIndex < numPaths; pathIndex++) { PathwayEntry path(parent); - path.SetRawDataIndex(currentPtr); - path.ParseRawData(); + path.ExtractFromFile(currentPtr); if (path.GetListAddress() == 0) break; @@ -62,9 +53,23 @@ void ZPath::DeclareReferences(const std::string& prefix) 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 = ""; + std::string declaration; size_t index = 0; for (const auto& entry : pathways) @@ -80,20 +85,6 @@ std::string ZPath::GetBodySourceCode() const return declaration; } -std::string ZPath::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - std::string declaration = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr || decl->isPlaceholder) - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, pathways.size() * 8, - GetSourceTypeName(), name, pathways.size(), declaration); - else - decl->text = declaration; - - return ""; -} - std::string ZPath::GetSourceTypeName() const { return "Path"; @@ -134,10 +125,7 @@ void PathwayEntry::ParseRawData() for (int32_t i = 0; i < numPoints; i++) { ZVector vec(parent); - vec.SetRawDataIndex(currentPtr); - vec.SetScalarType(ZScalarType::ZSCALAR_S16); - vec.SetDimensions(3); - vec.ParseRawData(); + vec.ExtractFromBinary(currentPtr, ZScalarType::ZSCALAR_S16, 3); currentPtr += vec.GetRawDataSize(); points.push_back(vec); @@ -150,12 +138,18 @@ void PathwayEntry::DeclareReferences(const std::string& prefix) if (points.empty()) return; - std::string declaration = ""; + std::string pointsName; + bool addressFound = + Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", pointsName); + if (addressFound) + return; + + std::string declaration; size_t index = 0; for (const auto& point : points) { - declaration += StringHelper::Sprintf("\t%s,", point.GetBodySourceCode().c_str()); + declaration += StringHelper::Sprintf("\t{ %s },", point.GetBodySourceCode().c_str()); if (index < points.size() - 1) declaration += "\n"; @@ -163,14 +157,13 @@ void PathwayEntry::DeclareReferences(const std::string& prefix) index++; } - Declaration* decl = parent->GetDeclaration(GETSEGOFFSET(listSegmentAddress)); + uint32_t pointsOffset = Seg2Filespace(listSegmentAddress, parent->baseAddress); + Declaration* decl = parent->GetDeclaration(pointsOffset); if (decl == nullptr) { - parent->AddDeclarationArray(GETSEGOFFSET(listSegmentAddress), DeclarationAlignment::Align4, - DeclarationPadding::Pad4, points.size() * 6, - points.at(0).GetSourceTypeName(), - StringHelper::Sprintf("%sPathwayList0x%06X", prefix.c_str(), - GETSEGOFFSET(listSegmentAddress)), + 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 @@ -179,8 +172,9 @@ void PathwayEntry::DeclareReferences(const std::string& prefix) std::string PathwayEntry::GetBodySourceCode() const { - std::string declaration = ""; - std::string listName = parent->GetDeclarationPtrName(listSegmentAddress); + std::string declaration; + std::string listName; + Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", listName); if (Globals::Instance->game == ZGame::MM_RETAIL) declaration += diff --git a/tools/ZAPD/ZAPD/ZPath.h b/tools/ZAPD/ZAPD/ZPath.h index 21394fa568..e519decff4 100644 --- a/tools/ZAPD/ZAPD/ZPath.h +++ b/tools/ZAPD/ZAPD/ZPath.h @@ -32,14 +32,12 @@ class ZPath : public ZResource public: ZPath(ZFile* nParent); - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; - 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 GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; diff --git a/tools/ZAPD/ZAPD/ZPlayerAnimationData.cpp b/tools/ZAPD/ZAPD/ZPlayerAnimationData.cpp new file mode 100644 index 0000000000..a96604fda0 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZPlayerAnimationData.cpp @@ -0,0 +1,97 @@ +#include "ZPlayerAnimationData.h" + +#include "Utils/BitConverter.h" +#include "Utils/StringHelper.h" +#include "ZFile.h" + +REGISTER_ZFILENODE(PlayerAnimationData, ZPlayerAnimationData); + +ZPlayerAnimationData::ZPlayerAnimationData(ZFile* nParent) : ZResource(nParent) +{ + RegisterRequiredAttribute("FrameCount"); +} + +void ZPlayerAnimationData::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); + + std::string& frameCountXml = registeredAttributes.at("FrameCount").value; + + frameCount = StringHelper::StrToL(frameCountXml); +} + +void ZPlayerAnimationData::ParseRawData() +{ + ZResource::ParseRawData(); + + const auto& rawData = parent->GetRawData(); + + size_t totalSize = GetRawDataSize(); + // Divided by 2 because each value is an s16 + limbRotData.reserve(totalSize * frameCount / 2); + + for (size_t i = 0; i < totalSize; i += 2) + { + limbRotData.push_back(BitConverter::ToUInt16BE(rawData, rawDataIndex + i)); + } +} + +Declaration* ZPlayerAnimationData::DeclareVar(const std::string& prefix, const std::string& bodyStr) +{ + std::string auxName = name; + + if (auxName == "") + auxName = GetDefaultName(prefix); + + Declaration* decl = + parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), + GetSourceTypeName(), name, limbRotData.size(), bodyStr); + decl->staticConf = staticConf; + return decl; +} + +std::string ZPlayerAnimationData::GetBodySourceCode() const +{ + std::string declaration = ""; + + size_t index = 0; + for (const auto& entry : limbRotData) + { + if (index % 8 == 0) + { + declaration += "\t"; + } + + declaration += StringHelper::Sprintf("0x%04X, ", entry); + + if ((index + 1) % 8 == 0) + { + declaration += "\n"; + } + + index++; + } + + return declaration; +} + +std::string ZPlayerAnimationData::GetDefaultName(const std::string& prefix) const +{ + return StringHelper::Sprintf("%sPlayerAnimationData_%06X", prefix.c_str(), rawDataIndex); +} + +std::string ZPlayerAnimationData::GetSourceTypeName() const +{ + return "s16"; +} + +ZResourceType ZPlayerAnimationData::GetResourceType() const +{ + return ZResourceType::PlayerAnimationData; +} + +size_t ZPlayerAnimationData::GetRawDataSize() const +{ + // (sizeof(Vec3s) * limbCount + 2) * frameCount + return (6 * 22 + 2) * frameCount; +} diff --git a/tools/ZAPD/ZAPD/ZPlayerAnimationData.h b/tools/ZAPD/ZAPD/ZPlayerAnimationData.h new file mode 100644 index 0000000000..20835f2369 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZPlayerAnimationData.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +#include "ZResource.h" + +class ZPlayerAnimationData : public ZResource +{ +public: + int16_t frameCount = 0; + std::vector limbRotData; + + ZPlayerAnimationData(ZFile* nParent); + + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; + + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; + + std::string GetBodySourceCode() const override; + std::string GetDefaultName(const std::string& prefix) const override; + + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; +}; diff --git a/tools/ZAPD/ZAPD/ZResource.cpp b/tools/ZAPD/ZAPD/ZResource.cpp index bff7037d47..cb811f4c3b 100644 --- a/tools/ZAPD/ZAPD/ZResource.cpp +++ b/tools/ZAPD/ZAPD/ZResource.cpp @@ -2,6 +2,7 @@ #include #include + #include "Utils/StringHelper.h" #include "ZFile.h" @@ -19,23 +20,43 @@ ZResource::ZResource(ZFile* nParent) RegisterOptionalAttribute("OutName"); RegisterOptionalAttribute("Offset"); RegisterOptionalAttribute("Custom"); + RegisterOptionalAttribute("Static", "Global"); } -void ZResource::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) +void ZResource::ExtractFromXML(tinyxml2::XMLElement* reader, offset_t nRawDataIndex) { rawDataIndex = nRawDataIndex; + declaredInXml = true; if (reader != nullptr) ParseXML(reader); - ParseRawData(); - CalcHash(); + // Don't parse raw data of external files + if (parent->GetMode() != ZFileMode::ExternalFile) + { + ParseRawData(); + CalcHash(); + } + + if (!isInner) + { + Declaration* decl = DeclareVar(parent->GetName(), ""); + if (decl != nullptr) + { + decl->declaredInXml = true; + decl->staticConf = staticConf; + } + } } -void ZResource::ExtractFromFile(uint32_t nRawDataIndex) +void ZResource::ExtractFromFile(offset_t nRawDataIndex) { rawDataIndex = nRawDataIndex; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); CalcHash(); } @@ -110,6 +131,24 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) isCustomAsset = registeredAttributes["Custom"].wasSet; + std::string& staticXml = registeredAttributes["Static"].value; + if (staticXml == "Global") + { + staticConf = StaticConfig::Global; + } + else if (staticXml == "On") + { + staticConf = StaticConfig::On; + } + else if (staticXml == "Off") + { + staticConf = StaticConfig::Off; + } + else + { + throw std::runtime_error("Invalid value for 'Static' attribute."); + } + declaredInXml = true; } } @@ -130,6 +169,20 @@ void ZResource::DeclareReferencesLate([[maybe_unused]] const std::string& prefix { } +Declaration* ZResource::DeclareVar(const std::string& prefix, const std::string& bodyStr) +{ + std::string auxName = name; + + if (name == "") + auxName = GetDefaultName(prefix); + + Declaration* decl = + parent->AddDeclaration(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), + GetSourceTypeName(), auxName, bodyStr); + decl->staticConf = staticConf; + return decl; +} + void ZResource::Save([[maybe_unused]] const fs::path& outFolder) { } @@ -169,19 +222,24 @@ std::string ZResource::GetExternalExtension() const return ""; } +DeclarationAlignment ZResource::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align4; +} + bool ZResource::WasDeclaredInXml() const { return declaredInXml; } -uint32_t ZResource::GetRawDataIndex() const +StaticConfig ZResource::GetStaticConf() const { - return rawDataIndex; + return staticConf; } -void ZResource::SetRawDataIndex(uint32_t value) +offset_t ZResource::GetRawDataIndex() const { - rawDataIndex = value; + return rawDataIndex; } std::string ZResource::GetBodySourceCode() const @@ -189,8 +247,23 @@ std::string ZResource::GetBodySourceCode() const return "ERROR"; } +std::string ZResource::GetDefaultName(const std::string& prefix) const +{ + return StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), GetSourceTypeName().c_str(), + rawDataIndex); +} + std::string ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) { + std::string bodyStr = GetBodySourceCode(); + + Declaration* decl = parent->GetDeclaration(rawDataIndex); + if (decl == nullptr || decl->isPlaceholder) + decl = DeclareVar(prefix, bodyStr); + else + decl->text = bodyStr; + decl->staticConf = staticConf; + return ""; } @@ -230,12 +303,24 @@ void ZResource::RegisterOptionalAttribute(const std::string& attr, const std::st registeredAttributes[attr] = resAtrr; } -uint32_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress) +offset_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress) { - uint32_t currentPtr = GETSEGOFFSET(segmentedAddress); + offset_t currentPtr = GETSEGOFFSET(segmentedAddress); if (GETSEGNUM(segmentedAddress) == 0x80) // Is defined in code? - currentPtr -= GETSEGOFFSET(parentBaseAddress); + { + uint32_t parentBaseOffset = GETSEGOFFSET(parentBaseAddress); + if (parentBaseOffset > currentPtr) + { + throw std::runtime_error( + StringHelper::Sprintf("\nSeg2Filespace: Segmented address is smaller than " + "'BaseAddress'. Maybe your 'BaseAddress' is wrong?\n" + "\t SegmentedAddress: 0x%08X\n" + "\t BaseAddress: 0x%08X\n", + segmentedAddress, parentBaseAddress)); + } + currentPtr -= parentBaseOffset; + } return currentPtr; } diff --git a/tools/ZAPD/ZAPD/ZResource.h b/tools/ZAPD/ZAPD/ZResource.h index 71d91ee2b3..ff35786fac 100644 --- a/tools/ZAPD/ZAPD/ZResource.h +++ b/tools/ZAPD/ZAPD/ZResource.h @@ -21,8 +21,6 @@ #define GETSEGOFFSET(x) (x & 0x00FFFFFF) #define GETSEGNUM(x) ((x >> 24) & 0xFF) -typedef uint32_t segptr_t; - class ZFile; enum class ZResourceType @@ -40,6 +38,7 @@ enum class ZResourceType LimbTable, Mtx, Path, + PlayerAnimationData, Room, RoomCommand, Scalar, @@ -57,8 +56,8 @@ enum class ZResourceType class ResourceAttribute { public: - std::string key = ""; - std::string value = ""; + std::string key; + std::string value; bool isRequired = false; bool wasSet = false; }; @@ -70,54 +69,127 @@ public: bool outputDeclaration = true; uint32_t hash = 0; + /** + * Constructor. + * Child classes should not declare any other constructor besides this one + */ ZResource(ZFile* nParent); virtual ~ZResource() = default; // Parsing from File - virtual void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex); - virtual void ExtractFromFile(uint32_t nRawDataIndex); + virtual void ExtractFromXML(tinyxml2::XMLElement* reader, offset_t nRawDataIndex); + virtual void ExtractFromFile(offset_t nRawDataIndex); // Misc + /** + * Parses additional attributes of the XML node. + * Extra attritbutes have to be registered using `RegisterRequiredAttribute` or + * `RegisterOptionalAttribute` in the constructor of the ZResource + */ virtual void ParseXML(tinyxml2::XMLElement* reader); + /** + * Extracts data from the binary file + */ virtual void ParseRawData(); + /** + * Declares any data pointed by this resource that has not been declared already. + * For example, a Vtx referenced by a Dlist should be declared here if it wasn't + * declared previously by something else + */ virtual void DeclareReferences(const std::string& prefix); virtual void ParseRawDataLate(); virtual void DeclareReferencesLate(const std::string& prefix); - virtual std::string GetBodySourceCode() const; + + /** + * Adds this resource as a Declaration of its parent ZFile + */ + virtual Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr); + /** + * Returns the body of the variable of the extracted resource, without any side-effect + */ + [[nodiscard]] virtual std::string GetBodySourceCode() const; + /** + * Creates an automatically generated variable name for the current resource + */ + [[nodiscard]] virtual std::string GetDefaultName(const std::string& prefix) const; virtual std::string GetSourceOutputCode(const std::string& prefix); virtual std::string GetSourceOutputHeader(const std::string& prefix); virtual void CalcHash(); + /** + * Exports the resource to binary format + */ virtual void Save(const fs::path& outFolder); // Properties + /** + * Returns true if the resource will be externalized, and included back to the C file using + * `#include`s + */ virtual bool IsExternalResource() const; - virtual bool DoesSupportArray() const; // Can this type be wrapped in an node? - virtual std::string GetSourceTypeName() const = 0; - virtual ZResourceType GetResourceType() const = 0; - virtual std::string GetExternalExtension() const; + /** + * Can this type be wrapped in an node? + */ + virtual bool DoesSupportArray() const; + /** + * The type of the resource as a C struct + */ + [[nodiscard]] virtual std::string GetSourceTypeName() const = 0; + /** + * The type in the ZResource enum + */ + [[nodiscard]] virtual ZResourceType GetResourceType() const = 0; + /** + * The filename extension for assets extracted as standalone files + */ + [[nodiscard]] virtual std::string GetExternalExtension() const; // Getters/Setters - const std::string& GetName() const; + [[nodiscard]] const std::string& GetName() const; void SetName(const std::string& nName); - const std::string& GetOutName() const; + [[nodiscard]] const std::string& GetOutName() const; void SetOutName(const std::string& nName); - virtual uint32_t GetRawDataIndex() const; - virtual void SetRawDataIndex(uint32_t value); - virtual size_t GetRawDataSize() const = 0; + [[nodiscard]] offset_t GetRawDataIndex() const; + /** + * The size of the current struct being extracted, not counting data referenced by it + */ + [[nodiscard]] virtual size_t GetRawDataSize() const = 0; + /** + * The alignment of the extracted struct + */ + [[nodiscard]] virtual DeclarationAlignment GetDeclarationAlignment() const; void SetInnerNode(bool inner); - bool WasDeclaredInXml() const; + /** + * Returns `true` if this ZResource was declared using an XML node, + * `false` otherwise (for example, a Vtx extracted indirectly by a DList) + */ + [[nodiscard]] bool WasDeclaredInXml() const; + [[nodiscard]] StaticConfig GetStaticConf() const; protected: std::string name; std::string outName; - uint32_t rawDataIndex; + offset_t rawDataIndex; std::string sourceOutput; - bool isInner = false; // Is this resource an inner node of another resource? inside of - bool canHaveInner = false; // Can this type have an inner node? - bool isCustomAsset; // If set to true, create a reference for the asset in the file, but don't - // actually try to extract it from the file + + // Inner is used mostly for nodes + /** + * Is this resource an inner node of another resource? + * (namely inside an ) + */ + bool isInner = false; + /** + * Can this type have an inner node? + */ + bool canHaveInner = false; + + /** + * If set to true, create a reference for the asset in the file, but don't + * actually try to extract it from the file + */ + bool isCustomAsset; bool declaredInXml = false; + StaticConfig staticConf = StaticConfig::Global; // Reading from this XMLs attributes should be performed in the overrided `ParseXML` method. std::map registeredAttributes; @@ -137,11 +209,12 @@ class ZResourceExporter { public: ZResourceExporter() = default; + virtual ~ZResourceExporter() = default; virtual void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) = 0; }; -uint32_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress); +offset_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress); typedef ZResource*(ZResourceFactoryFunc)(ZFile* nParent); @@ -167,4 +240,4 @@ typedef ZResource*(ZResourceFactoryFunc)(ZFile* nParent); public: \ ZResExp_##expFunc() { expFunc(); } \ }; \ - static ZResExp_##expFunc inst_ZResExp_##expFunc; + static ZResExp_##expFunc inst_ZResExp_##expFunc diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp index 32c50747e7..60391a9d1d 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp @@ -29,7 +29,7 @@ void SetActorCutsceneList::DeclareReferences(const std::string& prefix) { if (cutscenes.size() > 0) { - std::string declaration = ""; + std::string declaration; for (size_t i = 0; i < cutscenes.size(); i++) { @@ -45,15 +45,16 @@ void SetActorCutsceneList::DeclareReferences(const std::string& prefix) std::string typeName = cutscenes.at(0).GetSourceTypeName(); parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::Align4, cutscenes.size() * 16, typeName, + segmentOffset, GetDeclarationAlignment(), cutscenes.size() * 16, typeName, StringHelper::Sprintf("%s%sList_%06X", prefix.c_str(), typeName.c_str(), segmentOffset), - 0, declaration); + cutscenes.size(), declaration); } } std::string SetActorCutsceneList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorCutscene", listName); return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_LIST(%i, %s)", cutscenes.size(), listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp index 64cea558d0..919d86f573 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp @@ -48,7 +48,7 @@ void SetActorList::DeclareReferencesLate(const std::string& prefix) if (actors.empty()) return; - std::string declaration = ""; + std::string declaration; size_t largestlength = 0; for (const auto& entry : actors) @@ -72,19 +72,16 @@ void SetActorList::DeclareReferencesLate(const std::string& prefix) const auto& entry = actors.front(); - DeclarationPadding padding = DeclarationPadding::Pad16; - if (Globals::Instance->game == ZGame::MM_RETAIL) - padding = DeclarationPadding::None; - std::string varName = StringHelper::Sprintf("%sActorList_%06X", prefix.c_str(), segmentOffset); - parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4, padding, + parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4, actors.size() * entry.GetRawDataSize(), entry.GetSourceTypeName(), varName, GetActorListArraySize(), declaration); } std::string SetActorList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName); if (numActors != actors.size()) { printf("%s: numActors(%i) ~ actors(%li)\n", parent->GetName().c_str(), numActors, @@ -140,7 +137,7 @@ ActorSpawnEntry::ActorSpawnEntry(const std::vector& rawData, uint32_t r std::string ActorSpawnEntry::GetBodySourceCode() const { - std::string body = ""; + std::string body; std::string actorNameFmt = StringHelper::Sprintf("%%-%zus ", largestActorName + 1); body = diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp index 4f5461f30d..629d4a0b05 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp @@ -1,5 +1,6 @@ #include "SetAlternateHeaders.h" +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -10,8 +11,12 @@ SetAlternateHeaders::SetAlternateHeaders(ZFile* nParent) : ZRoomCommand(nParent) void SetAlternateHeaders::DeclareReferences([[maybe_unused]] const std::string& prefix) { - if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); + if (cmdArg2 != 0) + { + std::string varName = + StringHelper::Sprintf("%sAlternateHeaders0x%06X", prefix.c_str(), segmentOffset); + parent->AddDeclarationPlaceholder(segmentOffset, varName); + } } void SetAlternateHeaders::ParseRawDataLate() @@ -38,27 +43,30 @@ void SetAlternateHeaders::DeclareReferencesLate(const std::string& prefix) { if (!headers.empty()) { - std::string declaration = ""; + std::string declaration; for (size_t i = 0; i < headers.size(); i++) { - declaration += StringHelper::Sprintf( - "\t%s,", parent->GetDeclarationPtrName(headers.at(i)).c_str()); + std::string altHeaderName; + Globals::Instance->GetSegmentedPtrName(headers.at(i), parent, "", altHeaderName); + + declaration += StringHelper::Sprintf("\t%s,", altHeaderName.c_str()); if (i + 1 < headers.size()) declaration += "\n"; } - parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::Align4, headers.size() * 4, "SceneCmd*", - StringHelper::Sprintf("%sAltHeader_%06X", prefix.c_str(), segmentOffset), 0, - declaration); + std::string varName = + StringHelper::Sprintf("%sAlternateHeaders0x%06X", prefix.c_str(), segmentOffset); + parent->AddDeclarationArray(segmentOffset, GetDeclarationAlignment(), headers.size() * 4, + "SceneCmd*", varName, headers.size(), declaration); } } std::string SetAlternateHeaders::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "SceneCmd*", listName); return StringHelper::Sprintf("SCENE_CMD_ALTERNATE_HEADER_LIST(%s)", listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp index b1b3ed0aeb..0b9a67e0ec 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp @@ -20,8 +20,7 @@ SetAnimatedMaterialList::SetAnimatedMaterialList(ZFile* nParent) void SetAnimatedMaterialList::ParseRawData() { ZRoomCommand::ParseRawData(); - textureAnimation.SetRawDataIndex(segmentOffset); - textureAnimation.ParseRawData(); + textureAnimation.ExtractFromFile(segmentOffset); } void SetAnimatedMaterialList::DeclareReferences(const std::string& prefix) @@ -33,7 +32,8 @@ void SetAnimatedMaterialList::DeclareReferences(const std::string& prefix) std::string SetAnimatedMaterialList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "AnimatedMaterial", listName); return StringHelper::Sprintf("SCENE_CMD_ANIMATED_MATERIAL_LIST(%s)", listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h index fecb9f2a02..3dbbf9684a 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h @@ -1,6 +1,5 @@ #pragma once -#include #include "ZRoom/ZRoomCommand.h" #include "ZTextureAnimation.h" diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp index 22273e0311..03aaa4bbbc 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp @@ -1,5 +1,6 @@ #include "SetCollisionHeader.h" +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -12,21 +13,23 @@ SetCollisionHeader::SetCollisionHeader(ZFile* nParent) : ZRoomCommand(nParent) void SetCollisionHeader::ParseRawData() { ZRoomCommand::ParseRawData(); + collisionHeader = new ZCollisionHeader(parent); - collisionHeader->SetRawDataIndex(segmentOffset); collisionHeader->SetName( StringHelper::Sprintf("%sCollisionHeader_%06X", parent->GetName().c_str(), segmentOffset)); - collisionHeader->ParseRawData(); + collisionHeader->ExtractFromFile(segmentOffset); + parent->AddResource(collisionHeader); } -SetCollisionHeader::~SetCollisionHeader() +void SetCollisionHeader::DeclareReferences(const std::string& prefix) { - delete collisionHeader; + collisionHeader->DeclareVar(prefix, ""); } std::string SetCollisionHeader::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CollisionHeader", listName); return StringHelper::Sprintf("SCENE_CMD_COL_HEADER(%s)", listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.h index b0a599fd06..f7d5ecf358 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.h @@ -9,9 +9,9 @@ public: ZCollisionHeader* collisionHeader; SetCollisionHeader(ZFile* nParent); - ~SetCollisionHeader(); void ParseRawData() override; + void DeclareReferences(const std::string& prefix) override; std::string GetBodySourceCode() const override; diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCsCamera.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCsCamera.cpp index ec41683add..5cf0a3d034 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCsCamera.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCsCamera.cpp @@ -1,5 +1,6 @@ #include "SetCsCamera.h" +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -33,31 +34,23 @@ void SetCsCamera::ParseRawData() for (int32_t i = 0; i < numPoints; i++) { ZVector vec(parent); - vec.SetRawDataIndex(currentPtr); - vec.SetScalarType(ZScalarType::ZSCALAR_S16); - vec.SetDimensions(3); - vec.ParseRawData(); + vec.ExtractFromBinary(currentPtr, ZScalarType::ZSCALAR_S16, 3); currentPtr += vec.GetRawDataSize(); points.push_back(vec); } } - - if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); } void SetCsCamera::DeclareReferences(const std::string& prefix) { if (points.size() > 0) { - std::string declaration = ""; + std::string declaration; size_t index = 0; for (auto& point : points) { - declaration += - StringHelper::Sprintf("\t%s, //0x%06X", point.GetBodySourceCode().c_str(), - cameras.at(0).segmentOffset + (index * 6)); + declaration += StringHelper::Sprintf("\t{ %s },", point.GetBodySourceCode().c_str()); if (index < points.size() - 1) declaration += "\n"; @@ -76,8 +69,10 @@ void SetCsCamera::DeclareReferences(const std::string& prefix) if (!cameras.empty()) { - std::string camPointsName = parent->GetDeclarationName(cameras.at(0).GetSegmentOffset()); - std::string declaration = ""; + std::string camPointsName; + Globals::Instance->GetSegmentedPtrName(cameras.at(0).GetCamAddress(), parent, "Vec3s", + camPointsName); + std::string declaration; size_t index = 0; size_t pointsIndex = 0; @@ -98,8 +93,8 @@ void SetCsCamera::DeclareReferences(const std::string& prefix) std::string camTypename = entry.GetSourceTypeName(); parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::Align4, DeclarationPadding::Pad16, - cameras.size() * entry.GetRawDataSize(), camTypename, + segmentOffset, DeclarationAlignment::Align4, cameras.size() * entry.GetRawDataSize(), + camTypename, StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), camTypename.c_str(), segmentOffset), cameras.size(), declaration); } @@ -107,7 +102,8 @@ void SetCsCamera::DeclareReferences(const std::string& prefix) std::string SetCsCamera::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CsCameraEntry", listName); return StringHelper::Sprintf("SCENE_CMD_ACTOR_CUTSCENE_CAM_LIST(%i, %s)", cameras.size(), listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp index 34707a26f7..e51e550b09 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCutscenes.cpp @@ -19,7 +19,7 @@ SetCutscenes::~SetCutscenes() void SetCutscenes::ParseRawData() { ZRoomCommand::ParseRawData(); - std::string output = ""; + std::string output; numCutscenes = cmdArg1; if (Globals::Instance->game == ZGame::OOT_RETAIL || Globals::Instance->game == ZGame::OOT_SW97) @@ -38,7 +38,7 @@ void SetCutscenes::ParseRawData() else { int32_t currentPtr = segmentOffset; - std::string declaration = ""; + std::string declaration; for (uint8_t i = 0; i < numCutscenes; i++) { @@ -46,8 +46,9 @@ void SetCutscenes::ParseRawData() cutsceneEntries.push_back(entry); currentPtr += 8; + // TODO: don't hardcode %sCutsceneData_%06X, look up for the declared name instead declaration += StringHelper::Sprintf( - " { %sCutsceneData0x%06X, 0x%04X, 0x%02X, 0x%02X },", zRoom->GetName().c_str(), + " { %sCutsceneData_%06X, 0x%04X, 0x%02X, 0x%02X },", zRoom->GetName().c_str(), entry.segmentOffset, entry.exit, entry.entrance, entry.flag); if (i < numCutscenes - 1) @@ -67,9 +68,9 @@ void SetCutscenes::ParseRawData() for (ZCutsceneBase* cutscene : cutscenes) { - if (cutscene->getSegmentOffset() != 0) + if (cutscene->GetRawDataIndex() != 0) { - Declaration* decl = parent->GetDeclaration(cutscene->getSegmentOffset()); + Declaration* decl = parent->GetDeclaration(cutscene->GetRawDataIndex()); if (decl == nullptr) { cutscene->GetSourceOutputCode(zRoom->GetName()); @@ -84,7 +85,8 @@ void SetCutscenes::ParseRawData() std::string SetCutscenes::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "CutsceneData", listName); if (Globals::Instance->game == ZGame::MM_RETAIL) return StringHelper::Sprintf("SCENE_CMD_CUTSCENE_LIST(%i, %s)", numCutscenes, diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.cpp index 9f8a0e0f40..8099bacf12 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetEntranceList.cpp @@ -1,4 +1,6 @@ #include "SetEntranceList.h" + +#include "Globals.h" #include "SetStartPositionList.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -12,7 +14,11 @@ SetEntranceList::SetEntranceList(ZFile* nParent) : ZRoomCommand(nParent) void SetEntranceList::DeclareReferences([[maybe_unused]] const std::string& prefix) { if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); + { + std::string varName = + StringHelper::Sprintf("%sEntranceList0x%06X", prefix.c_str(), segmentOffset); + parent->AddDeclarationPlaceholder(segmentOffset, varName); + } } void SetEntranceList::ParseRawDataLate() @@ -34,30 +40,30 @@ void SetEntranceList::DeclareReferencesLate([[maybe_unused]] const std::string& { if (!entrances.empty()) { - std::string declaration = ""; + std::string declaration; size_t index = 0; for (const auto& entry : entrances) { - declaration += - StringHelper::Sprintf(" { %s }, //0x%06X", entry.GetBodySourceCode().c_str(), - segmentOffset + (index * 2)); + declaration += StringHelper::Sprintf(" { %s },", entry.GetBodySourceCode().c_str()); if (index + 1 < entrances.size()) declaration += "\n"; index++; } - parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::None, entrances.size() * 2, "EntranceEntry", - StringHelper::Sprintf("%sEntranceList0x%06X", prefix.c_str(), segmentOffset), - entrances.size(), declaration); + std::string varName = + StringHelper::Sprintf("%sEntranceList0x%06X", prefix.c_str(), segmentOffset); + parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4, + entrances.size() * 2, "EntranceEntry", varName, + entrances.size(), declaration); } } std::string SetEntranceList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "EntranceEntry", listName); return StringHelper::Sprintf("SCENE_CMD_ENTRANCE_LIST(%s)", listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp index a3cd64202a..ddc4c5d43e 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp @@ -1,5 +1,6 @@ #include "SetExitList.h" +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -12,7 +13,11 @@ SetExitList::SetExitList(ZFile* nParent) : ZRoomCommand(nParent) void SetExitList::DeclareReferences([[maybe_unused]] const std::string& prefix) { if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); + { + std::string varName = + StringHelper::Sprintf("%sExitList_%06X", prefix.c_str(), segmentOffset); + parent->AddDeclarationPlaceholder(segmentOffset, varName); + } } void SetExitList::ParseRawDataLate() @@ -34,7 +39,7 @@ void SetExitList::DeclareReferencesLate([[maybe_unused]] const std::string& pref { if (!exits.empty()) { - std::string declaration = ""; + std::string declaration; for (size_t i = 0; i < exits.size(); i++) { @@ -43,16 +48,17 @@ void SetExitList::DeclareReferencesLate([[maybe_unused]] const std::string& pref declaration += "\n"; } - parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::Align4, exits.size() * 2, "u16", - StringHelper::Sprintf("%sExitList_%06X", prefix.c_str(), segmentOffset), exits.size(), - declaration); + std::string varName = + StringHelper::Sprintf("%sExitList_%06X", prefix.c_str(), segmentOffset); + parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4, exits.size() * 2, + "u16", varName, exits.size(), declaration); } } std::string SetExitList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "u16", listName); return StringHelper::Sprintf("SCENE_CMD_EXIT_LIST(%s)", listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp index 3bfc3a08ad..2e023ff206 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightList.cpp @@ -1,4 +1,6 @@ #include "SetLightList.h" + +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -9,7 +11,7 @@ SetLightList::SetLightList(ZFile* nParent) : ZRoomCommand(nParent) void SetLightList::ParseRawData() { ZRoomCommand::ParseRawData(); - std::string declarations = ""; + std::string declarations; numLights = cmdArg1; int32_t currentPtr = segmentOffset; @@ -26,7 +28,7 @@ void SetLightList::DeclareReferences(const std::string& prefix) { if (!lights.empty()) { - std::string declarations = ""; + std::string declarations; for (size_t i = 0; i < lights.size(); i++) { @@ -40,7 +42,7 @@ void SetLightList::DeclareReferences(const std::string& prefix) const auto& light = lights.front(); parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::None, lights.size() * light.GetRawDataSize(), + segmentOffset, DeclarationAlignment::Align4, lights.size() * light.GetRawDataSize(), light.GetSourceTypeName(), StringHelper::Sprintf("%sLightInfo0x%06X", prefix.c_str(), segmentOffset), lights.size(), declarations); @@ -49,7 +51,8 @@ void SetLightList::DeclareReferences(const std::string& prefix) std::string SetLightList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightInfo", listName); return StringHelper::Sprintf("SCENE_CMD_LIGHT_LIST(%i, %s)", numLights, listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp index cad21521e2..08cd83d141 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp @@ -1,4 +1,6 @@ #include "SetLightingSettings.h" + +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -21,13 +23,12 @@ void SetLightingSettings::DeclareReferences(const std::string& prefix) { if (settings.size() > 0) { - std::string declaration = ""; + std::string declaration; for (size_t i = 0; i < settings.size(); i++) { - declaration += StringHelper::Sprintf("\t{ %s }, // 0x%06X", - settings.at(i).GetBodySourceCode().c_str(), - segmentOffset + (i * 22)); + declaration += + StringHelper::Sprintf("\t{ %s },", settings.at(i).GetBodySourceCode().c_str()); if (i + 1 < settings.size()) declaration += "\n"; } @@ -42,7 +43,8 @@ void SetLightingSettings::DeclareReferences(const std::string& prefix) std::string SetLightingSettings::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "LightSettings", listName); return StringHelper::Sprintf("SCENE_CMD_ENV_LIGHT_SETTINGS(%i, %s)", settings.size(), listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp index b2f9268ee3..d1c8abd5c5 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp @@ -22,15 +22,15 @@ void SetMesh::ParseRawData() switch (meshHeaderType) { case 0: - polyType = std::make_shared(parent, parentRawData, segmentOffset, zRoom); + polyType = std::make_shared(parent, segmentOffset, zRoom); break; case 1: - polyType = std::make_shared(parent, parentRawData, segmentOffset, zRoom); + polyType = std::make_shared(parent, segmentOffset, zRoom); break; case 2: - polyType = std::make_shared(parent, parentRawData, segmentOffset, zRoom); + polyType = std::make_shared(parent, segmentOffset, zRoom); break; default: @@ -49,36 +49,23 @@ void SetMesh::DeclareReferences(const std::string& prefix) polyType->DeclareAndGenerateOutputCode(prefix); } +// TODO: is this really needed? void GenDListDeclarations(ZRoom* zRoom, ZFile* parent, ZDisplayList* dList) { if (dList == nullptr) { return; } - std::string srcVarName = - StringHelper::Sprintf("%s%s", zRoom->GetName().c_str(), dList->GetName().c_str()); - dList->SetName(srcVarName); std::string sourceOutput = dList->GetSourceOutputCode(zRoom->GetName()); for (ZDisplayList* otherDList : dList->otherDLists) GenDListDeclarations(zRoom, parent, otherDList); - - for (const auto& vtxEntry : dList->vtxDeclarations) - { - DeclarationAlignment alignment = DeclarationAlignment::Align4; - if (Globals::Instance->game == ZGame::MM_RETAIL) - alignment = DeclarationAlignment::None; - parent->AddDeclarationArray( - vtxEntry.first, alignment, dList->vertices[vtxEntry.first].size() * 16, "static Vtx", - StringHelper::Sprintf("%sVtx_%06X", zRoom->GetName().c_str(), vtxEntry.first), - dList->vertices[vtxEntry.first].size(), vtxEntry.second); - } } std::string SetMesh::GenDListExterns(ZDisplayList* dList) { - std::string sourceOutput = ""; + std::string sourceOutput; sourceOutput += StringHelper::Sprintf("extern Gfx %sDL_%06X[];\n", zRoom->GetName().c_str(), dList->GetRawDataIndex()); @@ -86,14 +73,13 @@ std::string SetMesh::GenDListExterns(ZDisplayList* dList) for (ZDisplayList* otherDList : dList->otherDLists) sourceOutput += GenDListExterns(otherDList); - sourceOutput += dList->defines; - return sourceOutput; } std::string SetMesh::GetBodySourceCode() const { - std::string list = parent->GetDeclarationPtrName(cmdArg2); + std::string list; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "", list); return StringHelper::Sprintf("SCENE_CMD_MESH(%s)", list.c_str()); } @@ -107,15 +93,8 @@ RoomCommand SetMesh::GetRoomCommand() const return RoomCommand::SetMesh; } -PolygonDlist::PolygonDlist(const std::string& prefix, - [[maybe_unused]] const std::vector& nRawData, - uint32_t nRawDataIndex, ZFile* nParent, ZRoom* nRoom) +PolygonDlist::PolygonDlist(ZFile* nParent) : ZResource(nParent) { - rawDataIndex = nRawDataIndex; - parent = nParent; - zRoom = nRoom; - - name = GetDefaultName(prefix.c_str(), rawDataIndex); } void PolygonDlist::ParseRawData() @@ -146,22 +125,57 @@ void PolygonDlist::DeclareReferences(const std::string& prefix) xluDList = MakeDlist(xlu, prefix); } -ZDisplayList* PolygonDlist::MakeDlist(segptr_t ptr, [[maybe_unused]] const std::string& prefix) +std::string PolygonDlist::GetBodySourceCode() const { - if (ptr == 0) + std::string bodyStr; + std::string opaStr; + std::string xluStr; + Globals::Instance->GetSegmentedPtrName(opa, parent, "Gfx", opaStr); + Globals::Instance->GetSegmentedPtrName(xlu, parent, "Gfx", xluStr); + + if (polyType == 2) { - return nullptr; + bodyStr += StringHelper::Sprintf("{ %6i, %6i, %6i }, %6i, ", x, y, z, unk_06); } - uint32_t dlistAddress = Seg2Filespace(ptr, parent->baseAddress); + bodyStr += StringHelper::Sprintf("%s, %s", opaStr.c_str(), xluStr.c_str()); - int32_t dlistLength = ZDisplayList::GetDListLength( - parent->GetRawData(), dlistAddress, - Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); - ZDisplayList* dlist = new ZDisplayList(dlistAddress, dlistLength, parent); - GenDListDeclarations(zRoom, parent, dlist); + return bodyStr; +} - return dlist; +std::string PolygonDlist::GetSourceOutputCode(const std::string& prefix) +{ + std::string bodyStr = StringHelper::Sprintf("\n\t%s\n", GetBodySourceCode().c_str()); + + Declaration* decl = parent->GetDeclaration(rawDataIndex); + if (decl == nullptr) + { + DeclareVar(prefix, bodyStr); + } + else + { + decl->text = bodyStr; + } + + return ""; +} + +std::string PolygonDlist::GetSourceTypeName() const +{ + switch (polyType) + { + case 2: + return "PolygonDlist2"; + + default: + return "PolygonDlist"; + } +} + +ZResourceType PolygonDlist::GetResourceType() const +{ + // TODO + return ZResourceType::Error; } size_t PolygonDlist::GetRawDataSize() const @@ -181,97 +195,42 @@ void PolygonDlist::SetPolyType(uint8_t nPolyType) polyType = nPolyType; } -void PolygonDlist::DeclareVar(const std::string& prefix, const std::string& bodyStr) +ZDisplayList* PolygonDlist::MakeDlist(segptr_t ptr, [[maybe_unused]] const std::string& prefix) { - std::string auxName = name; - if (name == "") + if (ptr == 0) { - auxName = GetDefaultName(prefix, rawDataIndex); + return nullptr; } - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), auxName, bodyStr); + + uint32_t dlistAddress = Seg2Filespace(ptr, parent->baseAddress); + + int32_t dlistLength = ZDisplayList::GetDListLength( + parent->GetRawData(), dlistAddress, + Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + ZDisplayList* dlist = new ZDisplayList(parent); + parent->AddResource(dlist); + dlist->ExtractFromBinary(dlistAddress, dlistLength); + dlist->SetName(dlist->GetDefaultName(prefix)); + GenDListDeclarations(zRoom, parent, dlist); + + return dlist; } -std::string PolygonDlist::GetBodySourceCode(bool arrayElement) +/* BgImage */ + +BgImage::BgImage(ZFile* nParent) : ZResource(nParent) { - std::string bodyStr = ""; - std::string opaStr = parent->GetDeclarationPtrName(opa); - std::string xluStr = parent->GetDeclarationPtrName(xlu); - if (arrayElement) - { - bodyStr += " { "; - } - else - { - bodyStr += "\n "; - } - - if (polyType == 2) - { - bodyStr += StringHelper::Sprintf("{ %6i, %6i, %6i }, %6i, ", x, y, z, unk_06); - } - - bodyStr += StringHelper::Sprintf("%s, ", opaStr.c_str()); - bodyStr += StringHelper::Sprintf("%s", xluStr.c_str()); - - if (arrayElement) - { - bodyStr += " },"; - } - else - { - bodyStr += "\n"; - } - - return bodyStr; } -void PolygonDlist::DeclareAndGenerateOutputCode() -{ - std::string bodyStr = GetBodySourceCode(false); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr) - { - DeclareVar("", bodyStr); - } - else - { - decl->text = bodyStr; - } -} - -std::string PolygonDlist::GetDefaultName(const std::string& prefix, uint32_t address) -{ - return StringHelper::Sprintf("%sPolyDlist_%06X", prefix.c_str(), address); -} - -std::string PolygonDlist::GetSourceTypeName() -{ - switch (polyType) - { - case 2: - return "PolygonDlist2"; - - default: - return "PolygonDlist"; - } -} - -std::string PolygonDlist::GetName() -{ - return name; -} - -BgImage::BgImage(bool nIsSubStruct, const std::string& prefix, - [[maybe_unused]] const std::vector& nRawData, uint32_t nRawDataIndex, +BgImage::BgImage(bool nIsSubStruct, const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent) + : BgImage(nParent) { rawDataIndex = nRawDataIndex; parent = nParent; isSubStruct = nIsSubStruct; - name = GetDefaultName(prefix.c_str(), rawDataIndex); + name = GetDefaultName(prefix); ParseRawData(); sourceBackground = MakeBackground(source, prefix); @@ -306,22 +265,28 @@ ZBackground* BgImage::MakeBackground(segptr_t ptr, const std::string& prefix) uint32_t backAddress = Seg2Filespace(ptr, parent->baseAddress); - ZBackground* background = new ZBackground(prefix, backAddress, parent); + ZBackground* background = new ZBackground(parent); + background->ExtractFromFile(backAddress); + + std::string defaultName = background->GetDefaultName(prefix); + background->SetName(defaultName); + background->SetOutName(defaultName); + background->DeclareVar(prefix, ""); parent->resources.push_back(background); return background; } -size_t BgImage::GetRawDataSize() +size_t BgImage::GetRawDataSize() const { return 0x1C; } -std::string BgImage::GetBodySourceCode(bool arrayElement) const +std::string BgImage::GetBodySourceCode() const { std::string bodyStr = " "; - if (arrayElement) + if (!isSubStruct) { bodyStr += "{ \n "; } @@ -331,16 +296,14 @@ std::string BgImage::GetBodySourceCode(bool arrayElement) const bodyStr += StringHelper::Sprintf("0x%04X, ", unk_00); bodyStr += StringHelper::Sprintf("%i, ", id); bodyStr += "\n "; - if (arrayElement) - { - bodyStr += " "; - } + bodyStr += " "; } - std::string backgroundName = parent->GetDeclarationPtrName(source); + std::string backgroundName; + Globals::Instance->GetSegmentedPtrName(source, parent, "", backgroundName); bodyStr += StringHelper::Sprintf("%s, ", backgroundName.c_str()); bodyStr += "\n "; - if (arrayElement) + if (!isSubStruct) { bodyStr += " "; } @@ -348,7 +311,7 @@ std::string BgImage::GetBodySourceCode(bool arrayElement) const bodyStr += StringHelper::Sprintf("0x%08X, ", unk_0C); bodyStr += StringHelper::Sprintf("0x%08X, ", tlut); bodyStr += "\n "; - if (arrayElement) + if (!isSubStruct) { bodyStr += " "; } @@ -356,7 +319,7 @@ std::string BgImage::GetBodySourceCode(bool arrayElement) const bodyStr += StringHelper::Sprintf("%i, ", width); bodyStr += StringHelper::Sprintf("%i, ", height); bodyStr += "\n "; - if (arrayElement) + if (!isSubStruct) { bodyStr += " "; } @@ -364,14 +327,14 @@ std::string BgImage::GetBodySourceCode(bool arrayElement) const bodyStr += StringHelper::Sprintf("%i, ", fmt); bodyStr += StringHelper::Sprintf("%i, ", siz); bodyStr += "\n "; - if (arrayElement) + if (!isSubStruct) { bodyStr += " "; } bodyStr += StringHelper::Sprintf("0x%04X, ", mode0); bodyStr += StringHelper::Sprintf("0x%04X, ", tlutCount); - if (arrayElement) + if (!isSubStruct) { bodyStr += " \n }, "; } @@ -383,41 +346,26 @@ std::string BgImage::GetBodySourceCode(bool arrayElement) const return bodyStr; } -std::string BgImage::GetDefaultName(const std::string& prefix, uint32_t address) -{ - return StringHelper::Sprintf("%sBgImage_%06X", prefix.c_str(), address); -} - -std::string BgImage::GetSourceTypeName() +std::string BgImage::GetSourceTypeName() const { return "BgImage"; } -std::string BgImage::GetName() +ZResourceType BgImage::GetResourceType() const { - return name; + // TODO + return ZResourceType::Error; } /* PolygonType section */ -PolygonTypeBase::PolygonTypeBase(ZFile* nParent, - [[maybe_unused]] const std::vector& nRawData, - uint32_t nRawDataIndex, ZRoom* nRoom) - : rawDataIndex{nRawDataIndex}, parent{nParent}, zRoom{nRoom} +PolygonTypeBase::PolygonTypeBase(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom) + : ZResource(nParent), zRoom{nRoom} { + rawDataIndex = nRawDataIndex; type = BitConverter::ToUInt8BE(parent->GetRawData(), rawDataIndex); } -void PolygonTypeBase::DeclareVar(const std::string& prefix, const std::string& bodyStr) -{ - std::string auxName = name; - if (name == "") - auxName = GetDefaultName(prefix); - - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), auxName, bodyStr); -} - void PolygonTypeBase::DeclareAndGenerateOutputCode(const std::string& prefix) { std::string bodyStr = GetBodySourceCode(); @@ -448,25 +396,14 @@ std::string PolygonTypeBase::GetSourceTypeName() const } } -std::string PolygonTypeBase::GetName() const +ZResourceType PolygonTypeBase::GetResourceType() const { - return name; + // TODO + return ZResourceType::Error; } -void PolygonTypeBase::SetName(const std::string& newName) -{ - name = newName; -} - -std::string PolygonTypeBase::GetDefaultName(const std::string& prefix) const -{ - return StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), GetSourceTypeName().c_str(), - rawDataIndex); -} - -PolygonType1::PolygonType1(ZFile* nParent, const std::vector& nRawData, - uint32_t nRawDataIndex, ZRoom* nRoom) - : PolygonTypeBase(nParent, nRawData, nRawDataIndex, nRoom) +PolygonType1::PolygonType1(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom) + : PolygonTypeBase(nParent, nRawDataIndex, nRoom), single(nParent) { } @@ -485,10 +422,10 @@ void PolygonType1::ParseRawData() if (dlist != 0) { - PolygonDlist polyGfxList(zRoom->GetName(), rawData, - Seg2Filespace(dlist, parent->baseAddress), parent, zRoom); + PolygonDlist polyGfxList(parent); + polyGfxList.zRoom = zRoom; polyGfxList.SetPolyType(type); - polyGfxList.ParseRawData(); + polyGfxList.ExtractFromFile(Seg2Filespace(dlist, parent->baseAddress)); polyGfxList.DeclareReferences(zRoom->GetName()); polyDLists.push_back(polyGfxList); } @@ -496,26 +433,27 @@ void PolygonType1::ParseRawData() void PolygonType1::DeclareReferences(const std::string& prefix) { - polyDLists.at(0).DeclareAndGenerateOutputCode(); + polyDLists.at(0).GetSourceOutputCode(prefix); uint32_t listAddress; - std::string bgImageArrayBody = ""; + std::string bgImageArrayBody; switch (format) { case 1: - single = BgImage(true, prefix, parent->GetRawData(), rawDataIndex + 0x08, parent); + single = BgImage(true, prefix, rawDataIndex + 0x08, parent); break; case 2: if (list != 0) { listAddress = Seg2Filespace(list, parent->baseAddress); + uint32_t auxPtr = listAddress; for (size_t i = 0; i < count; ++i) { - BgImage bg(false, prefix, parent->GetRawData(), - listAddress + i * BgImage::GetRawDataSize(), parent); + BgImage bg(false, prefix, auxPtr, parent); multiList.push_back(bg); - bgImageArrayBody += bg.GetBodySourceCode(true); + auxPtr += bg.GetRawDataSize(); + bgImageArrayBody += bg.GetBodySourceCode(); if (i + 1 < count) { bgImageArrayBody += "\n"; @@ -526,9 +464,9 @@ void PolygonType1::DeclareReferences(const std::string& prefix) if (decl == nullptr) { parent->AddDeclarationArray( - listAddress, DeclarationAlignment::Align4, count * BgImage::GetRawDataSize(), - BgImage::GetSourceTypeName(), multiList.at(0).GetName().c_str(), count, - bgImageArrayBody); + listAddress, DeclarationAlignment::Align4, + count * multiList.at(0).GetRawDataSize(), multiList.at(0).GetSourceTypeName(), + multiList.at(0).GetName().c_str(), count, bgImageArrayBody); } } break; @@ -560,26 +498,26 @@ std::string PolygonType1::GetBodySourceCode() const bodyStr += "{ "; bodyStr += StringHelper::Sprintf("%i, %i, ", type, format); - std::string dlistStr = parent->GetDeclarationPtrName(dlist); + std::string dlistStr; + Globals::Instance->GetSegmentedPtrName(dlist, parent, "", dlistStr); + bodyStr += StringHelper::Sprintf("%s, ", dlistStr.c_str()); bodyStr += "}, \n"; std::string listStr = "NULL"; - // bodyStr += " { \n"; switch (format) { case 1: - bodyStr += single.GetBodySourceCode(false); + bodyStr += single.GetBodySourceCode(); break; case 2: - listStr = parent->GetDeclarationPtrName(list); + Globals::Instance->GetSegmentedPtrName(list, parent, "BgImage", listStr); bodyStr += StringHelper::Sprintf(" %i, %s, \n", count, listStr.c_str()); break; default: break; } - // bodyStr += " } \n"; return bodyStr; } @@ -598,9 +536,8 @@ std::string PolygonType1::GetSourceTypeName() const // return "PolygonType1"; } -PolygonType2::PolygonType2(ZFile* nParent, const std::vector& nRawData, - uint32_t nRawDataIndex, ZRoom* nRoom) - : PolygonTypeBase(nParent, nRawData, nRawDataIndex, nRoom) +PolygonType2::PolygonType2(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom) + : PolygonTypeBase(nParent, nRawDataIndex, nRoom) { } @@ -616,9 +553,10 @@ void PolygonType2::ParseRawData() uint32_t currentPtr = GETSEGOFFSET(start); for (size_t i = 0; i < num; i++) { - PolygonDlist entry(zRoom->GetName(), rawData, currentPtr, parent, zRoom); + PolygonDlist entry(parent); + entry.zRoom = zRoom; entry.SetPolyType(type); - entry.ParseRawData(); + entry.ExtractFromFile(currentPtr); entry.DeclareReferences(zRoom->GetName()); polyDLists.push_back(entry); currentPtr += entry.GetRawDataSize(); @@ -629,17 +567,18 @@ void PolygonType2::DeclareReferences(const std::string& prefix) { if (num > 0) { - std::string declaration = ""; + std::string declaration; for (size_t i = 0; i < polyDLists.size(); i++) { - declaration += polyDLists.at(i).GetBodySourceCode(true); + declaration += + StringHelper::Sprintf("\t{ %s },", polyDLists.at(i).GetBodySourceCode().c_str()); if (i + 1 < polyDLists.size()) declaration += "\n"; } std::string polyDlistType = polyDLists.at(0).GetSourceTypeName(); - std::string polyDListName = ""; + std::string polyDListName; polyDListName = StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), polyDlistType.c_str(), GETSEGOFFSET(start)); @@ -648,13 +587,16 @@ void PolygonType2::DeclareReferences(const std::string& prefix) polyDlistType, polyDListName, polyDLists.size(), declaration); } - parent->AddDeclaration(GETSEGOFFSET(end), DeclarationAlignment::Align4, 4, "static s32", - "terminatorMaybe", "0x01000000"); + parent->AddDeclaration(GETSEGOFFSET(end), DeclarationAlignment::Align4, 4, "s32", + StringHelper::Sprintf("%s_terminatorMaybe_%06X", + parent->GetName().c_str(), GETSEGOFFSET(end)), + "0x01000000"); } std::string PolygonType2::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(start); + std::string listName; + Globals::Instance->GetSegmentedPtrName(start, parent, "", listName); std::string body = StringHelper::Sprintf("\n %i, %i,\n", type, polyDLists.size()); body += StringHelper::Sprintf(" %s,\n", listName.c_str()); @@ -667,3 +609,8 @@ size_t PolygonType2::GetRawDataSize() const { return 0x0C; } + +DeclarationAlignment PolygonType2::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align4; +} diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h index 65591966c4..566711a9a7 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h @@ -5,9 +5,11 @@ #include "ZDisplayList.h" #include "ZRoom/ZRoomCommand.h" -class PolygonDlist +class PolygonDlist : public ZResource { public: + ZRoom* zRoom; + uint8_t polyType; int16_t x, y, z; // polyType == 2 @@ -19,35 +21,27 @@ public: ZDisplayList* opaDList = nullptr; // Gfx* ZDisplayList* xluDList = nullptr; // Gfx* - PolygonDlist() = default; - PolygonDlist(const std::string& prefix, const std::vector& nRawData, - uint32_t nRawDataIndex, ZFile* nParent, ZRoom* nRoom); + PolygonDlist(ZFile* nParent); - void ParseRawData(); - void DeclareReferences(const std::string& prefix); + void ParseRawData() override; + void DeclareReferences(const std::string& prefix) override; + + std::string GetBodySourceCode() const override; + + std::string GetSourceOutputCode(const std::string& prefix) override; + + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; - size_t GetRawDataSize() const; void SetPolyType(uint8_t nPolyType); - void DeclareVar(const std::string& prefix, const std::string& bodyStr); - - std::string GetBodySourceCode(bool arrayElement); - void DeclareAndGenerateOutputCode(); - - static std::string GetDefaultName(const std::string& prefix, uint32_t address); - std::string GetSourceTypeName(); - std::string GetName(); - protected: - uint32_t rawDataIndex; - ZFile* parent; - ZRoom* zRoom; - std::string name; - ZDisplayList* MakeDlist(segptr_t ptr, const std::string& prefix); }; -class BgImage +class BgImage : public ZResource { public: uint16_t unk_00; @@ -64,59 +58,39 @@ public: ZBackground* sourceBackground; - uint32_t rawDataIndex; - ZFile* parent; - std::string name; bool isSubStruct; + BgImage(ZFile* nParent); + BgImage(bool nIsSubStruct, const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent); + + void ParseRawData() override; + + std::string GetBodySourceCode() const override; + + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; + protected: - void ParseRawData(); ZBackground* MakeBackground(segptr_t ptr, const std::string& prefix); - -public: - BgImage() = default; - BgImage(bool nIsSubStruct, const std::string& prefix, const std::vector& nRawData, - uint32_t nRawDataIndex, ZFile* nParent); - - static size_t GetRawDataSize(); - - std::string GetBodySourceCode(bool arrayElement) const; - - static std::string GetDefaultName(const std::string& prefix, uint32_t address); - static std::string GetSourceTypeName(); - std::string GetName(); }; -class PolygonTypeBase +class PolygonTypeBase : public ZResource { public: uint8_t type; std::vector polyDLists; - PolygonTypeBase(ZFile* nParent, const std::vector& nRawData, uint32_t nRawDataIndex, - ZRoom* nRoom); - virtual ~PolygonTypeBase() = default; + PolygonTypeBase(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom); - virtual void ParseRawData() = 0; - virtual void DeclareReferences(const std::string& prefix) = 0; - - virtual std::string GetBodySourceCode() const = 0; - void DeclareVar(const std::string& prefix, const std::string& bodyStr); void DeclareAndGenerateOutputCode(const std::string& prefix); - virtual std::string GetSourceTypeName() const; - - std::string GetName() const; - void SetName(const std::string& newName); - virtual size_t GetRawDataSize() const = 0; - - std::string GetDefaultName(const std::string& prefix) const; + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; protected: - uint32_t rawDataIndex; - ZFile* parent; ZRoom* zRoom; - std::string name; }; class PolygonType1 : public PolygonTypeBase @@ -133,8 +107,7 @@ public: segptr_t list; // BgImage* std::vector multiList; - PolygonType1(ZFile* nParent, const std::vector& nRawData, uint32_t nRawDataIndex, - ZRoom* nRoom); + PolygonType1(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom); void ParseRawData() override; void DeclareReferences(const std::string& prefix) override; @@ -153,8 +126,7 @@ public: segptr_t start; segptr_t end; - PolygonType2(ZFile* nParent, const std::vector& nRawData, uint32_t nRawDataIndex, - ZRoom* nRoom); + PolygonType2(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom); void ParseRawData() override; void DeclareReferences(const std::string& prefix) override; @@ -162,8 +134,7 @@ public: std::string GetBodySourceCode() const override; size_t GetRawDataSize() const override; - -protected: + DeclarationAlignment GetDeclarationAlignment() const override; }; class SetMesh : public ZRoomCommand diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapChests.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapChests.cpp index 75f032f8a4..ec432b7d99 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapChests.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapChests.cpp @@ -28,7 +28,7 @@ void SetMinimapChests::ParseRawData() void SetMinimapChests::DeclareReferences(const std::string& prefix) { - std::string declaration = ""; + std::string declaration; size_t index = 0; for (const auto& chest : chests) @@ -42,14 +42,15 @@ void SetMinimapChests::DeclareReferences(const std::string& prefix) } parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::None, chests.size() * 10, "MinimapChest", + segmentOffset, DeclarationAlignment::Align4, chests.size() * 10, "MinimapChest", StringHelper::Sprintf("%sMinimapChests0x%06X", prefix.c_str(), segmentOffset), chests.size(), declaration); } std::string SetMinimapChests::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapChest", listName); return StringHelper::Sprintf("SCENE_CMD_MINIMAP_COMPASS_ICON_INFO(0x%02X, %s)", chests.size(), listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapList.cpp index c81fb200cd..be5d8f15d1 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMinimapList.cpp @@ -31,7 +31,7 @@ void SetMinimapList::ParseRawData() void SetMinimapList::DeclareReferences(const std::string& prefix) { { - std::string declaration = ""; + std::string declaration; size_t index = 0; for (const auto& entry : minimaps) @@ -51,7 +51,8 @@ void SetMinimapList::DeclareReferences(const std::string& prefix) } { - std::string listName = parent->GetDeclarationPtrName(listSegmentAddr); + std::string listName; + Globals::Instance->GetSegmentedPtrName(listSegmentAddr, parent, "MinimapEntry", listName); std::string declaration = StringHelper::Sprintf("\n\t%s, 0x%08X\n", listName.c_str(), unk4); parent->AddDeclaration( @@ -63,7 +64,8 @@ void SetMinimapList::DeclareReferences(const std::string& prefix) std::string SetMinimapList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "MinimapList", listName); return StringHelper::Sprintf("SCENE_CMD_MINIMAP_INFO(%s)", listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp index 9e3e9bb7ff..fdd41e6cb4 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp @@ -23,16 +23,13 @@ void SetObjectList::ParseRawData() objects.push_back(objectIndex); currentPtr += 2; } - - if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); } void SetObjectList::DeclareReferences(const std::string& prefix) { if (!objects.empty()) { - std::string declaration = ""; + std::string declaration; for (size_t i = 0; i < objects.size(); i++) { @@ -45,7 +42,7 @@ void SetObjectList::DeclareReferences(const std::string& prefix) } parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::None, objects.size() * 2, "s16", + segmentOffset, DeclarationAlignment::Align4, objects.size() * 2, "s16", StringHelper::Sprintf("%sObjectList_%06X", prefix.c_str(), segmentOffset), objects.size(), declaration); } @@ -53,7 +50,8 @@ void SetObjectList::DeclareReferences(const std::string& prefix) std::string SetObjectList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "s16", listName); return StringHelper::Sprintf("SCENE_CMD_OBJECT_LIST(%i, %s)", objects.size(), listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp index 0f7b4beda0..52d400a848 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp @@ -1,4 +1,5 @@ #include "SetPathways.h" + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -12,7 +13,11 @@ SetPathways::SetPathways(ZFile* nParent) : ZRoomCommand(nParent), pathwayList(nP void SetPathways::DeclareReferences([[maybe_unused]] const std::string& prefix) { if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); + { + std::string varName = + StringHelper::Sprintf("%sPathway_%06X", prefix.c_str(), segmentOffset); + parent->AddDeclarationPlaceholder(segmentOffset, varName); + } } void SetPathways::ParseRawDataLate() @@ -23,20 +28,21 @@ void SetPathways::ParseRawDataLate() pathwayList.SetNumPaths(numPaths); } - pathwayList.SetRawDataIndex(segmentOffset); - pathwayList.ParseRawData(); + pathwayList.ExtractFromFile(segmentOffset); } void SetPathways::DeclareReferencesLate(const std::string& prefix) { - pathwayList.SetName(StringHelper::Sprintf("%sPathway_%06X", prefix.c_str(), segmentOffset)); + std::string varName = StringHelper::Sprintf("%sPathway_%06X", prefix.c_str(), segmentOffset); + pathwayList.SetName(varName); pathwayList.DeclareReferences(prefix); pathwayList.GetSourceOutputCode(prefix); } std::string SetPathways::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "Path", listName); return StringHelper::Sprintf("SCENE_CMD_PATH_LIST(%s)", listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h index cc754f7526..9abc93d32e 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.h @@ -17,8 +17,6 @@ public: void ParseRawDataLate() override; void DeclareReferencesLate(const std::string& prefix) override; - void DeclareVar(const std::string& prefix, const std::string& bodyStr); - std::string GetBodySourceCode() const override; RoomCommand GetRoomCommand() const override; diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.cpp index 426804b577..8c6f4bf514 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomBehavior.cpp @@ -1,4 +1,5 @@ #include "SetRoomBehavior.h" + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp index 6d697fa375..43c3968221 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp @@ -16,9 +16,8 @@ void SetRoomList::ParseRawData() int numRooms = cmdArg1; romfile = new RomFile(parent); - romfile->SetRawDataIndex(segmentOffset); romfile->numRooms = numRooms; - romfile->ParseRawData(); + romfile->ExtractFromFile(segmentOffset); parent->resources.push_back(romfile); @@ -34,8 +33,9 @@ void SetRoomList::DeclareReferences(const std::string& prefix) std::string SetRoomList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); - return StringHelper::Sprintf("SCENE_CMD_ROOM_LIST(%i, %s)", romfile->numRooms, + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "RomFile", listName); + return StringHelper::Sprintf("SCENE_CMD_ROOM_LIST(%i, %s)", romfile->rooms.size(), listName.c_str()); } @@ -78,20 +78,20 @@ void RomFile::ParseRawData() } } -void RomFile::DeclareVar(const std::string& prefix, const std::string body) +Declaration* RomFile::DeclareVar(const std::string& prefix, const std::string& body) { std::string auxName = name; if (name == "") auxName = StringHelper::Sprintf("%sRoomList0x%06X", prefix.c_str(), rawDataIndex); - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, - rooms.size() * rooms.at(0).GetRawDataSize(), GetSourceTypeName(), - auxName, 0, body); + return parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, + rooms.size() * rooms.at(0).GetRawDataSize(), + GetSourceTypeName(), auxName, rooms.size(), body); } std::string RomFile::GetBodySourceCode() const { - std::string declaration = ""; + std::string declaration; bool isFirst = true; for (ZFile* file : Globals::Instance->files) diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h index ae2035115c..4fb2ced176 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h @@ -22,7 +22,7 @@ public: void ParseXML(tinyxml2::XMLElement* reader) override; void ParseRawData() override; - void DeclareVar(const std::string& prefix, const std::string body); + Declaration* DeclareVar(const std::string& prefix, const std::string& body) override; std::string GetBodySourceCode() const override; std::string GetSourceOutputCode(const std::string& prefix) override; @@ -38,7 +38,6 @@ public: class SetRoomList : public ZRoomCommand { public: - std::vector rooms; // Borrowed reference. Don't delete. RomFile* romfile = nullptr; diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp index 5e160121b9..f75b5e0d5e 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp @@ -29,7 +29,7 @@ void SetStartPositionList::DeclareReferences(const std::string& prefix) { if (!actors.empty()) { - std::string declaration = ""; + std::string declaration; size_t index = 0; for (const auto& entry : actors) @@ -43,14 +43,15 @@ void SetStartPositionList::DeclareReferences(const std::string& prefix) parent->AddDeclarationArray( segmentOffset, DeclarationAlignment::Align4, actors.size() * 16, "ActorEntry", - StringHelper::Sprintf("%sStartPositionList0x%06X", prefix.c_str(), segmentOffset), 0, - declaration); + StringHelper::Sprintf("%sStartPositionList0x%06X", prefix.c_str(), segmentOffset), + actors.size(), declaration); } } std::string SetStartPositionList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName); return StringHelper::Sprintf("SCENE_CMD_SPAWN_LIST(%i, %s)", actors.size(), listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp index 9065bf1531..a33d1c6e1c 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp @@ -28,7 +28,7 @@ void SetTransitionActorList::ParseRawData() void SetTransitionActorList::DeclareReferences(const std::string& prefix) { - std::string declaration = ""; + std::string declaration; size_t index = 0; for (const auto& entry : transitionActors) @@ -43,15 +43,16 @@ void SetTransitionActorList::DeclareReferences(const std::string& prefix) } parent->AddDeclarationArray( - segmentOffset, DeclarationAlignment::None, transitionActors.size() * 16, + segmentOffset, DeclarationAlignment::Align4, transitionActors.size() * 16, "TransitionActorEntry", - StringHelper::Sprintf("%sTransitionActorList_%06X", prefix.c_str(), segmentOffset), 0, - declaration); + StringHelper::Sprintf("%sTransitionActorList_%06X", prefix.c_str(), segmentOffset), + transitionActors.size(), declaration); } std::string SetTransitionActorList::GetBodySourceCode() const { - std::string listName = parent->GetDeclarationPtrName(cmdArg2); + std::string listName; + Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "TransitionActorEntry", listName); return StringHelper::Sprintf("SCENE_CMD_TRANSITION_ACTOR_LIST(%i, %s)", transitionActors.size(), listName.c_str()); } diff --git a/tools/ZAPD/ZAPD/ZRoom/ZNames.h b/tools/ZAPD/ZAPD/ZRoom/ZNames.h index d8488a6f1f..94e08de0d2 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZNames.h +++ b/tools/ZAPD/ZAPD/ZRoom/ZNames.h @@ -29,7 +29,7 @@ public: { int32_t flags = id & 0xF000; id &= 0xFFF; - std::string name = ""; + std::string name; if (id < ZNames::GetNumActors()) name = Globals::Instance->cfg.actorList.at(id); else diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp index 0ef3724d1c..edc0cad029 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp @@ -1,9 +1,8 @@ #include "ZRoom.h" - #include #include #include - +#include #include "Commands/EndMarker.h" #include "Commands/SetActorCutsceneList.h" #include "Commands/SetActorList.h" @@ -113,7 +112,6 @@ void ZRoom::ParseXML(tinyxml2::XMLElement* reader) std::string nodeName = std::string(reader->Name()); if (nodeName == "Scene") { - Globals::Instance->lastScene = this; zroomType = ZResourceType::Scene; } else if (nodeName == "Room") @@ -293,7 +291,7 @@ void ZRoom::DeclareReferencesLate(const std::string& prefix) cmd->DeclareReferencesLate(prefix); } -void ZRoom::DeclareVar(const std::string& prefix, const std::string body) +Declaration* ZRoom::DeclareVar(const std::string& prefix, const std::string& body) { std::string auxName = name; if (auxName == "") @@ -301,13 +299,16 @@ void ZRoom::DeclareVar(const std::string& prefix, const std::string body) if (zroomType == ZResourceType::Scene || zroomType == ZResourceType::Room) auxName = StringHelper::Sprintf("%sCommands", name.c_str()); - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), auxName, 0, body); + Declaration* decl = + parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), + GetSourceTypeName(), auxName, commands.size(), body); + decl->staticConf = staticConf; + return decl; } std::string ZRoom::GetBodySourceCode() const { - std::string declaration = ""; + std::string declaration; for (size_t i = 0; i < commands.size(); i++) { @@ -327,17 +328,17 @@ std::string ZRoom::GetDefaultName(const std::string& prefix) const } /* - * There is one room in Ocarina of Time that lacks a header. Room 120, "Syotes", dates back to very - * early in the game's development. Since this room is a special case, declare automatically the - * data its contains whitout the need of a header. + * There is one room in Ocarina of Time that lacks a header. Room 120, "Syotes", dates + * back to very early in the game's development. Since this room is a special case, + * declare automatically the data its contains whitout the need of a header. */ void ZRoom::SyotesRoomHack() { - PolygonType2 poly(parent, parent->GetRawData(), 0, this); + PolygonType2 poly(parent, 0, this); poly.ParseRawData(); poly.DeclareReferences(GetName()); - parent->AddDeclaration(0, DeclarationAlignment::Align4, poly.GetRawDataSize(), + parent->AddDeclaration(0, poly.GetDeclarationAlignment(), poly.GetRawDataSize(), poly.GetSourceTypeName(), poly.GetDefaultName(GetName()), poly.GetBodySourceCode()); } @@ -391,32 +392,14 @@ size_t ZRoom::GetCommandSizeFromNeighbor(ZRoomCommand* cmd) return 0; } -std::string ZRoom::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) -{ - return "\n" + extDefines + "\n\n"; -} - std::string ZRoom::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) { - std::string sourceOutput = ""; - - if (zroomType == ZResourceType::Scene || zroomType == ZResourceType::Room) - { - sourceOutput += "#include \"segment_symbols.h\"\n"; - sourceOutput += "#include \"command_macros_base.h\"\n"; - sourceOutput += "#include \"z64cutscene_commands.h\"\n"; - sourceOutput += "#include \"variables.h\"\n"; - - if (Globals::Instance->lastScene != nullptr) - sourceOutput += Globals::Instance->lastScene->parent->GetHeaderInclude(); - } - if (hackMode == "syotes_room") - return sourceOutput; + return ""; DeclareVar(prefix, GetBodySourceCode()); - return sourceOutput; + return ""; } size_t ZRoom::GetRawDataSize() const diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.h b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h index 993baafe7d..0993a9d302 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoom.h +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h @@ -14,9 +14,7 @@ public: std::vector commands; int32_t roomCount; // Only valid for scenes - std::string extDefines; - - std::string hackMode = ""; + std::string hackMode; ZResourceType zroomType = ZResourceType::Error; ZResourceType parentZroomType = ZResourceType::Error; @@ -33,21 +31,20 @@ public: void ParseRawDataLate() override; void DeclareReferencesLate(const std::string& prefix) override; - void DeclareVar(const std::string& prefix, const std::string body); + Declaration* DeclareVar(const std::string& prefix, const std::string& body) override; std::string GetBodySourceCode() const override; - std::string GetDefaultName(const std::string& prefix) const; + std::string GetSourceOutputCode(const std::string& prefix) override; + + std::string GetDefaultName(const std::string& prefix) const override; size_t GetDeclarationSizeFromNeighbor(uint32_t declarationAddress); size_t GetCommandSizeFromNeighbor(ZRoomCommand* cmd); ZRoomCommand* FindCommandOfType(RoomCommand cmdType); - std::string GetSourceTypeName() const override; - size_t GetRawDataSize() const override; + std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; protected: - std::string GetSourceOutputHeader(const std::string& prefix) override; - std::string GetSourceOutputCode(const std::string& prefix) override; void SyotesRoomHack(); }; diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp index 3f5876eafa..711c86a409 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.cpp @@ -27,11 +27,6 @@ void ZRoomCommand::ParseRawData() segmentOffset = Seg2Filespace(cmdArg2, parent->baseAddress); } -std::string ZRoomCommand::GetSourceTypeName() const -{ - return "SCmdBase"; -} - RoomCommand ZRoomCommand::GetRoomCommand() const { return RoomCommand::Error; @@ -42,6 +37,11 @@ size_t ZRoomCommand::GetRawDataSize() const return 0x08; } +std::string ZRoomCommand::GetSourceTypeName() const +{ + return GetCommandCName(); +} + ZResourceType ZRoomCommand::GetResourceType() const { return ZResourceType::RoomCommand; diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h index b79dc3e16c..e4029984c9 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoomCommand.h @@ -57,7 +57,7 @@ public: uint32_t cmdIndex; uint32_t commandSet; RoomCommand cmdID; - uint32_t segmentOffset; + offset_t segmentOffset; ZRoomCommand(ZFile* nParent); virtual ~ZRoomCommand() = default; diff --git a/tools/ZAPD/ZAPD/ZScalar.cpp b/tools/ZAPD/ZAPD/ZScalar.cpp index 007c1cd03f..062fb0e079 100644 --- a/tools/ZAPD/ZAPD/ZScalar.cpp +++ b/tools/ZAPD/ZAPD/ZScalar.cpp @@ -1,4 +1,5 @@ #include "ZScalar.h" + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/File.h" @@ -14,9 +15,16 @@ ZScalar::ZScalar(ZFile* nParent) : ZResource(nParent) RegisterRequiredAttribute("Type"); } -ZScalar::ZScalar(const ZScalarType scalarType, ZFile* nParent) : ZScalar(nParent) +void ZScalar::ExtractFromBinary(uint32_t nRawDataIndex, ZScalarType nScalarType) { - this->scalarType = scalarType; + rawDataIndex = nRawDataIndex; + scalarType = nScalarType; + + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + + ParseRawData(); } void ZScalar::ParseXML(tinyxml2::XMLElement* reader) @@ -247,15 +255,6 @@ std::string ZScalar::GetBodySourceCode() const } } -std::string ZScalar::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - if (parent != nullptr) - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), GetName(), GetBodySourceCode()); - - return ""; -} - ZResourceType ZScalar::GetResourceType() const { return ZResourceType::Scalar; @@ -265,3 +264,16 @@ bool ZScalar::DoesSupportArray() const { return true; } + +DeclarationAlignment ZScalar::GetDeclarationAlignment() const +{ + switch (scalarType) + { + case ZScalarType::ZSCALAR_S64: + case ZScalarType::ZSCALAR_U64: + case ZScalarType::ZSCALAR_F64: + return DeclarationAlignment::Align8; + default: + return DeclarationAlignment::Align4; + } +} diff --git a/tools/ZAPD/ZAPD/ZScalar.h b/tools/ZAPD/ZAPD/ZScalar.h index ca2082756b..d269995cca 100644 --- a/tools/ZAPD/ZAPD/ZScalar.h +++ b/tools/ZAPD/ZAPD/ZScalar.h @@ -44,25 +44,25 @@ class ZScalar : public ZResource friend class ZVector; public: + ZScalarData scalarData; + ZScalarType scalarType; + ZScalar(ZFile* nParent); - ZScalar(const ZScalarType scalarType, ZFile* nParent); + + void ExtractFromBinary(uint32_t nRawDataIndex, ZScalarType nScalarType); void ParseRawData() override; void ParseXML(tinyxml2::XMLElement* reader) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; bool DoesSupportArray() const override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; size_t GetRawDataSize() const override; + DeclarationAlignment GetDeclarationAlignment() const override; static size_t MapTypeToSize(const ZScalarType scalarType); static ZScalarType MapOutputTypeToScalarType(const std::string& type); static std::string MapScalarTypeToOutputType(const ZScalarType scalarType); - -protected: - ZScalarData scalarData; - ZScalarType scalarType; }; diff --git a/tools/ZAPD/ZAPD/ZSkeleton.cpp b/tools/ZAPD/ZAPD/ZSkeleton.cpp index 6912f2ea4c..84f00c8187 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.cpp +++ b/tools/ZAPD/ZAPD/ZSkeleton.cpp @@ -1,6 +1,8 @@ #include "ZSkeleton.h" #include + +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -13,14 +15,6 @@ ZSkeleton::ZSkeleton(ZFile* nParent) : ZResource(nParent), limbsTable(nParent) RegisterRequiredAttribute("LimbType"); } -void ZSkeleton::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), name, ""); -} - void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); @@ -33,24 +27,18 @@ void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) type = ZSkeletonType::Curve; else if (skelTypeXml != "Normal") { - fprintf(stderr, - "ZSkeleton::ParseXML: Warning in '%s'.\n" - "\t Invalid Type found: '%s'.\n" - "\t Defaulting to 'Normal'.\n", - name.c_str(), skelTypeXml.c_str()); - type = ZSkeletonType::Normal; + throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n" + "\t Invalid Type found: '%s'.\n", + name.c_str(), skelTypeXml.c_str())); } std::string limbTypeXml = registeredAttributes.at("LimbType").value; limbType = ZLimb::GetTypeByAttributeName(limbTypeXml); if (limbType == ZLimbType::Invalid) { - fprintf(stderr, - "ZSkeleton::ParseXML: Warning in '%s'.\n" - "\t Invalid LimbType found: '%s'.\n" - "\t Defaulting to 'Standard'.\n", - name.c_str(), limbTypeXml.c_str()); - limbType = ZLimbType::Standard; + throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n" + "\t Invalid LimbType found: '%s'.\n", + name.c_str(), limbTypeXml.c_str())); } } @@ -61,7 +49,11 @@ void ZSkeleton::ParseRawData() const auto& rawData = parent->GetRawData(); limbsArrayAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex); limbCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4); - dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8); + + if (type == ZSkeletonType::Flex) + { + dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8); + } if (limbsArrayAddress != 0 && GETSEGNUM(limbsArrayAddress) == parent->segment) { @@ -76,6 +68,8 @@ void ZSkeleton::DeclareReferences(const std::string& prefix) if (defaultPrefix == "") defaultPrefix = prefix; + ZResource::DeclareReferences(defaultPrefix); + if (limbsArrayAddress != 0 && GETSEGNUM(limbsArrayAddress) == parent->segment) { uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); @@ -90,22 +84,22 @@ void ZSkeleton::DeclareReferences(const std::string& prefix) std::string ZSkeleton::GetBodySourceCode() const { - std::string limbTableName = parent->GetDeclarationPtrName(limbsArrayAddress); + std::string limbArrayName; + Globals::Instance->GetSegmentedPtrName(limbsArrayAddress, parent, "", limbArrayName); - std::string headerStr; switch (type) { case ZSkeletonType::Normal: case ZSkeletonType::Curve: - headerStr = StringHelper::Sprintf("\n\t%s, %i\n", limbTableName.c_str(), limbCount); - break; + return StringHelper::Sprintf("\n\t%s, %i\n", limbArrayName.c_str(), limbCount); + case ZSkeletonType::Flex: - headerStr = StringHelper::Sprintf("\n\t{ %s, %i }, %i\n", limbTableName.c_str(), limbCount, - dListCount); - break; + return StringHelper::Sprintf("\n\t{ %s, %i }, %i\n", limbArrayName.c_str(), limbCount, + dListCount); } - return headerStr; + // TODO: Throw exception? + return "ERROR"; } size_t ZSkeleton::GetRawDataSize() const @@ -121,25 +115,6 @@ size_t ZSkeleton::GetRawDataSize() const } } -std::string ZSkeleton::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - std::string headerStr = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(GetAddress()); - - if (decl == nullptr) - { - parent->AddDeclaration(GetAddress(), DeclarationAlignment::Align16, GetRawDataSize(), - GetSourceTypeName(), name, headerStr); - } - else - { - decl->text = headerStr; - } - - return ""; -} - std::string ZSkeleton::GetSourceTypeName() const { switch (type) @@ -160,9 +135,9 @@ ZResourceType ZSkeleton::GetResourceType() const return ZResourceType::Skeleton; } -segptr_t ZSkeleton::GetAddress() +DeclarationAlignment ZSkeleton::GetDeclarationAlignment() const { - return rawDataIndex; + return DeclarationAlignment::Align16; } uint8_t ZSkeleton::GetLimbCount() @@ -178,14 +153,6 @@ ZLimbTable::ZLimbTable(ZFile* nParent) : ZResource(nParent) RegisterRequiredAttribute("Count"); } -void ZLimbTable::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), name, limbsAddresses.size(), ""); -} - void ZLimbTable::ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nLimbType, size_t nCount) { rawDataIndex = nRawDataIndex; @@ -229,9 +196,9 @@ void ZLimbTable::ParseRawData() void ZLimbTable::DeclareReferences(const std::string& prefix) { - std::string varPrefix = prefix; - if (name != "") - varPrefix = name; + std::string varPrefix = name; + if (varPrefix == "") + varPrefix = prefix; ZResource::DeclareReferences(varPrefix); @@ -244,22 +211,39 @@ void ZLimbTable::DeclareReferences(const std::string& prefix) uint32_t limbOffset = Seg2Filespace(limbAddress, parent->baseAddress); if (!parent->HasDeclaration(limbOffset)) { - ZLimb* limb = new ZLimb(limbType, varPrefix, limbOffset, parent); + ZLimb* limb = new ZLimb(parent); + limb->ExtractFromBinary(limbOffset, limbType); + limb->SetName(limb->GetDefaultName(varPrefix)); + limb->DeclareVar(varPrefix, ""); limb->DeclareReferences(varPrefix); - limb->GetSourceOutputCode(varPrefix); parent->AddResource(limb); } } } } +Declaration* ZLimbTable::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(), auxName, limbsAddresses.size(), bodyStr); + decl->staticConf = staticConf; + return decl; +} + std::string ZLimbTable::GetBodySourceCode() const { - std::string body = ""; + std::string body; for (size_t i = 0; i < count; i++) { - std::string limbName = parent->GetDeclarationPtrName(limbsAddresses[i]); + std::string limbName; + Globals::Instance->GetSegmentedPtrName(limbsAddresses[i], parent, "", limbName); body += StringHelper::Sprintf("\t%s,", limbName.c_str()); if (i + 1 < count) @@ -269,20 +253,6 @@ std::string ZLimbTable::GetBodySourceCode() const return body; } -std::string ZLimbTable::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - std::string body = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr || decl->isPlaceholder) - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), name, limbsAddresses.size(), body); - else - decl->text = body; - - return ""; -} - std::string ZLimbTable::GetSourceTypeName() const { switch (limbType) diff --git a/tools/ZAPD/ZAPD/ZSkeleton.h b/tools/ZAPD/ZAPD/ZSkeleton.h index fb658503e6..ed003ceafd 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.h +++ b/tools/ZAPD/ZAPD/ZSkeleton.h @@ -20,15 +20,15 @@ class ZLimbTable : public ZResource public: ZLimbTable(ZFile* nParent); - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; void ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nLimbType, size_t nCount); void ParseXML(tinyxml2::XMLElement* reader) override; void ParseRawData() override; void DeclareReferences(const std::string& prefix) override; - std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(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; @@ -53,21 +53,18 @@ public: ZSkeleton(ZFile* nParent); - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; - void ParseXML(tinyxml2::XMLElement* reader) override; void ParseRawData() override; void DeclareReferences(const std::string& prefix) override; + std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; - - size_t GetRawDataSize() const override; - std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; - segptr_t GetAddress(); + size_t GetRawDataSize() const override; + DeclarationAlignment GetDeclarationAlignment() const override; + uint8_t GetLimbCount(); protected: diff --git a/tools/ZAPD/ZAPD/ZString.cpp b/tools/ZAPD/ZAPD/ZString.cpp index b545604603..965d4d6360 100644 --- a/tools/ZAPD/ZAPD/ZString.cpp +++ b/tools/ZAPD/ZAPD/ZString.cpp @@ -29,19 +29,25 @@ void ZString::ParseRawData() strData.assign(dataStart, dataStart + size); } +Declaration* ZString::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(), auxName, 0, bodyStr); + decl->staticConf = staticConf; + return decl; +} + std::string ZString::GetBodySourceCode() const { return StringHelper::Sprintf("\t\"%s\"", strData.data()); } -std::string ZString::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), name, 0, GetBodySourceCode()); - - return ""; -} - std::string ZString::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) { return StringHelper::Sprintf("#define %s_macro \"%s\"", name.c_str(), strData.data()); diff --git a/tools/ZAPD/ZAPD/ZString.h b/tools/ZAPD/ZAPD/ZString.h index 19b4abb1d3..6c58ebdcb5 100644 --- a/tools/ZAPD/ZAPD/ZString.h +++ b/tools/ZAPD/ZAPD/ZString.h @@ -9,8 +9,9 @@ public: ZString(ZFile* nParent); void ParseRawData() override; + + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceOutputHeader(const std::string& prefix) override; std::string GetSourceTypeName() const override; diff --git a/tools/ZAPD/ZAPD/ZSymbol.cpp b/tools/ZAPD/ZAPD/ZSymbol.cpp index 278c80d6c8..b24c3de4b0 100644 --- a/tools/ZAPD/ZAPD/ZSymbol.cpp +++ b/tools/ZAPD/ZAPD/ZSymbol.cpp @@ -1,4 +1,5 @@ #include "ZSymbol.h" + #include "Utils/StringHelper.h" #include "ZFile.h" @@ -54,6 +55,18 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) if (countXml != "") count = StringHelper::StrToL(countXml, 0); } + + if (registeredAttributes.at("Static").value == "On") + { + fprintf(stderr, "A can't be marked as static.\n\t Disabling static\n"); + } + staticConf = StaticConfig::Off; +} + +Declaration* ZSymbol::DeclareVar([[maybe_unused]] const std::string& prefix, + [[maybe_unused]] const std::string& bodyStr) +{ + return nullptr; } size_t ZSymbol::GetRawDataSize() const @@ -64,19 +77,17 @@ size_t ZSymbol::GetRawDataSize() const return typeSize; } -std::string ZSymbol::GetSourceOutputHeader(const std::string& prefix) +std::string ZSymbol::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) { if (isArray) { if (count == 0) - return StringHelper::Sprintf("extern %s %s%s[];\n", type.c_str(), prefix.c_str(), - name.c_str()); + return StringHelper::Sprintf("extern %s %s[];\n", type.c_str(), name.c_str()); else - return StringHelper::Sprintf("extern %s %s%s[%i];\n", type.c_str(), prefix.c_str(), - name.c_str(), count); + return StringHelper::Sprintf("extern %s %s[%i];\n", type.c_str(), name.c_str(), count); } - return StringHelper::Sprintf("extern %s %s%s;\n", type.c_str(), prefix.c_str(), name.c_str()); + return StringHelper::Sprintf("extern %s %s;\n", type.c_str(), name.c_str()); } std::string ZSymbol::GetSourceTypeName() const diff --git a/tools/ZAPD/ZAPD/ZSymbol.h b/tools/ZAPD/ZAPD/ZSymbol.h index 1094a0222c..7cb14aa9b4 100644 --- a/tools/ZAPD/ZAPD/ZSymbol.h +++ b/tools/ZAPD/ZAPD/ZSymbol.h @@ -16,10 +16,12 @@ public: void ParseXML(tinyxml2::XMLElement* reader) override; - size_t GetRawDataSize() const override; + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetSourceOutputHeader(const std::string& prefix) override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; }; diff --git a/tools/ZAPD/ZAPD/ZTexture.cpp b/tools/ZAPD/ZAPD/ZTexture.cpp index 45a6a7cce6..33ee54d1bc 100644 --- a/tools/ZAPD/ZAPD/ZTexture.cpp +++ b/tools/ZAPD/ZAPD/ZTexture.cpp @@ -1,6 +1,7 @@ #include "ZTexture.h" #include + #include "CRC32.h" #include "Globals.h" #include "Utils/BitConverter.h" @@ -21,21 +22,8 @@ ZTexture::ZTexture(ZFile* nParent) : ZResource(nParent) RegisterOptionalAttribute("TlutOffset"); } -void ZTexture::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - - auto filepath = Globals::Instance->outputPath / fs::path(name).stem(); - - std::string incStr = - StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str()); - - parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), - name, 0); -} - -void ZTexture::FromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight, - TextureType nType, bool nIsPalette) +void ZTexture::ExtractFromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight, + TextureType nType, bool nIsPalette) { width = nWidth; height = nHeight; @@ -45,6 +33,10 @@ void ZTexture::FromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeigh name = GetDefaultName(parent->GetName()); outName = name; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); CalcHash(); } @@ -339,15 +331,10 @@ void ZTexture::DeclareReferences([[maybe_unused]] const std::string& prefix) if (format == TextureType::Palette4bpp) tlutDim = 4; - auto filepath = Globals::Instance->outputPath / fs::path(name).stem(); - std::string incStr = StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), - GetExternalExtension().c_str()); - tlut = new ZTexture(parent); - tlut->FromBinary(tlutOffset, tlutDim, tlutDim, TextureType::RGBA16bpp, true); + tlut->ExtractFromBinary(tlutOffset, tlutDim, tlutDim, TextureType::RGBA16bpp, true); parent->AddTextureResource(tlutOffset, tlut); - parent->AddDeclarationIncludeArray(tlutOffset, incStr, tlut->GetRawDataSize(), - tlut->GetSourceTypeName(), tlut->GetName(), 0); + tlut->DeclareVar(prefix, ""); } else { @@ -685,7 +672,7 @@ std::string ZTexture::GetIMSizFromType() } } -std::string ZTexture::GetDefaultName(const std::string& prefix) +std::string ZTexture::GetDefaultName(const std::string& prefix) const { const char* suffix = "Tex"; if (isPalette) @@ -746,9 +733,45 @@ void ZTexture::Save(const fs::path& outFolder) #endif } +Declaration* ZTexture::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()); + + if (!Globals::Instance->cfg.texturePool.empty()) + { + CalcHash(); + + // TEXTURE POOL CHECK + const auto& poolEntry = Globals::Instance->cfg.texturePool.find(hash); + if (poolEntry != Globals::Instance->cfg.texturePool.end()) + { + incStr = StringHelper::Sprintf("%s.%s.inc.c", poolEntry->second.path.c_str(), + GetExternalExtension().c_str()); + } + } + + Declaration* decl = parent->AddDeclarationIncludeArray( + rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), auxName, GetRawDataSize() / 8); + decl->staticConf = staticConf; + return decl; +} + std::string ZTexture::GetBodySourceCode() const { - std::string sourceOutput = ""; + std::string sourceOutput; for (size_t i = 0; i < textureDataRaw.size(); i += 8) { @@ -826,7 +849,7 @@ fs::path ZTexture::GetPoolOutPath(const fs::path& defaultValue) return defaultValue; } -TextureType ZTexture::GetTextureTypeFromString(std::string str) +TextureType ZTexture::GetTextureTypeFromString(const std::string& str) { TextureType texType = TextureType::Error; diff --git a/tools/ZAPD/ZAPD/ZTexture.h b/tools/ZAPD/ZAPD/ZTexture.h index 2ec4a4c891..ef67c3f6ef 100644 --- a/tools/ZAPD/ZAPD/ZTexture.h +++ b/tools/ZAPD/ZAPD/ZTexture.h @@ -55,15 +55,16 @@ public: bool isPalette = false; - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; - void FromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight, TextureType nType, - bool nIsPalette); + void ExtractFromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t nHeight, + TextureType nType, bool nIsPalette); void FromPNG(const fs::path& pngFilePath, TextureType texType); - static TextureType GetTextureTypeFromString(std::string str); + static TextureType GetTextureTypeFromString(const std::string& str); 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; void CalcHash() override; void Save(const fs::path& outFolder) override; @@ -76,7 +77,7 @@ public: size_t GetRawDataSize() const override; std::string GetIMFmtFromType(); std::string GetIMSizFromType(); - std::string GetDefaultName(const std::string& prefix); + std::string GetDefaultName(const std::string& prefix) const override; uint32_t GetWidth() const; uint32_t GetHeight() const; void SetDimensions(uint32_t nWidth, uint32_t nHeight); diff --git a/tools/ZAPD/ZAPD/ZTextureAnimation.cpp b/tools/ZAPD/ZAPD/ZTextureAnimation.cpp index e8236f186b..4332fcf1e5 100644 --- a/tools/ZAPD/ZAPD/ZTextureAnimation.cpp +++ b/tools/ZAPD/ZAPD/ZTextureAnimation.cpp @@ -75,9 +75,11 @@ * Each of these will declare all its subsidiary arrays, using POD structs. */ #include "ZTextureAnimation.h" + #include #include #include + #include "Globals.h" #include "Utils/BitConverter.h" #include "ZFile.h" @@ -125,32 +127,6 @@ ZTextureAnimationParams::GetDefaultName([[maybe_unused]] const std::string& pref return "ShouldNotBeVIsible"; } -void ZTextureAnimationParams::DeclareVar(const std::string& prefix, - const std::string& bodyStr) const -{ - std::string auxName = name; - - if (name == "") - auxName = GetDefaultName(prefix); - - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), auxName, bodyStr); -} - -std::string ZTextureAnimationParams::GetSourceOutputCode(const std::string& prefix) -{ - std::string bodyStr = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - - if (decl == nullptr) - DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - - return ""; -} - ZResourceType ZTextureAnimationParams::GetResourceType() const { return ZResourceType::TextureAnimationParams; @@ -197,24 +173,25 @@ size_t TextureScrollingParams::GetRawDataSize() const /** * Overrides the parent version to declare an array of the params rather than just one entry. */ -void TextureScrollingParams::DeclareVar(const std::string& prefix, const std::string& bodyStr) const +Declaration* TextureScrollingParams::DeclareVar(const std::string& prefix, + const std::string& bodyStr) { std::string auxName = name; if (name == "") auxName = GetDefaultName(prefix); - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), auxName, count, bodyStr); + return parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), + GetSourceTypeName(), auxName, count, bodyStr); } std::string TextureScrollingParams::GetBodySourceCode() const { - std::string bodyStr = ""; + std::string bodyStr; for (int i = 0; i < count; i++) { - bodyStr += StringHelper::Sprintf(" { %d, %d, 0x%02X, 0x%02X },\n", rows[i].xStep, + bodyStr += StringHelper::Sprintf("\t{ %d, %d, 0x%02X, 0x%02X },\n", rows[i].xStep, rows[i].yStep, rows[i].width, rows[i].height); } @@ -318,11 +295,11 @@ void TextureColorChangingParams::DeclareReferences([[maybe_unused]] const std::s { if (primColorListAddress != 0) // NULL { - std::string primColorBodyStr = ""; + std::string primColorBodyStr; for (const auto& color : primColorList) { - primColorBodyStr += StringHelper::Sprintf(" { %d, %d, %d, %d, %d },\n", color.r, + primColorBodyStr += StringHelper::Sprintf("\t{ %d, %d, %d, %d, %d },\n", color.r, color.g, color.b, color.a, color.lodFrac); } @@ -338,11 +315,11 @@ void TextureColorChangingParams::DeclareReferences([[maybe_unused]] const std::s if (envColorListAddress != 0) // NULL { - std::string envColorBodyStr = ""; + std::string envColorBodyStr; for (const auto& color : envColorList) { - envColorBodyStr += StringHelper::Sprintf(" { %d, %d, %d, %d },\n", color.r, color.g, + envColorBodyStr += StringHelper::Sprintf("\t{ %d, %d, %d, %d },\n", color.r, color.g, color.b, color.a); } @@ -358,7 +335,7 @@ void TextureColorChangingParams::DeclareReferences([[maybe_unused]] const std::s if (frameDataListAddress != 0) // NULL { - std::string frameDataBodyStr = " "; + std::string frameDataBodyStr = "\t"; for (const auto& frame : frameDataList) { @@ -378,11 +355,17 @@ void TextureColorChangingParams::DeclareReferences([[maybe_unused]] const std::s std::string TextureColorChangingParams::GetBodySourceCode() const { - std::string bodyStr = - StringHelper::Sprintf("\n %d, %d, %s, %s, %s,\n", animLength, colorListCount, - parent->GetDeclarationPtrName(primColorListAddress).c_str(), - parent->GetDeclarationPtrName(envColorListAddress).c_str(), - parent->GetDeclarationPtrName(frameDataListAddress).c_str()); + std::string primColorListName; + std::string envColorListName; + std::string frameDataListName; + + Globals::Instance->GetSegmentedPtrName(primColorListAddress, parent, "", primColorListName); + Globals::Instance->GetSegmentedPtrName(envColorListAddress, parent, "", envColorListName); + Globals::Instance->GetSegmentedPtrName(frameDataListAddress, parent, "", frameDataListName); + + std::string bodyStr = StringHelper::Sprintf( + "\n %d, %d, %s, %s, %s,\n", animLength, colorListCount, primColorListName.c_str(), + envColorListName.c_str(), frameDataListName.c_str()); return bodyStr; } @@ -456,18 +439,18 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& { if (textureListAddress != 0) // NULL { - std::string texturesBodyStr = ""; + std::string texturesBodyStr; std::string texName; - std::string comment = ""; + std::string comment; for (const auto& tex : textureList) { - texName = parent->GetDeclarationPtrName(tex); + bool texFound = Globals::Instance->GetSegmentedPtrName(tex, parent, "", texName); // texName is a raw segmented pointer. This occurs if the texture is not declared // separately since we cannot read the format. In theory we could scan DLists for the // format on the appropriate segments. - if (texName.length() == 10 && texName.substr(0, 2) == "0x") + if (!texFound) { comment = " // Raw pointer, declare texture in XML to use proper symbol"; @@ -487,8 +470,7 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), Seg2Filespace(textureListAddress, parent->baseAddress), texName.c_str()); } - texturesBodyStr += - StringHelper::Sprintf(" %s,%s\n", texName.c_str(), comment.c_str()); + texturesBodyStr += StringHelper::Sprintf("\t%s,%s\n", texName.c_str(), comment.c_str()); } texturesBodyStr.pop_back(); @@ -503,7 +485,7 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& if (textureIndexListAddress != 0) // NULL { - std::string indicesBodyStr = " "; + std::string indicesBodyStr = "\t"; for (uint8_t index : textureIndexList) { @@ -523,10 +505,15 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& std::string TextureCyclingParams::GetBodySourceCode() const { - std::string bodyStr = - StringHelper::Sprintf("\n %d, %s, %s,\n", cycleLength, - parent->GetDeclarationPtrName(textureListAddress).c_str(), - parent->GetDeclarationPtrName(textureIndexListAddress).c_str()); + std::string textureListName; + std::string textureIndexListName; + + Globals::Instance->GetSegmentedPtrName(textureListAddress, parent, "", textureListName); + Globals::Instance->GetSegmentedPtrName(textureIndexListAddress, parent, "", + textureIndexListName); + + std::string bodyStr = StringHelper::Sprintf( + "\n %d, %s, %s,\n", cycleLength, textureListName.c_str(), textureIndexListName.c_str()); return bodyStr; } @@ -537,12 +524,6 @@ ZTextureAnimation::ZTextureAnimation(ZFile* nParent) : ZResource(nParent) { } -void ZTextureAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) -{ - ZResource::ExtractFromXML(reader, nRawDataIndex); - DeclareVar("", ""); -} - /** * Builds the array of params */ @@ -688,42 +669,34 @@ std::string ZTextureAnimation::GetDefaultName(const std::string& prefix) const return StringHelper::Sprintf("%sTexAnim_%06X", prefix.c_str(), rawDataIndex); } -void ZTextureAnimation::DeclareVar(const std::string& prefix, const std::string& bodyStr) const +Declaration* ZTextureAnimation::DeclareVar(const std::string& prefix, const std::string& bodyStr) { std::string auxName = name; if (name == "") auxName = GetDefaultName(prefix); - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), auxName, entries.size(), bodyStr); + Declaration* decl = + parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), + GetSourceTypeName(), auxName, entries.size(), bodyStr); + decl->staticConf = staticConf; + return decl; } std::string ZTextureAnimation::GetBodySourceCode() const { - std::string bodyStr = ""; + std::string bodyStr; for (const auto& entry : entries) { - bodyStr += StringHelper::Sprintf(" { %d, %d, %s },\n", entry.segment, entry.type, - parent->GetDeclarationPtrName(entry.paramsPtr).c_str()); + std::string paramName; + Globals::Instance->GetSegmentedPtrName(entry.paramsPtr, parent, "", paramName); + + bodyStr += StringHelper::Sprintf("\t{ %d, %d, %s },\n", entry.segment, entry.type, + paramName.c_str()); } bodyStr.pop_back(); return bodyStr; } - -std::string ZTextureAnimation::GetSourceOutputCode(const std::string& prefix) -{ - std::string bodyStr = GetBodySourceCode(); - - Declaration* decl = parent->GetDeclaration(rawDataIndex); - - if (decl == nullptr) - DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - - return ""; -} diff --git a/tools/ZAPD/ZAPD/ZTextureAnimation.h b/tools/ZAPD/ZAPD/ZTextureAnimation.h index d233071913..6b03eb7cf4 100644 --- a/tools/ZAPD/ZAPD/ZTextureAnimation.h +++ b/tools/ZAPD/ZAPD/ZTextureAnimation.h @@ -4,8 +4,8 @@ #include #include #include + #include "ZResource.h" -#include "tinyxml2.h" enum class TextureAnimationParamsType { @@ -26,10 +26,7 @@ public: void ExtractFromBinary(uint32_t nRawDataIndex); virtual void ExtractFromBinary(uint32_t nRawDataIndex, int count); - std::string GetSourceOutputCode(const std::string& prefix); - virtual std::string GetDefaultName(const std::string& prefix) const; - virtual void DeclareVar(const std::string& prefix, const std::string& bodyStr) const; ZResourceType GetResourceType() const; TextureAnimationParamsType type; @@ -55,7 +52,7 @@ public: std::string GetDefaultName(const std::string& prefix) const override; size_t GetRawDataSize() const override; - void DeclareVar(const std::string& prefix, const std::string& bodyStr) const override; + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetBodySourceCode() const override; int count; // 1 for Single, 2 for Dual @@ -138,20 +135,17 @@ class ZTextureAnimation : public ZResource public: ZTextureAnimation(ZFile* nParent); - void ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex) override; void ParseRawData() override; - void DeclareReferences(const std::string& prefix) override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; size_t GetRawDataSize() const override; - std::string GetDefaultName(const std::string& prefix) const; + std::string GetDefaultName(const std::string& prefix) const override; - void DeclareVar(const std::string& prefix, const std::string& bodyStr) const; + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; private: std::vector entries; -}; \ No newline at end of file +}; diff --git a/tools/ZAPD/ZAPD/ZVector.cpp b/tools/ZAPD/ZAPD/ZVector.cpp index 0b7b9f3df9..c940b0b0de 100644 --- a/tools/ZAPD/ZAPD/ZVector.cpp +++ b/tools/ZAPD/ZAPD/ZVector.cpp @@ -1,5 +1,7 @@ #include "ZVector.h" -#include + +#include + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/File.h" @@ -17,6 +19,20 @@ ZVector::ZVector(ZFile* nParent) : ZResource(nParent) RegisterRequiredAttribute("Dimensions"); } +void ZVector::ExtractFromBinary(uint32_t nRawDataIndex, ZScalarType nScalarType, + uint32_t nDimensions) +{ + rawDataIndex = nRawDataIndex; + scalarType = nScalarType; + dimensions = nDimensions; + + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + + ParseRawData(); +} + void ZVector::ParseXML(tinyxml2::XMLElement* reader) { ZResource::ParseXML(reader); @@ -34,9 +50,8 @@ void ZVector::ParseRawData() for (uint32_t i = 0; i < dimensions; i++) { - ZScalar scalar(scalarType, parent); - scalar.rawDataIndex = currentRawDataIndex; - scalar.ParseRawData(); + ZScalar scalar(parent); + scalar.ExtractFromBinary(currentRawDataIndex, scalarType); currentRawDataIndex += scalar.GetRawDataSize(); scalars.push_back(scalar); @@ -84,21 +99,17 @@ std::string ZVector::GetSourceTypeName() const std::string ZVector::GetBodySourceCode() const { - std::string body = ""; + std::string body; - for (size_t i = 0; i < this->scalars.size(); i++) - body += StringHelper::Sprintf("%6s, ", scalars[i].GetBodySourceCode().c_str()); + for (size_t i = 0; i < scalars.size(); i++) + { + body += StringHelper::Sprintf("%6s", scalars[i].GetBodySourceCode().c_str()); - return "{ " + body + "}"; -} + if (i + 1 < scalars.size()) + body += ", "; + } -std::string ZVector::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - if (parent != nullptr) - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, GetRawDataSize(), - GetSourceTypeName(), GetName(), GetBodySourceCode()); - - return ""; + return body; } ZResourceType ZVector::GetResourceType() const @@ -106,12 +117,11 @@ ZResourceType ZVector::GetResourceType() const return ZResourceType::Vector; } -void ZVector::SetScalarType(ZScalarType type) +DeclarationAlignment ZVector::GetDeclarationAlignment() const { - scalarType = type; -} - -void ZVector::SetDimensions(uint32_t dim) -{ - dimensions = dim; + if (scalars.size() == 0) + { + return DeclarationAlignment::Align4; + } + return scalars.at(0).GetDeclarationAlignment(); } diff --git a/tools/ZAPD/ZAPD/ZVector.h b/tools/ZAPD/ZAPD/ZVector.h index d700d43963..d1a738968d 100644 --- a/tools/ZAPD/ZAPD/ZVector.h +++ b/tools/ZAPD/ZAPD/ZVector.h @@ -10,24 +10,22 @@ class ZVector : public ZResource { public: + std::vector scalars; + ZScalarType scalarType; + uint32_t dimensions; + ZVector(ZFile* nParent); + void ExtractFromBinary(uint32_t nRawDataIndex, ZScalarType nScalarType, uint32_t nDimensions); + void ParseXML(tinyxml2::XMLElement* reader) override; void ParseRawData() override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; bool DoesSupportArray() const override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; size_t GetRawDataSize() const override; - - void SetScalarType(ZScalarType type); - void SetDimensions(uint32_t dim); - -protected: - std::vector scalars; - ZScalarType scalarType; - uint32_t dimensions; + DeclarationAlignment GetDeclarationAlignment() const override; }; diff --git a/tools/ZAPD/ZAPD/ZVtx.cpp b/tools/ZAPD/ZAPD/ZVtx.cpp index 8b825b1dbf..d5214e840a 100644 --- a/tools/ZAPD/ZAPD/ZVtx.cpp +++ b/tools/ZAPD/ZAPD/ZVtx.cpp @@ -1,4 +1,5 @@ #include "ZVtx.h" + #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" #include "ZFile.h" @@ -36,27 +37,19 @@ void ZVtx::ParseRawData() a = rawData[rawDataIndex + 15]; } +Declaration* ZVtx::DeclareVar(const std::string& prefix, const std::string& bodyStr) +{ + Declaration* decl = ZResource::DeclareVar(prefix, bodyStr); + decl->isExternal = true; + return decl; +} + std::string ZVtx::GetBodySourceCode() const { return StringHelper::Sprintf("VTX(%i, %i, %i, %i, %i, %i, %i, %i, %i)", x, y, z, s, t, r, g, b, a); } -std::string ZVtx::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - std::string output = GetBodySourceCode(); - - if (parent != nullptr) - { - Declaration* decl = - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, GetRawDataSize(), - GetSourceTypeName(), name, output); - decl->isExternal = true; - } - - return ""; -} - size_t ZVtx::GetRawDataSize() const { return 16; @@ -86,3 +79,8 @@ std::string ZVtx::GetExternalExtension() const { return "vtx"; } + +DeclarationAlignment ZVtx::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align16; +} diff --git a/tools/ZAPD/ZAPD/ZVtx.h b/tools/ZAPD/ZAPD/ZVtx.h index feed307665..018a1d4a9a 100644 --- a/tools/ZAPD/ZAPD/ZVtx.h +++ b/tools/ZAPD/ZAPD/ZVtx.h @@ -18,8 +18,9 @@ public: ZVtx(ZFile* nParent); void ParseRawData() override; + + Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; bool IsExternalResource() const override; bool DoesSupportArray() const override; @@ -28,6 +29,5 @@ public: std::string GetExternalExtension() const override; size_t GetRawDataSize() const override; - -protected: -}; \ No newline at end of file + DeclarationAlignment GetDeclarationAlignment() const override; +}; diff --git a/tools/ZAPD/ZAPDUtils/Color3b.h b/tools/ZAPD/ZAPDUtils/Color3b.h index d2412972ca..7e59f6b7f7 100644 --- a/tools/ZAPD/ZAPDUtils/Color3b.h +++ b/tools/ZAPD/ZAPDUtils/Color3b.h @@ -6,6 +6,16 @@ struct Color3b { uint8_t r, g, b; - Color3b() { r = 0; g = 0; b = 0; }; - Color3b(uint8_t nR, uint8_t nG, uint8_t nB) { r = nR; g = nG; b = nB; }; + Color3b() + { + r = 0; + g = 0; + b = 0; + }; + Color3b(uint8_t nR, uint8_t nG, uint8_t nB) + { + r = nR; + g = nG; + b = nB; + }; }; \ No newline at end of file diff --git a/tools/ZAPD/ZAPDUtils/StrHash.h b/tools/ZAPD/ZAPDUtils/StrHash.h index 858c517614..68d22b9cd6 100644 --- a/tools/ZAPD/ZAPDUtils/StrHash.h +++ b/tools/ZAPD/ZAPDUtils/StrHash.h @@ -6,8 +6,7 @@ typedef uint32_t strhash; -[[maybe_unused]] -static strhash CRC32B(unsigned char* message, int32_t size) +[[maybe_unused]] static strhash CRC32B(unsigned char* message, int32_t size) { int32_t byte = 0, crc = 0; int32_t mask = 0; @@ -29,8 +28,7 @@ static strhash CRC32B(unsigned char* message, int32_t size) return ~(uint32_t)(crc); } -[[maybe_unused]] -constexpr static strhash CRC32BCT(const char* message, int32_t size) +[[maybe_unused]] constexpr static strhash CRC32BCT(const char* message, int32_t size) { int32_t byte = 0, crc = 0; int32_t mask = 0; diff --git a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp index b05188883b..a4cf782294 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp +++ b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp @@ -1,7 +1,7 @@ #include "BinaryReader.h" -#include "Stream.h" #include #include +#include "Stream.h" BinaryReader::BinaryReader(Stream* nStream) { @@ -23,7 +23,7 @@ uint32_t BinaryReader::GetBaseAddress() return stream->GetBaseAddress(); } -void BinaryReader::Read([[maybe_unused]]char* buffer, int32_t length) +void BinaryReader::Read([[maybe_unused]] char* buffer, int32_t length) { stream->Read(length); } @@ -133,9 +133,9 @@ Color3b BinaryReader::ReadColor3b() std::string BinaryReader::ReadString() { - std::string res = ""; + std::string res; char c; - + do { c = ReadChar(); @@ -144,6 +144,5 @@ std::string BinaryReader::ReadString() res += c; } while (c != 0); - return res; } \ No newline at end of file diff --git a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.h b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.h index 9e28718126..cf0eeb42c9 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.h +++ b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.h @@ -1,14 +1,14 @@ #pragma once -#include "Stream.h" +#include +#include +#include +#include +#include "../Color3b.h" #include "../Vec2f.h" #include "../Vec3f.h" #include "../Vec3s.h" -#include "../Color3b.h" -#include -#include -#include -#include +#include "Stream.h" class BinaryReader { @@ -16,7 +16,7 @@ public: BinaryReader(Stream* nStream); void Close(); - + void Seek(uint32_t offset, SeekOffsetType seekType); uint32_t GetBaseAddress(); @@ -37,7 +37,7 @@ public: Vec2f ReadVec2f(); Color3b ReadColor3b(); std::string ReadString(); - + protected: std::shared_ptr stream; }; \ No newline at end of file diff --git a/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.cpp b/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.cpp index a48d40d7fa..87bc0ac684 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.cpp +++ b/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.cpp @@ -85,7 +85,7 @@ void BinaryWriter::Write(double value) stream->Write((char*)&value, sizeof(double)); } -void BinaryWriter::Write(std::string str) +void BinaryWriter::Write(const std::string& str) { int strLen = str.size(); stream->Write((char*)&strLen, sizeof(int)); diff --git a/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.h b/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.h index e187b8c3e4..e224d182e3 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.h +++ b/tools/ZAPD/ZAPDUtils/Utils/BinaryWriter.h @@ -28,7 +28,7 @@ public: void Write(uint64_t value); void Write(float value); void Write(double value); - void Write(std::string str); + void Write(const std::string& str); protected: std::shared_ptr stream; diff --git a/tools/ZAPD/ZAPDUtils/Utils/Directory.h b/tools/ZAPD/ZAPDUtils/Utils/Directory.h index adb2e17d28..eaa6a26abb 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/Directory.h +++ b/tools/ZAPD/ZAPDUtils/Utils/Directory.h @@ -23,7 +23,7 @@ public: static void CreateDirectory(const std::string& path) { - std::string curPath = ""; + std::string curPath; std::vector split = StringHelper::Split(path, "/"); for (std::string s : split) diff --git a/tools/ZAPD/ZAPDUtils/Utils/Path.h b/tools/ZAPD/ZAPDUtils/Utils/Path.h index fd3c658cce..496a0ae13c 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/Path.h +++ b/tools/ZAPD/ZAPDUtils/Utils/Path.h @@ -15,16 +15,16 @@ namespace fs = std::experimental::filesystem; class Path { public: - static std::string GetFileName(const std::string& input) + static std::string GetFileName(const fs::path& input) { - std::vector split = StringHelper::Split(input, "/"); - return split[split.size() - 1]; + // https://en.cppreference.com/w/cpp/filesystem/path/filename + return input.filename(); }; - static std::string GetFileNameWithoutExtension(const std::string& input) + static std::string GetFileNameWithoutExtension(const fs::path& input) { - std::vector split = StringHelper::Split(input, "/"); - return split[split.size() - 1].substr(0, split[split.size() - 1].find_last_of(".")); + // https://en.cppreference.com/w/cpp/filesystem/path/stem + return input.stem(); }; static std::string GetFileNameExtension(const std::string& input) @@ -32,22 +32,19 @@ public: return input.substr(input.find_last_of("."), input.length()); }; - static std::string GetPath(const std::string& input) + static fs::path GetPath(const std::string& input) { std::vector split = StringHelper::Split(input, "/"); - std::string output = ""; + fs::path output; for (std::string str : split) { if (str.find_last_of(".") == std::string::npos) - output += str + "/"; + output /= str; } return output; }; - static std::string GetDirectoryName(const fs::path& path) - { - return path.parent_path().u8string(); - }; + static fs::path GetDirectoryName(const fs::path& path) { return path.parent_path(); }; }; diff --git a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h index ed8921cac7..74607ce3a2 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h +++ b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h @@ -81,7 +81,7 @@ public: { char buffer[32768]; // char buffer[2048]; - std::string output = ""; + std::string output; va_list va; va_start(va, format); diff --git a/tools/ZAPD/ZAPDUtils/Vec2f.h b/tools/ZAPD/ZAPDUtils/Vec2f.h index e9c5059556..9d4beeb465 100644 --- a/tools/ZAPD/ZAPDUtils/Vec2f.h +++ b/tools/ZAPD/ZAPDUtils/Vec2f.h @@ -6,6 +6,14 @@ struct Vec2f { float x, y; - Vec2f() { x = 0; y = 0; }; - Vec2f(float nX, float nY) { x = nX; y = nY; }; + Vec2f() + { + x = 0; + y = 0; + }; + Vec2f(float nX, float nY) + { + x = nX; + y = nY; + }; }; \ No newline at end of file diff --git a/tools/ZAPD/ZAPDUtils/Vec3f.h b/tools/ZAPD/ZAPDUtils/Vec3f.h index cde5202d14..4bfbb3c254 100644 --- a/tools/ZAPD/ZAPDUtils/Vec3f.h +++ b/tools/ZAPD/ZAPDUtils/Vec3f.h @@ -6,6 +6,16 @@ struct Vec3f { float x, y, z; - Vec3f() { x = 0; y = 0; z = 0; }; - Vec3f(float nX, float nY, float nZ) { x = nX; y = nY; z = nZ; }; + Vec3f() + { + x = 0; + y = 0; + z = 0; + }; + Vec3f(float nX, float nY, float nZ) + { + x = nX; + y = nY; + z = nZ; + }; }; \ No newline at end of file diff --git a/tools/ZAPD/copycheck.py b/tools/ZAPD/copycheck.py index d13f9843d4..36288f6853 100755 --- a/tools/ZAPD/copycheck.py +++ b/tools/ZAPD/copycheck.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import os from shutil import copyfile diff --git a/tools/ZAPD/docs/zapd_extraction_xml_reference.md b/tools/ZAPD/docs/zapd_extraction_xml_reference.md index d07ef98112..06b95bb575 100644 --- a/tools/ZAPD/docs/zapd_extraction_xml_reference.md +++ b/tools/ZAPD/docs/zapd_extraction_xml_reference.md @@ -32,6 +32,7 @@ This document aims to be a small reference of how to create a compatible xml fil - [Cutscene](#cutscene) - [Array](#array) - [Path](#path) + - [PlayerAnimationData](#playeranimationdata) ## Basic XML @@ -69,6 +70,20 @@ For most resources inside a `` tag **you should also set an `Offset` attri It's worth noting that every tag expects a `Name="gNameOfTheAsset"`. This is will be the name of the extracted variable in the output C code. Every asset must be prefixed with `g` and the suffix should represent the type of the variable. +Every tag can accept a `Static` attribute to specify if the asset should be marked as `static` or not. +There are 3 valid values (defaults to `Global`): + +- `Global`: Mark static if the flag `--static` was used. +- `On`: Override the global config and **always mark** as `static`. +- `Off`: Override the global config and **don't mark** as `static`. + +This table summarizes if the asset will be marked `static` (✅) or not (❌) +| `Static=""` attribute in XML | Without `--static` flag | With `--static` flag | +| ---------------------------- | ----------------------- | -------------------- | +| `On` | ✅ | ✅ | +| `Global` (default) | ❌ | ✅ | +| `Off` | ❌ | ❌ | + ------------------------- ### File @@ -83,7 +98,7 @@ It's worth noting that every tag expects a `Name="gNameOfTheAsset"`. This is wil - `Name`: Required. The name of the file in `baserom/` which will be extracted. - `OutName`: Optional. The output name of the generated C source file. Defaults to the value passed to `Name`. - - `Segment`: Required. This is the segment number of the current file. Expects a decimal number, usually 6 if it is an object, or 128 for overlays (It's kinda a whacky hack to get around of the `0x80` addresses). + - `Segment`: Optional. This is the segment number of the current file. Expects a decimal number between 0 and 15 inclusive, usually 6 if it is an object. If not specified, the file will use VRAM instead of segmented addresses. - `BaseAddress`: Optional. RAM address of the file. Expects a hex number (with `0x` prefix). Default value: `0`. - `RangeStart`: Optional. File offset where the extraction will begin. Hex. Default value: `0x000000000`. - `RangeEnd`: Optional. File offset where the extraction will end. Hex. Default value: `0xFFFFFFFF`. @@ -91,6 +106,27 @@ It's worth noting that every tag expects a `Name="gNameOfTheAsset"`. This is wil ------------------------- +### ExternalFile + +Allows ZAPD to map segmented addresses to variables declared in other files by using its XML. + +It is useful for objects that use variables from `gameplay_keep`, `gameplay_dangeon_keep`, `gameplay_field_keep`, etc. + +This tag can be used in the global `config.xml` file. + +- Example of this tag: + +```xml + +``` + +- Attributes: + + - `XmlPath`: Required. The path of the XML, relative to the value set by `ExternalXMLFolder` in the configuration file. + - `OutPath`: Required. The path were the header for the corresponding external file is. It is used to `#include` it in the generated `.c` file. + +------------------------- + ### Texture Textures are extracted as `.png` files. @@ -202,7 +238,6 @@ A.k.a. Display list, or Gfx. A data type exclusive to Majora's Mask, that has scrolling, color changing, and texture changing capabilities. Declaring the main array will generate everything else; textures for the TextureCycle type must be declared manually in the XML to use symbols. (If it does reference any undeclared textures, ZAPD will warn and give the their offsets.) - ```xml ``` @@ -402,6 +437,7 @@ extern u8 gJsjutanShadowTex[2048]; - `Type`: The type of the declared variable. If missing, it will default to `void*`. - `TypeSize`: The size in bytes of the type. If missing, it will default to `4` (the size of a word and a pointer). Integer or hex value. - `Count`: Optional. If it is present, the variable will be declared as an array instead of a plain variable. The value of this attribute specifies the length of the array. If `Count` is present but it has no value (`Count=""`), then the length of the array will not be specified either in the declared variable. Integer or hex value. + - `Static`: This attribute can't be enabled on a Symbol node. A warning will be showed in this case. ------------------------- @@ -570,8 +606,6 @@ Currently, only [`Scalar`](#scalar), [`Vector`](#vector) and [`Vtx`](#vtx) suppo ------------------------- -------------------------- - ### Path - Example: @@ -586,3 +620,20 @@ Currently, only [`Scalar`](#scalar), [`Vector`](#vector) and [`Vtx`](#vtx) suppo - `NumPaths`: Optional. The amount of paths contained in the array. It must be a positive integer. ------------------------- + +### PlayerAnimationData + +Allows the extraction of the specific data of the player animations which are found in the `link_animetion` file. + +- Example: + +```xml + +``` + +- Attributes: + + - `Name`: Required. Suxffixed by `AnimData`. + - `FrameCount`: Required. The length of the animation in frames. It must be a positive integer. + +------------------------- diff --git a/tools/ZAPD/docs/zapd_xml_spec.md b/tools/ZAPD/docs/zapd_xml_spec.md new file mode 100644 index 0000000000..9fcc0d4aab --- /dev/null +++ b/tools/ZAPD/docs/zapd_xml_spec.md @@ -0,0 +1,55 @@ +# ZAPD XML specification + +ZAPD XMLs use a restrictive subset of the XML standard: any ZAPD XML must be a valid XML (All elements starting with `` ending appropriately with ``, single "empty-element" tags with `/` at the end, etc.). + +Reminder that in + +```xml + + + + + + + + + +``` + +``, ``, `` are *children* of ``, but `` is not. `` is a *descendent* of `` and a child of ``. + +- Every XML's outermost element start/end tag is a single ``. +- The children of a `` must be ``s. +- A `` has *resources* as children. A resource is almost always single empty-element tag, and has one of the types + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + - `` + +- A `` cannot descend from a ``. +- All resources must be children of a ``. +- `` is the only paired resource tag enclosing an element; the element must be a single resource tag, one of + - `` + - `` + - `` diff --git a/tools/ZAPDConfigs/MM/Config.xml b/tools/ZAPDConfigs/MM/Config.xml index 2817cf591e..6570400107 100644 --- a/tools/ZAPDConfigs/MM/Config.xml +++ b/tools/ZAPDConfigs/MM/Config.xml @@ -2,4 +2,12 @@ + + + + diff --git a/tools/asm-differ/.gitrepo b/tools/asm-differ/.gitrepo index 12bcbb869b..d3e4418c9e 100644 --- a/tools/asm-differ/.gitrepo +++ b/tools/asm-differ/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/simonlindholm/asm-differ.git branch = main - commit = 55bba23ad53dea059db783bb5598bc0c299863e6 - parent = d3fd19b21c07664e488216b515b0e9a4ecbfa578 + commit = f30d43aceba6291aa3c08b7317b0458b6d734321 + parent = e977dfeb374c6de4076ca9a0f44ba5a6a701d849 method = merge cmdver = 0.4.3 diff --git a/tools/asm-differ/__init__.py b/tools/asm-differ/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/asm-differ/diff.py b/tools/asm-differ/diff.py index 3a2f844a20..d7ac3f3440 100755 --- a/tools/asm-differ/diff.py +++ b/tools/asm-differ/diff.py @@ -488,7 +488,12 @@ def get_objdump_executable(objdump_executable: Optional[str]) -> str: if objdump_executable is not None: return objdump_executable - for objdump_cand in ["mips-linux-gnu-objdump", "mips64-elf-objdump"]: + objdump_candidates = [ + "mips-linux-gnu-objdump", + "mips64-elf-objdump", + "mips-elf-objdump", + ] + for objdump_cand in objdump_candidates: try: subprocess.check_call( [objdump_cand, "--version"], @@ -502,7 +507,7 @@ def get_objdump_executable(objdump_executable: Optional[str]) -> str: pass return fail( - "Missing binutils; please ensure mips-linux-gnu-objdump or mips64-elf-objdump exist, or configure objdump_executable." + f"Missing binutils; please ensure {' or '.join(objdump_candidates)} exists, or configure objdump_executable." ) @@ -1480,7 +1485,6 @@ ARM32_BRANCH_INSTRUCTIONS = { } AARCH64_BRANCH_INSTRUCTIONS = { - "bl", "b", "b.eq", "b.ne", @@ -1534,7 +1538,7 @@ MIPS_SETTINGS = ArchSettings( re_int=re.compile(r"[0-9]+"), re_comment=re.compile(r"<.*?>"), re_reg=re.compile( - r"\$?\b(a[0-3]|t[0-9]|s[0-8]|at|v[01]|f[12]?[0-9]|f3[01]|k[01]|fp|ra|zero)\b" + r"\$?\b(a[0-7]|t[0-9]|s[0-8]|at|v[01]|f[12]?[0-9]|f3[01]|kt?[01]|fp|ra|zero)\b" ), re_sprel=re.compile(r"(?<=,)([0-9]+|0x[0-9a-f]+)\(sp\)"), re_large_imm=re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}"), @@ -1578,7 +1582,7 @@ AARCH64_SETTINGS = ArchSettings( re_large_imm=re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}"), re_imm=re.compile(r"(? Tuple[str, str, str]: def process_mips_reloc(row: str, prev: str, arch: ArchSettings) -> str: + if "R_MIPS_NONE" in row: + # GNU as emits no-op relocations immediately after real ones when + # assembling with -mabi=64. Return without trying to parse 'imm' as an + # integer. + return prev before, imm, after = parse_relocated_line(prev) repl = row.split()[-1] if imm != "0": @@ -2375,6 +2384,7 @@ def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: ) ) + output = output[config.skip_lines :] return Diff(lines=output, score=score) @@ -2608,10 +2618,9 @@ class Display: self.last_diff_output = diff_output meta, diff_lines = align_diffs(last_diff_output, diff_output, self.config) - diff_lines = diff_lines[self.config.skip_lines :] output = self.config.formatter.table(meta, diff_lines) refresh_key = ( - [[col.key2 for col in x[1:]] for x in diff_lines], + [line.key2 for line in diff_output.lines], diff_output.score, ) return (output, refresh_key) diff --git a/tools/decomp-permuter/.gitrepo b/tools/decomp-permuter/.gitrepo index 905668e4d2..270e3df564 100644 --- a/tools/decomp-permuter/.gitrepo +++ b/tools/decomp-permuter/.gitrepo @@ -7,6 +7,6 @@ remote = https://github.com/simonlindholm/decomp-permuter.git branch = main commit = a20bac9422b6d8adbf7c06473c2ae3c3fee16be5 - parent = 96e44d31f814b690ccc0a462513792c8daf6c9fd + parent = 2668eec556c01fa2f4c16a203c93c208dc03e639 method = merge cmdver = 0.4.3 diff --git a/tools/graphovl/.gitrepo b/tools/graphovl/.gitrepo index b55933807f..064b8ee581 100644 --- a/tools/graphovl/.gitrepo +++ b/tools/graphovl/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/AngheloAlf/graphovl.git branch = master - commit = eb25be944156ec859853f0aa28aea66c98b1ca99 - parent = ad3db144b2cdd212f61fac695e05dc06b9569699 + commit = f5fe93d75bb75ea4bea65f62c43f41f6a1e70679 + parent = 6c5a50ef95f351acc7c4c0455a347a94443adbe1 method = merge cmdver = 0.4.3 diff --git a/tools/graphovl/graphovl.py b/tools/graphovl/graphovl.py index b65657b570..28f0a361c0 100755 --- a/tools/graphovl/graphovl.py +++ b/tools/graphovl/graphovl.py @@ -3,10 +3,18 @@ # Generates graphs for actor overlay files # -from graphviz import Digraph -import argparse, os, re +import argparse, os, re, sys from configparser import ConfigParser +try: + from graphviz import Digraph +except ModuleNotFoundError: + print("Module 'graphviz' is not installed", file=sys.stderr) + print("You can install it using: pip3 install graphviz", file=sys.stderr) + print("You may also need to install it on your system", file=sys.stderr) + print("On Debian/Ubuntu derivates you can use: apt install graphviz", file=sys.stderr) + sys.exit(1) + script_dir = os.path.dirname(os.path.realpath(__file__)) config = ConfigParser() @@ -57,7 +65,12 @@ def capture_setupaction_calls(content): # Captures the function name of a setupaction call def capture_setupaction_call_arg(content): - return [x.group().split(",")[1].strip().split(");")[0].strip() for x in re.finditer(setupaction_regexpr, content)] + transitionList = [] + for x in re.finditer(setupaction_regexpr, content): + func = x.group().split(",")[1].strip().split(");")[0].strip() + if func not in transitionList: + transitionList.append(func) + return transitionList # Search for the function definition by supplied function name def definition_by_name(content, name): @@ -171,7 +184,8 @@ def action_var_values_in_func(code_body, action_var, macros, enums): elif index in enums: index = str(enums[index]) - transition.append(index) + if index not in transition: + transition.append(index) return transition def setup_line_numbers(content, func_names): @@ -201,7 +215,7 @@ def addFunctionTransitionToGraph(dot, index: int, func_name: str, action_transit edgeColor = config.get("colors", "actionFuncInit") dot.edge(indexStr, funcIndex, color=edgeColor) -def addCallNamesToGraph(dot, func_names: list, index: int, code_body: str, setupAction=False, rawActorFunc=False): +def addCallNamesToGraph(dot, func_names: list, index: int, code_body: str, removeList: list, setupAction=False, rawActorFunc=False): edgeColor = config.get("colors", "funcCall") fontColor = config.get("colors", "fontcolor") bubbleColor = config.get("colors", "bubbleColor") @@ -213,6 +227,8 @@ def addCallNamesToGraph(dot, func_names: list, index: int, code_body: str, setup continue if call in seen: continue + if call in removeList: + continue if setupAction and "_SetupAction" in call: continue @@ -226,6 +242,27 @@ def addCallNamesToGraph(dot, func_names: list, index: int, code_body: str, setup dot.node(calledFuncIndex, call, fontcolor=fontColor, color=bubbleColor) dot.edge(indexStr, calledFuncIndex, color=edgeColor) +def addCallbacksToGraph(dot, func_names: list, index: int, code_body: str, transitionList: list): + edgeColor = config.get("colors", "callback") + fontColor = config.get("colors", "fontcolor") + bubbleColor = config.get("colors", "bubbleColor") + + indexStr = str(index) + seen = set() + for call_with_arguments in capture_calls(code_body): + call_with_arguments = call_with_arguments.replace("\n", "").replace(" ", "") + name, arguments = call_with_arguments.split("(", 1) + argumentList = [x.strip() for x in arguments.split(",")] + for callback in [x for x in func_names if x in argumentList]: + if callback in transitionList: + # already catched in another edge + continue + seen.add(callback) + + calledFuncIndex = str(index_of_func(callback)) + + dot.node(calledFuncIndex, callback, fontcolor=fontColor, color=bubbleColor) + dot.edge(indexStr, calledFuncIndex, color=edgeColor) def loadConfigFile(selectedStyle): # For a list of colors, see https://www.graphviz.org/doc/info/colors.html @@ -241,6 +278,7 @@ def loadConfigFile(selectedStyle): config.set('colors', 'actionFunc', 'Black') config.set('colors', 'fontColor', 'Black') config.set('colors', 'bubbleColor', 'Black') + config.set('colors', 'callback', 'blue') if os.path.exists(configFilename): config.read(configFilename) @@ -264,14 +302,20 @@ def main(): parser.add_argument("filename", help="Filename without the z_ or ovl_ prefix, e.x. Door_Ana") parser.add_argument("--loners", help="Include functions that are not called or call any other overlay function", action="store_true") parser.add_argument("-s", "--style", help="Use a color style defined in graphovl_styles folder. i.e. solarized") + parser.add_argument("--format", help="Select output file format. Defaults to 'png'", default="png") + parser.add_argument("-r", "--remove", help="A space-separated list of nodes to remove from the graph", nargs='+') args = parser.parse_args() + removeList = [] + if args.remove is not None: + removeList = args.remove + loadConfigFile(args.style) fontColor = config.get("colors", "fontcolor") bubbleColor = config.get("colors", "bubbleColor") fname = args.filename - dot = Digraph(comment = fname, format = 'png') + dot = Digraph(comment = fname, format = args.format) dot.attr(bgcolor=config.get("colors", "background")) contents = "" @@ -325,6 +369,9 @@ def main(): action_var = actionVarMatch.group(1).strip() for index, func_name in enumerate(func_names): + if func_name in removeList: + continue + indexStr = str(index) if args.loners: dot.node(indexStr, func_name, fontcolor=fontColor, color=bubbleColor) @@ -348,13 +395,20 @@ def main(): """ transitionList = action_var_values_in_func(code_body, actionIdentifier, macros, enums) + # Remove functions calls + transitionList = [x for x in transitionList if x not in removeList] + for action_transition in transitionList: addFunctionTransitionToGraph(dot, index, func_name, action_transition) - addCallNamesToGraph(dot, func_names, index, code_body, setupAction, rawActorFunc) + addCallNamesToGraph(dot, func_names, index, code_body, removeList, setupAction, rawActorFunc) + + addCallbacksToGraph(dot, func_names, index, code_body, transitionList) # print(dot.source) - dot.render("graphs/" + fname + ".gv") + outname = f"graphs/{fname}.gv" + dot.render(outname) + print(f"Written to {outname}.{args.format}") if __name__ == "__main__": main() diff --git a/tools/graphovl/graphovl_styles/classic.ini b/tools/graphovl/graphovl_styles/classic.ini index 3264ad34a2..9a90dbbc80 100644 --- a/tools/graphovl/graphovl_styles/classic.ini +++ b/tools/graphovl/graphovl_styles/classic.ini @@ -5,3 +5,4 @@ actionFuncInit = green actionFunc = Black fontColor = Black bubbleColor = Black +callback = blue diff --git a/tools/graphovl/graphovl_styles/soft.ini b/tools/graphovl/graphovl_styles/soft.ini index 61cb50a8a3..2e936e97f7 100644 --- a/tools/graphovl/graphovl_styles/soft.ini +++ b/tools/graphovl/graphovl_styles/soft.ini @@ -5,3 +5,4 @@ actionfuncinit = seagreen1 actionfunc = Black fontColor = Black bubbleColor = Black +callback = deepskyblue diff --git a/tools/graphovl/graphovl_styles/solarized_dark.ini b/tools/graphovl/graphovl_styles/solarized_dark.ini index 5e4f28e2b4..b784893115 100644 --- a/tools/graphovl/graphovl_styles/solarized_dark.ini +++ b/tools/graphovl/graphovl_styles/solarized_dark.ini @@ -5,3 +5,4 @@ actionFuncInit = #dc322f actionFunc = #b58900 fontColor = #839496 bubbleColor = #839496 +callback = #268bd2 diff --git a/tools/graphovl/graphovl_styles/solarized_light.ini b/tools/graphovl/graphovl_styles/solarized_light.ini index 6eb37973ac..b6b4b116aa 100644 --- a/tools/graphovl/graphovl_styles/solarized_light.ini +++ b/tools/graphovl/graphovl_styles/solarized_light.ini @@ -5,3 +5,4 @@ actionFuncInit = #dc322f actionFunc = #b58900 fontColor = #657b83 bubbleColor = #657b83 +callback = #268bd2