diff options
| author | Anghelo Carvajal <angheloalf95@gmail.com> | 2021-10-16 18:55:56 -0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-16 17:55:56 -0400 |
| commit | e7a8a48cf361a7591b88592eb3e333ddf8d3ab34 (patch) | |
| tree | 4f63eac4c2136dd74e05593ea200b2c24c284a3f | |
| parent | 3e9ed72e202b1165152d42f7d160695f9f2f233a (diff) | |
`ExternalFile`: Expose other XML's declarations during extraction (#151)
* proof of concept
* fix header include paths
* GetDeclarationAlignment and others
* this should fix this
* minor
* DeclareVar in ExtractFromXML
* fix vtx intersections
* Fix segmented vtxs
* --version
* zcollision changes
* Use GetSegmentedPtrName a lot more
* memory related stuff
* minor style fixes and use the actual symbol for zlinkanimation instead of the hex address
* Simplify lots of GetSourceOutputCode
* ZSkeleton cleanup and other changes
* Elevate unknown types in skeleton to errors
* ZAnimation cleanup
* Add ExternalFile to config
* delete some code
* Remove unused code
* fix conflicts
* format
* remove redundant constructors
* minor fixes
* fix vtx warnings
* extract every vtx as standalone files
* format
* uups
* Bugfix: don't create extra blank files
* Fix some Vtx warnings and remove "defaulting to normal" in skeleton error
* Refactor ZLimb
* Make each limb to look up in every file for dlists
* Use GetSegmentedArrayIndexedName in VTX references in dlists
* simplify simple condition
* search by type
* run format
* Revert "search by type"
This reverts commit a049bdfc94c4ab04613b354f466dee836a20508a.
* Add range checks
* uups
* Always set rangeEnd
* special case zsymbol
* Revert "Revert "search by type""
This reverts commit 3f6e77c780bd30dc7000614304021a0940168316.
* symbol fix and IsOffsetInFileRange
* Bugfix and minor checks
* run format
* Don't extract data from external files
* Fix extraction of overly big tluts
* Minor changes
* More minor fixes
* Fix clang warnings
* Remove unused parameter
* Fix merge issues
* Fix ZLimbTable::DeclareVar
* Fix limbs not naming properly their DLists
* Remove segment number check
* Fix merge problems
* Run formatter
* Maybe fix?
* path
* empty commit
* Fix a typo
* Fix merge issues
* Fix null ptr dereferencing
* Fix merge issues and some clang warnings
* Format
* Fix not-matching
* Format
* Fix merge issues
* Fix exporter
* Last fixes I hope
* Fix merge issues
* format
* fix
* fix
* I'm dumb
* format
* static fix
* Whoops
* fix asan
* Fix?
* fix
* reduce artificial changes
* reduce artificial changes 2
* reorder more stuff
* format
* fix borken thing
* Remove redundant stuff in zfile
* fix
* Format
* Fix conflict issues
* format
* cleanup header includes
* format
* Add error checks in for ExternalXMLFolder
* format
66 files changed, 2130 insertions, 1957 deletions
diff --git a/ExporterTest/RoomExporter.cpp b/ExporterTest/RoomExporter.cpp index cc2a832..c4a6844 100644 --- a/ExporterTest/RoomExporter.cpp +++ b/ExporterTest/RoomExporter.cpp @@ -234,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(); + 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); @@ -34,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 diff --git a/ZAPD/Declaration.cpp b/ZAPD/Declaration.cpp index eafe948..d2a86ff 100644 --- a/ZAPD/Declaration.cpp +++ b/ZAPD/Declaration.cpp @@ -3,26 +3,29 @@ #include "Globals.h" #include "Utils/StringHelper.h" -Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, const std::string& nText) +Declaration::Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nText) { + address = nAddress; alignment = nAlignment; size = nSize; text = nText; } -Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, const std::string& nVarType, - const std::string& nVarName, bool nIsArray, const std::string& nText) - : Declaration(nAlignment, 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, size_t nSize, const std::string& nVarType, - const std::string& nVarName, bool nIsArray, size_t nArrayItemCnt, - const std::string& nText) - : Declaration(nAlignment, 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; @@ -30,10 +33,10 @@ Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, const st arrayItemCnt = nArrayItemCnt; } -Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, const std::string& nVarType, - const std::string& nVarName, bool nIsArray, +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(nAlignment, nSize, nText) + : Declaration(nAddress, nAlignment, nSize, nText) { varType = nVarType; varName = nVarName; @@ -41,17 +44,17 @@ Declaration::Declaration(DeclarationAlignment nAlignment, size_t nSize, const st arrayItemCntStr = nArrayItemCntStr; } -Declaration::Declaration(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(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(const std::string& nIncludePath, size_t nSize, const std::string& nVarType, - const std::string& nVarName) - : Declaration(DeclarationAlignment::Align4, 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; diff --git a/ZAPD/Declaration.h b/ZAPD/Declaration.h index 7d2eeba..138524a 100644 --- a/ZAPD/Declaration.h +++ b/ZAPD/Declaration.h @@ -26,6 +26,7 @@ enum class StaticConfig class Declaration { public: + offset_t address; DeclarationAlignment alignment; size_t size; std::string preText; @@ -47,19 +48,21 @@ public: bool declaredInXml = false; StaticConfig staticConf = StaticConfig::Global; - Declaration(DeclarationAlignment nAlignment, size_t nSize, const std::string& nVarType, - const std::string& nVarName, bool nIsArray, const std::string& nText); - Declaration(DeclarationAlignment nAlignment, size_t nSize, const std::string& nVarType, - const std::string& nVarName, bool nIsArray, size_t nArrayItemCnt, + Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nVarType, const std::string& nVarName, bool nIsArray, const std::string& nText); - Declaration(DeclarationAlignment nAlignment, size_t nSize, const std::string& nVarType, - const std::string& nVarName, bool nIsArray, const std::string& nArrayItemCntStr, - const std::string& nText); - Declaration(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(const std::string& nIncludePath, size_t nSize, const std::string& nVarType, - const std::string& nVarName); + 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; @@ -71,5 +74,6 @@ public: std::string GetStaticForwardDeclarationStr() const; protected: - Declaration(DeclarationAlignment nAlignment, size_t nSize, const std::string& nText); + Declaration(offset_t nAddress, DeclarationAlignment nAlignment, size_t nSize, + const std::string& nText); }; diff --git a/ZAPD/GameConfig.cpp b/ZAPD/GameConfig.cpp index 69ce045..f197493 100644 --- a/ZAPD/GameConfig.cpp +++ b/ZAPD/GameConfig.cpp @@ -2,14 +2,27 @@ #include <functional> #include <string_view> + #include "Utils/Directory.h" #include "Utils/File.h" #include "Utils/Path.h" +#include "ZFile.h" #include "tinyxml2.h" using ConfigFunc = void (GameConfig::*)(const tinyxml2::XMLElement&); -void GameConfig::ReadTexturePool(const std::string& texturePoolXmlPath) +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()); @@ -41,7 +54,7 @@ void GameConfig::ReadTexturePool(const std::string& texturePoolXmlPath) } } -void GameConfig::GenSymbolMap(const std::string& symbolMapPath) +void GameConfig::GenSymbolMap(const fs::path& symbolMapPath) { auto symbolLines = File::ReadAllLines(symbolMapPath); @@ -58,21 +71,14 @@ void GameConfig::GenSymbolMap(const std::string& symbolMapPath) void GameConfig::ConfigFunc_SymbolMap(const tinyxml2::XMLElement& element) { std::string fileName = element.Attribute("File"); - GenSymbolMap(Path::GetDirectoryName(configFilePath) + "/" + fileName); -} - -void GameConfig::ConfigFunc_Segment(const tinyxml2::XMLElement& element) -{ - std::string fileName = element.Attribute("File"); - int32_t segNumber = element.IntAttribute("Number"); - segmentRefs[segNumber] = std::move(fileName); + GenSymbolMap(Path::GetDirectoryName(configFilePath) / fileName); } void GameConfig::ConfigFunc_ActorList(const tinyxml2::XMLElement& element) { std::string fileName = element.Attribute("File"); std::vector<std::string> lines = - File::ReadAllLines(Path::GetDirectoryName(configFilePath) + "/" + fileName); + File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName); for (auto& line : lines) actorList.emplace_back(std::move(line)); @@ -82,7 +88,7 @@ void GameConfig::ConfigFunc_ObjectList(const tinyxml2::XMLElement& element) { std::string fileName = element.Attribute("File"); std::vector<std::string> lines = - File::ReadAllLines(Path::GetDirectoryName(configFilePath) + "/" + fileName); + File::ReadAllLines(Path::GetDirectoryName(configFilePath) / fileName); for (auto& line : lines) objectList.emplace_back(std::move(line)); @@ -91,7 +97,7 @@ void GameConfig::ConfigFunc_ObjectList(const tinyxml2::XMLElement& element) void GameConfig::ConfigFunc_TexturePool(const tinyxml2::XMLElement& element) { std::string fileName = element.Attribute("File"); - ReadTexturePool(Path::GetDirectoryName(configFilePath) + "/" + fileName); + ReadTexturePool(Path::GetDirectoryName(configFilePath) / fileName); } void GameConfig::ConfigFunc_BGConfig(const tinyxml2::XMLElement& element) @@ -100,15 +106,53 @@ void GameConfig::ConfigFunc_BGConfig(const tinyxml2::XMLElement& element) bgScreenHeight = element.IntAttribute("ScreenHeight", 240); } -void GameConfig::ReadConfigFile(const std::string& argConfigFilePath) +void GameConfig::ConfigFunc_ExternalXMLFolder(const tinyxml2::XMLElement& element) +{ + const char* pathValue = element.Attribute("Path"); + if (pathValue == nullptr) + { + throw std::runtime_error( + StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t Missing 'Path' attribute in `ExternalXMLFolder` element.\n")); + } + if (externalXmlFolder != "") + { + throw std::runtime_error(StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t `ExternalXMLFolder` is duplicated.\n")); + } + externalXmlFolder = pathValue; +} + +void GameConfig::ConfigFunc_ExternalFile(const tinyxml2::XMLElement& element) +{ + const char* xmlPathValue = element.Attribute("XmlPath"); + if (xmlPathValue == nullptr) + { + throw std::runtime_error( + StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t Missing 'XmlPath' attribute in `ExternalFile` element.\n")); + } + const char* outPathValue = element.Attribute("OutPath"); + if (outPathValue == nullptr) + { + throw std::runtime_error( + StringHelper::Sprintf("Parse: Fatal error in configuration file.\n" + "\t Missing 'OutPath' attribute in `ExternalFile` element.\n")); + } + + externalFiles.push_back(ExternalFile(fs::path(xmlPathValue), fs::path(outPathValue))); +} + +void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath) { static const std::map<std::string, ConfigFunc> ConfigFuncDictionary = { {"SymbolMap", &GameConfig::ConfigFunc_SymbolMap}, - {"Segment", &GameConfig::ConfigFunc_Segment}, {"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; diff --git a/ZAPD/GameConfig.h b/ZAPD/GameConfig.h index a9bbf72..c478d16 100644 --- a/ZAPD/GameConfig.h +++ b/ZAPD/GameConfig.h @@ -4,6 +4,7 @@ #include <map> #include <string> #include <vector> + #include "Utils/Directory.h" #include "tinyxml2.h" @@ -12,14 +13,21 @@ struct TexturePoolEntry fs::path path = ""; // Path to Shared Texture }; +class ExternalFile +{ +public: + fs::path xmlPath, outPath; + + ExternalFile(fs::path nXmlPath, fs::path nOutPath); +}; + class ZFile; class GameConfig { public: std::string configFilePath; - std::map<int32_t, std::string> segmentRefs; - std::map<int32_t, ZFile*> segmentRefFiles; + std::map<int32_t, std::vector<ZFile*>> segmentRefFiles; std::map<uint32_t, std::string> symbolMap; std::vector<std::string> actorList; std::vector<std::string> objectList; @@ -28,17 +36,23 @@ public: // ZBackground uint32_t bgScreenWidth = 320, bgScreenHeight = 240; + // ExternalFile + fs::path externalXmlFolder; + std::vector<ExternalFile> externalFiles; + GameConfig() = default; + ~GameConfig(); - void ReadTexturePool(const std::string& texturePoolXmlPath); - void GenSymbolMap(const std::string& symbolMapPath); + void ReadTexturePool(const fs::path& texturePoolXmlPath); + void GenSymbolMap(const fs::path& symbolMapPath); void ConfigFunc_SymbolMap(const tinyxml2::XMLElement& element); - void ConfigFunc_Segment(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 std::string& configFilePath); + void ReadConfigFile(const fs::path& configFilePath); }; diff --git a/ZAPD/Globals.cpp b/ZAPD/Globals.cpp index 893722b..51880b5 100644 --- a/ZAPD/Globals.cpp +++ b/ZAPD/Globals.cpp @@ -13,63 +13,24 @@ Globals::Globals() { Instance = this; - files = std::vector<ZFile*>(); - segments = std::vector<int32_t>(); game = ZGame::OOT_RETAIL; genSourceFile = true; testMode = false; profile = false; useLegacyZDList = false; useExternalResources = true; - lastScene = nullptr; verbosity = VerbosityLevel::VERBOSITY_SILENT; outputPath = Directory::GetCurrentDirectory(); } -std::string Globals::FindSymbolSegRef(int32_t segNumber, uint32_t symbolAddress) -{ - if (cfg.segmentRefs.find(segNumber) != cfg.segmentRefs.end()) - { - if (cfg.segmentRefFiles.find(segNumber) == cfg.segmentRefFiles.end()) - { - tinyxml2::XMLDocument doc; - std::string filePath = cfg.segmentRefs[segNumber]; - tinyxml2::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 (tinyxml2::XMLElement* child = root->FirstChildElement(); child != NULL; - child = child->NextSiblingElement()) - { - if (std::string_view(child->Name()) == "File") - { - ZFile* file = new ZFile(fileMode, child, "", "", filePath, true); - file->GeneratePlaceholderDeclarations(); - cfg.segmentRefFiles[segNumber] = file; - break; - } - } - } - - return cfg.segmentRefFiles[segNumber]->GetDeclarationName(symbolAddress, "ERROR"); - } - - return "ERROR"; -} - void Globals::AddSegment(int32_t segment, ZFile* file) { if (std::find(segments.begin(), segments.end(), segment) == segments.end()) segments.push_back(segment); + if (cfg.segmentRefFiles.find(segment) == cfg.segmentRefFiles.end()) + cfg.segmentRefFiles[segment] = std::vector<ZFile*>(); - cfg.segmentRefs[segment] = file->GetXmlFilePath().string(); - cfg.segmentRefFiles[segment] = file; + cfg.segmentRefFiles[segment].push_back(file); } bool Globals::HasSegment(int32_t segment) @@ -108,4 +69,127 @@ ExporterSet* Globals::GetExporterSet() 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} +{ +} diff --git a/ZAPD/Globals.h b/ZAPD/Globals.h index 0e6d344..e90efc2 100644 --- a/ZAPD/Globals.h +++ b/ZAPD/Globals.h @@ -59,17 +59,33 @@ public: bool forceStatic = false; std::vector<ZFile*> files; + std::vector<ZFile*> externalFiles; std::vector<int32_t> segments; - ZRoom* lastScene; + std::map<uint32_t, std::string> symbolMap; std::string currentExporter; static std::map<std::string, ExporterSet*>* GetExporterMap(); static void AddExporter(std::string exporterName, ExporterSet* exporterSet); Globals(); - std::string FindSymbolSegRef(int32_t segNumber, uint32_t symbolAddress); + 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/ZAPD/ImageBackend.cpp b/ZAPD/ImageBackend.cpp index a8fb900..137e326 100644 --- a/ZAPD/ImageBackend.cpp +++ b/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/ZAPD/Main.cpp b/ZAPD/Main.cpp index 9099cef..298ca02 100644 --- a/ZAPD/Main.cpp +++ b/ZAPD/Main.cpp @@ -25,7 +25,8 @@ 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); @@ -261,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; @@ -270,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) @@ -324,15 +317,17 @@ 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) { tinyxml2::XMLDocument doc; tinyxml2::XMLError eResult = doc.LoadFile(xmlFilePath.string().c_str()); @@ -356,39 +351,72 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, ZFileMode 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 + else if (std::string(child->Name()) == "ExternalFile") { - 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())); - } - } + 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())); + } - ExporterSet* exporterSet = Globals::Instance->GetExporterSet(); + fs::path externalXmlFilePath = + Globals::Instance->cfg.externalXmlFolder / fs::path(xmlPathValue); + fs::path externalOutFilePath = fs::path(outPathValue); - if (exporterSet != nullptr && exporterSet->beginXMLFunc != nullptr) - exporterSet->beginXMLFunc(); + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) + { + printf("Parsing external file: '%s'\n", externalXmlFilePath.c_str()); + } - for (ZFile* file : Globals::Instance->files) - { - if (fileMode == ZFileMode::BuildSourceFile) - file->BuildSourceFile(); + // Recursion. What can go wrong? + Parse(externalXmlFilePath, basePath, externalOutFilePath, ZFileMode::ExternalFile); + } else - file->ExtractResources(); + { + 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())); + } } - if (exporterSet != nullptr && exporterSet->endXMLFunc != nullptr) - exporterSet->endXMLFunc(); + if (fileMode != ZFileMode::ExternalFile) + { + ExporterSet* exporterSet = Globals::Instance->GetExporterSet(); + + if (exporterSet != nullptr && exporterSet->beginXMLFunc != nullptr) + exporterSet->beginXMLFunc(); - // All done, free files - for (ZFile* file : Globals::Instance->files) - delete file; + for (ZFile* file : Globals::Instance->files) + { + if (fileMode == ZFileMode::BuildSourceFile) + file->BuildSourceFile(); + else + file->ExtractResources(); + } - Globals::Instance->files.clear(); + if (exporterSet != nullptr && exporterSet->endXMLFunc != nullptr) + exporterSet->endXMLFunc(); + } return true; } diff --git a/ZAPD/OtherStructs/SkinLimbStructs.cpp b/ZAPD/OtherStructs/SkinLimbStructs.cpp new file mode 100644 index 0000000..9d16de4 --- /dev/null +++ b/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/ZAPD/OtherStructs/SkinLimbStructs.h b/ZAPD/OtherStructs/SkinLimbStructs.h new file mode 100644 index 0000000..33edd07 --- /dev/null +++ b/ZAPD/OtherStructs/SkinLimbStructs.h @@ -0,0 +1,113 @@ +#pragma once + +#include <cstdint> +#include <string> +#include <vector> + +#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<Struct_800A57C0> unk_8_arr; + std::vector<Struct_800A598C_2> unk_C_arr; +}; + +class Struct_800A5E28 : public ZResource +{ +public: + Struct_800A5E28(ZFile* nParent); + + void ParseRawData() override; + void DeclareReferences(const std::string& prefix) override; + + std::string GetBodySourceCode() const override; + + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; + + size_t GetRawDataSize() const override; + +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<Struct_800A598C> unk_4_arr; + // ZDisplayList* unk_8_dlist = nullptr; +}; diff --git a/ZAPD/ZAnimation.cpp b/ZAPD/ZAnimation.cpp index db72f2e..9242f65 100644 --- a/ZAPD/ZAnimation.cpp +++ b/ZAPD/ZAnimation.cpp @@ -25,74 +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(ZFile* nParent) : ZAnimation(nParent) -{ - rotationValues = std::vector<uint16_t>(); - rotationIndices = std::vector<RotationIndex>(); - limit = 0; -} +/* ZNormalAnimation */ -std::string ZNormalAnimation::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) +ZNormalAnimation::ZNormalAnimation(ZFile* nParent) : ZAnimation(nParent) { - 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); - Declaration* decl = parent->AddDeclaration( - rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), GetSourceTypeName(), - StringHelper::Sprintf("%s", name.c_str()), headerStr); - decl->staticConf = staticConf; - - 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(rotationValuesOffset, DeclarationAlignment::Align16, - rotationValues.size() * 2, "s16", - StringHelper::Sprintf("%sFrameData", defaultPrefix.c_str()), - rotationValues.size(), valuesStr); - - parent->AddDeclarationArray(rotationIndicesOffset, DeclarationAlignment::Align16, - rotationIndices.size() * 6, "JointIndex", - StringHelper::Sprintf("%sJointIndices", defaultPrefix.c_str()), - rotationIndices.size(), indicesStr); - } - - return ""; } size_t ZNormalAnimation::GetRawDataSize() const @@ -139,29 +80,69 @@ void ZNormalAnimation::ParseRawData() } } -ZLinkAnimation::ZLinkAnimation(ZFile* nParent) : ZAnimation(nParent) +void ZNormalAnimation::DeclareReferences(const std::string& prefix) { - segmentAddress = 0; -} + std::string defaultPrefix = prefix.c_str(); + if (name != "") + defaultPrefix = name; -std::string ZLinkAnimation::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) -{ - if (parent != nullptr) + // 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++) { - 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::Align4, GetRawDataSize(), - GetSourceTypeName(), StringHelper::Sprintf("%s", name.c_str()), - headerStr); + valuesStr += StringHelper::Sprintf("0x%04X, ", rotationValues[i]); + + if ((i - offset + 1) % lineLength == 0) + valuesStr += "\n "; } - return ""; + 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; } size_t ZLinkAnimation::GetRawDataSize() const @@ -178,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 */ @@ -376,82 +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) - { - decl = parent->AddDeclaration(address, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), name, bodyStr); - } - else - { - decl->text = bodyStr; - } - decl->staticConf = staticConf; - - return ""; + return DeclarationAlignment::Align16; } std::string ZCurveAnimation::GetSourceTypeName() const @@ -558,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()); @@ -568,21 +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) - decl = parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), name, body); - else - decl->text = body; - decl->staticConf = staticConf; - - return ""; -} - std::string ZLegacyAnimation::GetSourceTypeName() const { return "LegacyAnimationHeader"; diff --git a/ZAPD/ZAnimation.h b/ZAPD/ZAnimation.h index b59a342..e5b69d3 100644 --- a/ZAPD/ZAnimation.h +++ b/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,19 +34,21 @@ class ZNormalAnimation : public ZAnimation public: std::vector<uint16_t> rotationValues; std::vector<RotationIndex> rotationIndices; - segptr_t rotationValuesSeg; - segptr_t rotationIndicesSeg; - uint32_t rotationValuesOffset; - uint32_t rotationIndicesOffset; - 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; }; @@ -58,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; }; @@ -117,15 +118,17 @@ protected: std::vector<int16_t> copyValuesArr; public: - ZCurveAnimation(); ZCurveAnimation(ZFile* nParent); void ParseXML(tinyxml2::XMLElement* reader) override; void ParseRawData() override; void DeclareReferences(const std::string& prefix) override; + + std::string GetBodySourceCode() const override; + size_t GetRawDataSize() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + DeclarationAlignment GetDeclarationAlignment() const override; std::string GetSourceTypeName() const override; }; @@ -159,9 +162,8 @@ public: 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/ZAPD/ZArray.cpp b/ZAPD/ZArray.cpp index d7d546a..b1ba3a6 100644 --- a/ZAPD/ZArray.cpp +++ b/ZAPD/ZArray.cpp @@ -127,5 +127,9 @@ ZResourceType ZArray::GetResourceType() const DeclarationAlignment ZArray::GetDeclarationAlignment() const { + if (resList.size() == 0) + { + return DeclarationAlignment::Align4; + } return resList.at(0)->GetDeclarationAlignment(); } diff --git a/ZAPD/ZBackground.cpp b/ZAPD/ZBackground.cpp index 938f568..4125f23 100644 --- a/ZAPD/ZBackground.cpp +++ b/ZAPD/ZBackground.cpp @@ -11,6 +11,7 @@ REGISTER_ZFILENODE(Background, ZBackground); #define JPEG_MARKER 0xFFD8FFE0 #define MARKER_DQT 0xFFDB +#define MARKER_EOI 0xFFD9 ZBackground::ZBackground(ZFile* nParent) : ZResource(nParent) { @@ -27,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; @@ -117,16 +118,26 @@ size_t ZBackground::GetRawDataSize() const return Globals::Instance->cfg.bgScreenHeight * Globals::Instance->cfg.bgScreenWidth * 2; } -Declaration* ZBackground::DeclareVar(const std::string& prefix, const std::string& bodyStr) +Declaration* ZBackground::DeclareVar(const std::string& prefix, + [[maybe_unused]] const std::string& bodyStr) { std::string auxName = name; + std::string auxOutName = outName; - if (name == "") + if (auxName == "") auxName = GetDefaultName(prefix); - Declaration* decl = parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), - 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; } diff --git a/ZAPD/ZBlob.cpp b/ZAPD/ZBlob.cpp index 3839f83..40c534e 100644 --- a/ZAPD/ZBlob.cpp +++ b/ZAPD/ZBlob.cpp @@ -40,17 +40,21 @@ Declaration* ZBlob::DeclareVar(const std::string& prefix, [[maybe_unused]] const std::string& bodyStr) { std::string auxName = name; + std::string auxOutName = outName; - if (name == "") + if (auxName == "") auxName = GetDefaultName(prefix); - std::string path = Path::GetFileNameWithoutExtension(auxName); + 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", assetOutDir.c_str(), GetExternalExtension().c_str()); + StringHelper::Sprintf("%s.%s.inc.c", assetOutDir.c_str(), GetExternalExtension().c_str()); return parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), auxName, 0); diff --git a/ZAPD/ZCollision.cpp b/ZAPD/ZCollision.cpp index d96200e..758164e 100644 --- a/ZAPD/ZCollision.cpp +++ b/ZAPD/ZCollision.cpp @@ -126,8 +126,8 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) parent->AddDeclarationArray( polySegmentOffset, DeclarationAlignment::Align4, polygons.size() * 16, "CollisionPoly", - StringHelper::Sprintf("%s_polygons_%08X", auxName.c_str(), polySegmentOffset), 0, - declaration); + StringHelper::Sprintf("%s_polygons_%08X", auxName.c_str(), polySegmentOffset), + polygons.size(), declaration); } declaration.clear(); @@ -181,19 +181,24 @@ std::string ZCollisionHeader::GetBodySourceCode() const declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMinX, absMinY, absMinZ); declaration += StringHelper::Sprintf("\t{ %i, %i, %i },\n", absMaxX, absMaxY, absMaxZ); - std::string vtxName = parent->GetDeclarationPtrName(vtxAddress).c_str(); + std::string vtxName; + Globals::Instance->GetSegmentedPtrName(vtxAddress, parent, "Vec3s", vtxName); declaration += StringHelper::Sprintf("\t%i,\n\t%s,\n", numVerts, vtxName.c_str()); - std::string polyName = parent->GetDeclarationPtrName(polyAddress); + 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 = parent->GetDeclarationPtrName(polyTypeDefAddress); + std::string surfaceName; + Globals::Instance->GetSegmentedPtrName(polyTypeDefAddress, parent, "SurfaceType", surfaceName); declaration += StringHelper::Sprintf("\t%s,\n", surfaceName.c_str()); - std::string camName = parent->GetDeclarationPtrName(camDataAddress); + std::string camName; + Globals::Instance->GetSegmentedPtrName(camDataAddress, parent, "CamData", camName); declaration += StringHelper::Sprintf("\t%s,\n", camName.c_str()); - std::string waterBoxName = parent->GetDeclarationPtrName(waterBoxAddress); + 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; diff --git a/ZAPD/ZCutscene.cpp b/ZAPD/ZCutscene.cpp index f3621d0..2374810 100644 --- a/ZAPD/ZCutscene.cpp +++ b/ZAPD/ZCutscene.cpp @@ -1239,7 +1239,7 @@ Declaration* ZCutsceneBase::DeclareVar(const std::string& prefix, const std::str { std::string auxName = name; - if (name == "") + if (auxName == "") auxName = GetDefaultName(prefix); Declaration* decl = diff --git a/ZAPD/ZCutscene.h b/ZAPD/ZCutscene.h index 5424762..cbb6a78 100644 --- a/ZAPD/ZCutscene.h +++ b/ZAPD/ZCutscene.h @@ -427,6 +427,7 @@ public: void ParseRawData() override; std::string GetBodySourceCode() const override; + size_t GetRawDataSize() const override; ZResourceType GetResourceType() const override; diff --git a/ZAPD/ZCutsceneMM.cpp b/ZAPD/ZCutsceneMM.cpp index 657b39e..d0208bc 100644 --- a/ZAPD/ZCutsceneMM.cpp +++ b/ZAPD/ZCutsceneMM.cpp @@ -23,7 +23,7 @@ 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; diff --git a/ZAPD/ZCutsceneMM.h b/ZAPD/ZCutsceneMM.h index 0b8b13f..41b7de3 100644 --- a/ZAPD/ZCutsceneMM.h +++ b/ZAPD/ZCutsceneMM.h @@ -14,6 +14,7 @@ public: virtual ~ZCutsceneMM(); std::string GetBodySourceCode() const override; + size_t GetRawDataSize() const override; void ParseRawData() override; diff --git a/ZAPD/ZDisplayList.cpp b/ZAPD/ZDisplayList.cpp index bf5a895..f7be34a 100644 --- a/ZAPD/ZDisplayList.cpp +++ b/ZAPD/ZDisplayList.cpp @@ -17,8 +17,6 @@ REGISTER_ZFILENODE(DList, ZDisplayList); ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent) { - defines = ""; - sceneSegName = ""; lastTexWidth = 0; lastTexHeight = 0; lastTexAddr = 0; @@ -45,20 +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; } void ZDisplayList::ExtractFromBinary(uint32_t nRawDataIndex, int32_t rawDataSize) { rawDataIndex = nRawDataIndex; + name = GetDefaultName(parent->GetName()); numInstructions = rawDataSize / 8; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); } @@ -79,13 +87,18 @@ Declaration* ZDisplayList::DeclareVar([[maybe_unused]] const std::string& prefix const std::string& bodyStr) { Declaration* decl = - parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align8, GetRawDataSize(), + parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(), GetSourceTypeName(), name, numInstructions, bodyStr); decl->isExternal = true; decl->staticConf = staticConf; return decl; } +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) { @@ -430,7 +443,7 @@ int32_t ZDisplayList::GetDListLength(const std::vector<uint8_t>& 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" @@ -485,13 +498,8 @@ int32_t ZDisplayList::OptimizationChecks(int32_t startIndex, std::string& output } int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std::string& output, - const std::string& prefix) + [[maybe_unused]] const std::string& prefix) { - if (Globals::Instance->lastScene == nullptr) - { - return -1; - } - std::vector<F3DZEXOpcode> sequence = {F3DZEXOpcode::G_SETTIMG, F3DZEXOpcode::G_SETTILE, F3DZEXOpcode::G_RDPLOADSYNC, F3DZEXOpcode::G_LOADBLOCK, F3DZEXOpcode::G_RDPPIPESYNC, F3DZEXOpcode::G_SETTILE, @@ -525,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->cfg.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 @@ -649,7 +647,7 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, std lastTexSiz = (F3DZEXTexSizes)siz; lastTexLoaded = true; - TextureGenCheck(prefix); + TextureGenCheck(); return -1; } @@ -667,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(); } @@ -835,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 @@ -915,7 +912,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) printf("TextureGenCheck G_SETTIMG\n"); - TextureGenCheck(prefix); // HOTSPOT + TextureGenCheck(); // HOTSPOT lastTexFmt = (F3DZEXTexFormats)fmt; lastTexSiz = (F3DZEXTexSizes)siz; @@ -952,8 +949,10 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch } else { - sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %sTex_%06lX),", fmtTbl[fmt], sizTbl[siz], - 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()); } } @@ -990,7 +989,8 @@ void ZDisplayList::Opcode_G_SETTILE(uint64_t data, char* line) sizTbl[ii], nnnnnnnnn, mmmmmmmmm, ttt, pppp, cc, aaaa, ssss, dd, bbbb, uuuu); } -void ZDisplayList::Opcode_G_SETTILESIZE(uint64_t data, const 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, const std::string& prefix 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); } @@ -1492,7 +1492,8 @@ void ZDisplayList::Opcode_G_SETOTHERMODE_H(uint64_t data, char* line) sprintf(line, "gsSPSetOtherMode(0xE3, %i, %i, 0x%08X),", sft, nn + 1, dd); } -void ZDisplayList::Opcode_G_LOADTLUT(uint64_t data, const 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; @@ -1506,19 +1507,19 @@ void ZDisplayList::Opcode_G_LOADTLUT(uint64_t data, const std::string& prefix, c 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(const 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) @@ -1581,24 +1582,17 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count) { ZDisplayList* self = static_cast<ZDisplayList*>(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))) - { - vtxName = StringHelper::Sprintf("0x%08X", seg); - } - else + if (GETSEGNUM(seg) == self->parent->segment) { - 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; @@ -1606,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; @@ -1634,11 +1627,10 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count) } self->vertices[vtxOffset] = vtxList; } - - vtxName = "@r"; } - gfxd_puts(vtxName.c_str()); + self->references.push_back(seg); + gfxd_puts("@r"); return 1; } @@ -1648,7 +1640,6 @@ static int32_t GfxdCallback_Texture(segptr_t seg, int32_t fmt, int32_t siz, int3 { ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get()); uint32_t texOffset = Seg2Filespace(seg, self->parent->baseAddress); - uint32_t texSegNum = GETSEGNUM(seg); self->lastTexWidth = width; self->lastTexHeight = height; @@ -1659,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->cfg.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); + Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", texName); gfxd_puts(texName.c_str()); @@ -1684,7 +1664,6 @@ static int32_t GfxdCallback_Palette(uint32_t seg, [[maybe_unused]] int32_t idx, { ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get()); uint32_t palOffset = Seg2Filespace(seg, self->parent->baseAddress); - uint32_t palSegNum = GETSEGNUM(seg); self->lastTexWidth = sqrt(count); self->lastTexHeight = sqrt(count); @@ -1695,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->cfg.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); + Globals::Instance->GetSegmentedPtrName(seg, self->parent, "", palName); gfxd_puts(palName.c_str()); @@ -1722,7 +1690,10 @@ 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(self->parent); newDList->ExtractFromBinary( @@ -1730,14 +1701,9 @@ static int32_t GfxdCallback_DisplayList(uint32_t seg) 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->cfg.segmentRefFiles.at(dListSegNum); - - std::string dListName = auxParent->GetDeclarationPtrName(seg); - gfxd_puts(dListName.c_str()); return 1; @@ -1748,9 +1714,8 @@ static int32_t GfxdCallback_Matrix(uint32_t seg) std::string mtxName; ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get()); - if (Globals::Instance->cfg.symbolMap.find(seg) != Globals::Instance->cfg.symbolMap.end()) - mtxName = StringHelper::Sprintf("&%s", Globals::Instance->cfg.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)); @@ -1765,13 +1730,7 @@ static int32_t GfxdCallback_Matrix(uint32_t seg) self->mtxList.push_back(mtx); mtxName = "&" + mtx.GetName(); } - else - { - mtxName = "&" + decl->varName; - } } - else - mtxName = StringHelper::Sprintf("0x%08X", seg); gfxd_puts(mtxName.c_str()); @@ -1813,38 +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; + 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()); } - vtxDeclarations[item.first] = declaration; - - parent->AddDeclarationArray( - item.first, DeclarationAlignment::Align16, item.second.size() * 16, "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) @@ -1873,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<int32_t> vtxKeys; @@ -1893,10 +1840,7 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) for (auto& vtx : item) { - if (curAddr != vtxKeys[i]) - declaration += "\n"; - - declaration += StringHelper::Sprintf("\t%s,", vtx.GetBodySourceCode().c_str()); + declaration += StringHelper::Sprintf("\t%s,\n", vtx.GetBodySourceCode().c_str()); curAddr += 16; } @@ -1906,8 +1850,6 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) // that warning when building the OoT repo. declaration += "\n"; - vtxDeclarations[vtxKeys[i]] = declaration; - if (parent != nullptr) { std::string vtxName; @@ -1921,10 +1863,6 @@ 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::Align16, - item.size() * 16, "Vtx", vtxName, item.size(), - declaration); - Declaration* vtxDecl = parent->AddDeclarationIncludeArray( vtxKeys[i], incStr, item.size() * 16, "Vtx", vtxName, item.size()); vtxDecl->isExternal = true; @@ -1981,7 +1919,7 @@ 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; @@ -2008,7 +1946,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 @@ -2016,10 +1953,10 @@ std::string ZDisplayList::ProcessGfxDis(const std::string& prefix) return sourceOutput; } -void ZDisplayList::TextureGenCheck(const 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; @@ -2027,12 +1964,11 @@ void ZDisplayList::TextureGenCheck(const std::string& prefix) } } -bool ZDisplayList::TextureGenCheck(ZFile* parent, [[maybe_unused]] const 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; @@ -2046,58 +1982,53 @@ bool ZDisplayList::TextureGenCheck(ZFile* parent, [[maybe_unused]] const std::st 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) + { + auxParent = self->parent; + } + else { - if (texAddr < parent->GetRawData().size()) + // 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->ExtractFromBinary(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) + { + // We can't declare the texture in any of the files we are extracting. + return false; + } + + if (auxParent->IsOffsetInFileRange(texAddr)) { - if (Globals::Instance->lastScene->parent->GetDeclaration(texAddr) == nullptr) + 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->ExtractFromBinary(texAddr, texWidth, texHeight, - TexFormatToTexType(texFmt, texSiz), texIsPalette); + tex = new ZTexture(auxParent); + tex->ExtractFromBinary(texAddr, texWidth, texHeight, + TexFormatToTexType(texFmt, texSiz), texIsPalette); + auxParent->AddTextureResource(texAddr, tex); + } - Globals::Instance->lastScene->parent->AddTextureResource(texAddr, tex); - } + if (!texIsPalette) + self->lastTexture = tex; + else + self->lastTlut = 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(), tex->GetRawDataSize() / 8); + if (auxParent->GetDeclaration(texAddr) == nullptr) + { + tex->DeclareVar(self->GetName(), ""); } + return true; } } @@ -2172,3 +2103,8 @@ size_t ZDisplayList::GetRawDataSize() const { return instructions.size() * 8; } + +DeclarationAlignment ZDisplayList::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align8; +} diff --git a/ZAPD/ZDisplayList.h b/ZAPD/ZDisplayList.h index c564a04..d538666 100644 --- a/ZAPD/ZDisplayList.h +++ b/ZAPD/ZDisplayList.h @@ -324,9 +324,7 @@ protected: void Opcode_G_ENDDL(const std::string& prefix, char* line); public: - std::string sceneSegName; std::vector<uint64_t> instructions; - std::string curPrefix; int32_t lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg; F3DZEXTexFormats lastTexFmt; @@ -337,15 +335,12 @@ public: DListType dListType; std::map<uint32_t, std::vector<ZVtx>> vertices; - std::map<uint32_t, std::string> vtxDeclarations; std::vector<ZDisplayList*> otherDLists; ZTexture* lastTexture = nullptr; ZTexture* lastTlut = nullptr; - std::vector<uint32_t> references; - - std::string defines; // Hack for special cases where vertex arrays intersect... + std::vector<segptr_t> references; std::vector<ZMtx> mtxList; ZDisplayList(ZFile* nParent); @@ -357,16 +352,17 @@ public: void ParseRawData() override; Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; + std::string GetDefaultName(const std::string& prefix) const override; - void TextureGenCheck(const std::string& prefix); - static bool TextureGenCheck(ZFile* parent, const 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<uint8_t>& 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/ZAPD/ZFile.cpp b/ZAPD/ZFile.cpp index 2245168..e4bd771 100644 --- a/ZAPD/ZFile.cpp +++ b/ZAPD/ZFile.cpp @@ -40,13 +40,15 @@ ZFile::ZFile() rangeEnd = 0xFFFFFFFF; } -ZFile::ZFile(const 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, - const 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; @@ -55,8 +57,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() @@ -70,11 +80,17 @@ ZFile::~ZFile() { delete d.second; } + + for (auto sym : symbolResources) + { + delete sym.second; + } } -void ZFile::ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, const 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 @@ -113,14 +129,12 @@ void ZFile::ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, const std::st if (rangeStart > rangeEnd) throw std::runtime_error("Error: RangeStart must be before than RangeEnd."); - // 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())); - */ + // Not every XML may have a segment number, so this doesn't make much sense 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 (reader->Attribute("Segment") != nullptr) { @@ -128,13 +142,21 @@ void ZFile::ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, const std::st Globals::Instance->AddSegment(segment, this); } - 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<std::string> nameSet; @@ -151,9 +173,6 @@ void ZFile::ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, const std::st 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) { @@ -176,6 +195,10 @@ void ZFile::ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, const std::st 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()) @@ -203,14 +226,23 @@ void ZFile::ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, const std::st { 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<ZTexture*>(nRes)); - else - resources.push_back(nRes); + break; + + case ZResourceType::Symbol: + AddSymbolResource(rawDataIndex, static_cast<ZSymbol*>(nRes)); + break; + + default: + AddResource(nRes); + break; + } rawDataIndex += nRes->GetRawDataSize(); } @@ -240,21 +272,13 @@ void ZFile::DeclareResourceSubReferences() void ZFile::BuildSourceFile() { - if (!Directory::Exists(Globals::Instance->outputPath)) - Directory::CreateDirectory(Globals::Instance->outputPath.string()); - - GenerateSourceFiles(Globals::Instance->outputPath); -} + if (mode == ZFileMode::ExternalFile) + return; -std::string ZFile::GetVarName(uint32_t address) -{ - for (std::pair<uint32_t, Declaration*> pair : declarations) - { - if (pair.first == address) - return pair.second->varName; - } + if (!Directory::Exists(outputPath)) + Directory::CreateDirectory(outputPath); - return ""; + GenerateSourceFiles(); } std::string ZFile::GetName() const @@ -262,6 +286,11 @@ std::string ZFile::GetName() const return name; } +ZFileMode ZFile::GetMode() const +{ + return mode; +} + const fs::path& ZFile::GetXmlFilePath() const { return xmlFilePath; @@ -274,11 +303,14 @@ const std::vector<uint8_t>& 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(); @@ -286,7 +318,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); @@ -301,12 +333,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); } @@ -358,13 +388,14 @@ Declaration* ZFile::AddDeclaration(offset_t address, DeclarationAlignment alignm 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 = GetDeclaration(address); if (decl == nullptr) { - decl = new Declaration(alignment, size, varType, varName, false, body); + decl = new Declaration(address, alignment, size, varType, varName, false, body); declarations[address] = decl; } else @@ -383,13 +414,15 @@ Declaration* ZFile::AddDeclarationArray(offset_t address, DeclarationAlignment a const std::string& varName, size_t arrayItemCnt, const 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, size, varType, varName, true, arrayItemCnt, body); + decl = + new Declaration(address, alignment, size, varType, varName, true, arrayItemCnt, body); declarations[address] = decl; } else @@ -401,8 +434,7 @@ Declaration* ZFile::AddDeclarationArray(offset_t address, DeclarationAlignment a decl->varType = varType; decl->isArray = true; decl->arrayItemCnt = arrayItemCnt; - if (body != "" && decl->text == "") - decl->text = body; + decl->text = body; } return decl; @@ -413,13 +445,15 @@ Declaration* ZFile::AddDeclarationArray(offset_t address, DeclarationAlignment a const std::string& varName, const std::string& arrayItemCntStr, const 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, size, varType, varName, true, arrayItemCntStr, body); + decl = new Declaration(address, alignment, size, varType, varName, true, arrayItemCntStr, + body); declarations[address] = decl; } else @@ -435,33 +469,16 @@ Declaration* ZFile::AddDeclarationArray(offset_t address, DeclarationAlignment a return decl; } -Declaration* ZFile::AddDeclarationPlaceholder(uint32_t address) -{ - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); - Declaration* decl; - - if (declarations.find(address) == declarations.end()) - { - decl = new Declaration(DeclarationAlignment::Align4, 0, "", "", false, ""); - decl->isPlaceholder = true; - declarations[address] = decl; - } - else - decl = declarations[address]; - - return decl; -} - Declaration* ZFile::AddDeclarationPlaceholder(offset_t address, const std::string& varName) { - assert(GETSEGNUM(address) == 0); - AddDeclarationDebugChecks(address); - Declaration* decl; + bool validOffset = AddDeclarationChecks(address, varName); + if (!validOffset) + return nullptr; + Declaration* decl; if (declarations.find(address) == declarations.end()) { - decl = new Declaration(DeclarationAlignment::Align4, 0, "", varName, false, ""); + decl = new Declaration(address, DeclarationAlignment::Align4, 0, "", varName, false, ""); decl->isPlaceholder = true; declarations[address] = decl; } @@ -475,13 +492,14 @@ Declaration* ZFile::AddDeclarationInclude(offset_t address, const std::string& i size_t size, const std::string& varType, const std::string& varName) { - 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(includePath, size, varType, varName); + decl = new Declaration(address, includePath, size, varType, varName); declarations[address] = decl; } else @@ -498,8 +516,9 @@ Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& in size_t size, const std::string& varType, const 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]; @@ -509,7 +528,7 @@ Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& in Declaration* decl = GetDeclaration(address); if (decl == nullptr) { - decl = new Declaration(includePath, size, varType, varName); + decl = new Declaration(address, includePath, size, varType, varName); decl->isArray = true; decl->arrayItemCnt = arrayItemCnt; @@ -528,47 +547,106 @@ Declaration* ZFile::AddDeclarationIncludeArray(offset_t address, std::string& in 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) { [[maybe_unused]] int32_t bp = 0; } #endif -} -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 + 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 std::string& defaultResult) const +bool ZFile::GetDeclarationPtrName(segptr_t segAddress, const std::string& expectedType, + std::string& declName) const { - Declaration* decl = GetDeclaration(address); - if (decl != nullptr) - return decl->varName; + if (segAddress == 0) + { + declName = "NULL"; + return true; + } + + uint32_t offset = Seg2Filespace(segAddress, baseAddress); + Declaration* decl = GetDeclaration(offset); + if (GETSEGNUM(segAddress) != segment || decl == nullptr) + { + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; + } - return defaultResult; + if (expectedType != "" && expectedType != "void*") + { + if (expectedType != decl->varType && "static " + expectedType != decl->varType) + { + declName = StringHelper::Sprintf("0x%08X", segAddress); + return false; + } + } + + if (!decl->isArray) + declName = "&" + decl->varName; + else + declName = decl->varName; + return true; } -std::string ZFile::GetDeclarationPtrName(segptr_t segAddress) const +bool ZFile::GetDeclarationArrayIndexedName(segptr_t segAddress, size_t elementSize, + 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 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 (!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; + 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; + } - return decl->varName; + 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 @@ -590,24 +668,13 @@ 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; @@ -616,60 +683,34 @@ void ZFile::GenerateSourceFiles(fs::path outputDir) sourceOutput += "#include \"macros.h\"\n"; sourceOutput += GetHeaderInclude(); - GeneratePlaceholderDeclarations(); - - // Generate Code - for (size_t i = 0; i < resources.size(); i++) + bool hasZRoom = false; + for (const auto& res : resources) { - ZResource* res = resources.at(i); - std::string resSrc = res->GetSourceOutputCode(name); - - if (res->IsExternalResource()) + ZResourceType resType = res->GetResourceType(); + if (resType == ZResourceType::Room || resType == ZResourceType::Scene || + resType == ZResourceType::AltHeader) { - 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<ZTexture*>(res); + hasZRoom = true; + break; + } + } - if (!Globals::Instance->cfg.texturePool.empty()) - { - tex->CalcHash(); + if (hasZRoom) + { + sourceOutput += GetZRoomHeaderInclude(); + } - // 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"; - } - } + sourceOutput += GetExternalFileHeaderInclude(); - incStr += ".c"; - } - else if (res->GetResourceType() == ZResourceType::Blob || - res->GetResourceType() == ZResourceType::Background) - { - incStr += ".c"; - } + sourceOutput += "\n"; - AddDeclarationIncludeArray(res->GetRawDataIndex(), incStr, res->GetRawDataSize(), - declType, res->GetName(), 0); - } - else - { - sourceOutput += resSrc; - } + GeneratePlaceholderDeclarations(); - if (resSrc != "" && !res->IsExternalResource()) - sourceOutput += "\n"; + // Generate Code + for (size_t i = 0; i < resources.size(); i++) + { + ZResource* res = resources.at(i); + res->GetSourceOutputCode(name); } sourceOutput += ProcessDeclarations(); @@ -700,6 +741,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"); @@ -710,10 +756,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() @@ -752,9 +836,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<std::string, ZResourceFactoryFunc*>* ZFile::GetNodeMap() @@ -780,7 +907,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); @@ -798,21 +924,24 @@ 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); + i--; + continue; + } } } } @@ -833,26 +962,13 @@ 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) { @@ -861,7 +977,6 @@ std::string ZFile::ProcessDeclarations() while (curPtr % 4 != 0) { declarations[lastAddr]->size++; - // item.second->size++; curPtr++; } @@ -873,7 +988,6 @@ std::string ZFile::ProcessDeclarations() item.second->preText = buffer + item.second->preText; declarations[lastAddr]->size += 4; - // item.second->size += 4; curPtr += 4; } } @@ -882,132 +996,7 @@ std::string ZFile::ProcessDeclarations() lastAddr = item.first; } - // Handle unaccounted data - lastAddr = 0; - lastSize = 0; - std::vector<uint32_t> 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()); - } - } - - size_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::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 address '0x%06zX'.\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%06zX'.\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) @@ -1019,9 +1008,9 @@ std::string ZFile::ProcessDeclarations() output += "\n"; // Next, output the actual declarations - for (std::pair<uint32_t, Declaration*> item : declarations) + for (const auto& item : declarations) { - if (item.first < rangeStart || item.first >= rangeEnd) + if (!IsOffsetInFileRange(item.first)) continue; if (item.second->includePath != "") @@ -1033,10 +1022,10 @@ std::string ZFile::ProcessDeclarations() 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); @@ -1059,51 +1048,25 @@ void ZFile::ProcessDeclarationText(Declaration* decl) { size_t refIndex = 0; - if (decl->references.size() > 0) - { - for (size_t i = 0; i < decl->text.size() - 1; i++) - { - char c = decl->text[i]; - char c2 = decl->text[i + 1]; + if (!(decl->references.size() > 0)) + return; - if (c == '@' && c2 == 'r') - { - if (refIndex >= decl->references.size()) - break; - - Declaration* refDecl = GetDeclarationRanged(decl->references[refIndex]); - uint32_t refDeclAddr = GetDeclarationRangedAddress(decl->references[refIndex]); + for (size_t i = 0; i < decl->text.size() - 1; i++) + { + char c = decl->text[i]; + char c2 = decl->text[i + 1]; - 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; + if (c == '@' && c2 == 'r') + { + std::string vtxName; + Globals::Instance->GetSegmentedArrayIndexedName(decl->references[refIndex], 0x10, this, + "Vtx", vtxName); + decl->text.replace(i, 2, vtxName); - 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++; - refIndex++; - } + if (refIndex >= decl->references.size()) + break; } } } @@ -1112,9 +1075,9 @@ std::string ZFile::ProcessExterns() { std::string output; - for (std::pair<uint32_t, Declaration*> item : declarations) + for (const auto& item : declarations) { - if (item.first < rangeStart || item.first >= rangeEnd) + if (!IsOffsetInFileRange(item.first)) { continue; } @@ -1162,8 +1125,9 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] const std::strin } else { - std::string texName = GetDeclarationPtrName(currentOffset); + std::string texName; std::string texNextName; + GetDeclarationPtrName(currentOffset, "", texName); Declaration* nextDecl = GetDeclaration(nextOffset); if (nextDecl == nullptr) @@ -1174,6 +1138,7 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] const std::strin 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); @@ -1185,3 +1150,155 @@ std::string ZFile::ProcessTextureIntersections([[maybe_unused]] const std::strin return defines; } + +void ZFile::HandleUnaccountedData() +{ + uint32_t lastAddr = 0; + uint32_t lastSize = 0; + std::vector<uint32_t> 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/ZAPD/ZFile.h b/ZAPD/ZFile.h index 2d7e1f3..00ae5e0 100644 --- a/ZAPD/ZFile.h +++ b/ZAPD/ZFile.h @@ -3,6 +3,8 @@ #include <Utils/Directory.h> #include <string> #include <vector> + +#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,20 @@ enum class ZGame class ZFile { public: - std::map<uint32_t, Declaration*> declarations; + std::map<offset_t, Declaration*> declarations; std::string defines; std::vector<ZResource*> resources; uint32_t segment; uint32_t baseAddress, rangeStart, rangeEnd; + bool isExternalFile = false; - ZFile(const std::string& nName); - ZFile(ZFileMode mode, tinyxml2::XMLElement* reader, const fs::path& nBasePath, - const std::string& filename, const fs::path& nXmlFilePath, bool placeholderMode); + 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<uint8_t>& GetRawData() const; void ExtractResources(); @@ -52,35 +56,50 @@ public: 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(uint32_t address); + 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, const 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<std::string, ZResourceFactoryFunc*>* GetNodeMap(); static void RegisterNode(std::string nodeName, ZResourceFactoryFunc* nodeFunc); @@ -89,23 +108,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<uint32_t, ZTexture*> texturesResources; + std::map<uint32_t, ZSymbol*> symbolResources; + ZFileMode mode = ZFileMode::Invalid; ZFile(); - void ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, const 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(const std::string& prefix); + void HandleUnaccountedData(); + bool HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, uint32_t& lastSize); }; diff --git a/ZAPD/ZLimb.cpp b/ZAPD/ZLimb.cpp index 837160e..77c6687 100644 --- a/ZAPD/ZLimb.cpp +++ b/ZAPD/ZLimb.cpp @@ -8,351 +8,8 @@ REGISTER_ZFILENODE(Limb, ZLimb); -Struct_800A57C0::Struct_800A57C0(const std::vector<uint8_t>& 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<uint8_t>& 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<uint8_t>& 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<uint8_t>& 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<uint8_t>& 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<uint8_t>& 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::Align4, - 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::Align4, - 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<uint8_t>& 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::Align4, - 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(parent); - unk_8_dlist->ExtractFromBinary(unk_8_Offset, dlistLength); - - 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"); } @@ -362,6 +19,10 @@ void ZLimb::ExtractFromBinary(uint32_t nRawDataIndex, ZLimbType nType) rawDataIndex = nRawDataIndex; type = nType; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); } @@ -376,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); @@ -446,12 +99,16 @@ void ZLimb::ParseRawData() skinSegmentType = static_cast<ZLimbSkinType>(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; @@ -460,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: @@ -472,8 +134,8 @@ void ZLimb::DeclareReferences(const std::string& prefix) { ZLimb* child = new ZLimb(parent); child->ExtractFromBinary(childOffset, ZLimbType::Legacy); - child->DeclareVar(prefix, ""); - child->DeclareReferences(prefix); + child->DeclareVar(varPrefix, ""); + child->DeclareReferences(varPrefix); parent->AddResource(child); } } @@ -484,18 +146,45 @@ void ZLimb::DeclareReferences(const std::string& prefix) { ZLimb* sibling = new ZLimb(parent); sibling->ExtractFromBinary(siblingdOffset, ZLimbType::Legacy); - sibling->DeclareVar(prefix, ""); - sibling->DeclareReferences(prefix); + sibling->DeclareVar(varPrefix, ""); + sibling->DeclareReferences(varPrefix); parent->AddResource(sibling); } } break; - // TODO - case ZLimbType::Standard: + 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: - case ZLimbType::Curve: + 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: @@ -527,14 +216,18 @@ size_t ZLimb::GetRawDataSize() const std::string ZLimb::GetBodySourceCode() const { - std::string dListStr = parent->GetDeclarationPtrName(dListPtr); - std::string dListStr2 = parent->GetDeclarationPtrName(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 += @@ -565,7 +258,8 @@ std::string ZLimb::GetBodySourceCode() const case ZLimbType::Skin: { - std::string skinSegmentStr = parent->GetDeclarationPtrName(skinSegment); + std::string skinSegmentStr; + Globals::Instance->GetSegmentedPtrName(skinSegment, parent, "", skinSegmentStr); entryStr += StringHelper::Sprintf("\t0x%02X, %s\n", skinSegmentType, skinSegmentStr.c_str()); } @@ -656,122 +350,34 @@ ZLimbType ZLimb::GetTypeByAttributeName(const std::string& attrName) return ZLimbType::Invalid; } -// 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) +void ZLimb::DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix, + const std::string& limbSuffix) { - if (dListPtr == 0) - return "NULL"; - - uint32_t dListOffset = Seg2Filespace(dListPtr, parent->baseAddress); - - // Check if pointing past the object's size - if (dListOffset > parent->GetRawData().size()) - return StringHelper::Sprintf("0x%08X", dListPtr); + if (dListSegmentedPtr == 0 || GETSEGNUM(dListSegmentedPtr) != parent->segment) + return; - // Check if it is already declared - Declaration* decl = parent->GetDeclaration(dListOffset); - if (decl != nullptr) - return decl->varName; + uint32_t dlistOffset = Seg2Filespace(dListSegmentedPtr, parent->baseAddress); + if (parent->HasDeclaration(dlistOffset)) + return; - // 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); - } - } - } + if (!parent->IsOffsetInFileRange(dlistOffset) || dlistOffset >= parent->GetRawData().size()) + return; - // 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(parent); - dList->ExtractFromBinary(dListOffset, dlistLength); - 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); + ZDisplayList* dlist = new ZDisplayList(parent); + dlist->ExtractFromBinary(dlistOffset, dlistLength); - 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::Align4, - 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<int32_t>(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<int32_t>(skinSegmentType)); - skinSegmentStr = StringHelper::Sprintf("0x%08X", skinSegment); - break; - } - } - - std::string entryStr = - StringHelper::Sprintf(" 0x%02X, %s\n", skinSegmentType, skinSegmentStr.c_str()); - - return entryStr; + 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/ZAPD/ZLimb.h b/ZAPD/ZLimb.h index cd89c19..53a4143 100644 --- a/ZAPD/ZLimb.h +++ b/ZAPD/ZLimb.h @@ -3,6 +3,8 @@ #include <cstdint> #include <string> #include <vector> + +#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<uint8_t>& rawData, uint32_t fileOffset); - Struct_800A57C0(const std::vector<uint8_t>& 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<uint8_t>& rawData, uint32_t fileOffset); - Struct_800A598C_2(const std::vector<uint8_t>& 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<Struct_800A57C0> unk_8_arr; - std::vector<Struct_800A598C_2> unk_C_arr; - -public: - Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset); - Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& 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<Struct_800A598C> unk_4_arr; - ZDisplayList* unk_8_dlist = nullptr; - -public: - Struct_800A5E28() = default; - Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset); - Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& 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,15 +33,9 @@ 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; @@ -165,4 +58,8 @@ public: void SetLimbType(ZLimbType value); static const char* GetSourceTypeName(ZLimbType limbType); static ZLimbType GetTypeByAttributeName(const std::string& attrName); + +protected: + void DeclareDList(segptr_t dListSegmentedPtr, const std::string& prefix, + const std::string& limbSuffix); }; diff --git a/ZAPD/ZPath.cpp b/ZAPD/ZPath.cpp index d834076..4a95c5b 100644 --- a/ZAPD/ZPath.cpp +++ b/ZAPD/ZPath.cpp @@ -139,6 +139,10 @@ void PathwayEntry::DeclareReferences(const std::string& prefix) return; std::string pointsName; + bool addressFound = + Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", pointsName); + if (addressFound) + return; std::string declaration; @@ -154,16 +158,23 @@ void PathwayEntry::DeclareReferences(const std::string& prefix) } uint32_t pointsOffset = Seg2Filespace(listSegmentAddress, parent->baseAddress); - 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); + Declaration* decl = parent->GetDeclaration(pointsOffset); + if (decl == nullptr) + { + pointsName = StringHelper::Sprintf("%sPathwayList_%06X", prefix.c_str(), pointsOffset); + parent->AddDeclarationArray(pointsOffset, points.at(0).GetDeclarationAlignment(), + points.size() * 6, points.at(0).GetSourceTypeName(), pointsName, + points.size(), declaration); + } + else + decl->text = declaration; } std::string PathwayEntry::GetBodySourceCode() const { std::string declaration; - std::string listName = parent->GetDeclarationPtrName(listSegmentAddress); + std::string listName; + Globals::Instance->GetSegmentedPtrName(listSegmentAddress, parent, "Vec3s", listName); if (Globals::Instance->game == ZGame::MM_RETAIL) declaration += diff --git a/ZAPD/ZResource.cpp b/ZAPD/ZResource.cpp index c17f89a..1e772ae 100644 --- a/ZAPD/ZResource.cpp +++ b/ZAPD/ZResource.cpp @@ -31,14 +31,20 @@ void ZResource::ExtractFromXML(tinyxml2::XMLElement* reader, offset_t nRawDataIn 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(), ""); - assert(decl != nullptr); - decl->declaredInXml = true; + if (decl != nullptr) + { + decl->declaredInXml = true; + } } } @@ -46,6 +52,10 @@ void ZResource::ExtractFromFile(offset_t nRawDataIndex) { rawDataIndex = nRawDataIndex; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); CalcHash(); } diff --git a/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp b/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp index c6bc136..ba31bc7 100644 --- a/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp +++ b/ZAPD/ZRoom/Commands/SetActorCutsceneList.cpp @@ -45,7 +45,7 @@ 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); } @@ -53,7 +53,8 @@ void SetActorCutsceneList::DeclareReferences(const std::string& prefix) 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/ZAPD/ZRoom/Commands/SetActorList.cpp b/ZAPD/ZRoom/Commands/SetActorList.cpp index 3239cdc..919d86f 100644 --- a/ZAPD/ZRoom/Commands/SetActorList.cpp +++ b/ZAPD/ZRoom/Commands/SetActorList.cpp @@ -80,7 +80,8 @@ void SetActorList::DeclareReferencesLate(const std::string& prefix) 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, diff --git a/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp b/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp index 2f16eac..016df12 100644 --- a/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp +++ b/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() @@ -42,23 +47,26 @@ void SetAlternateHeaders::DeclareReferencesLate(const std::string& prefix) 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, 0, 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/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp b/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp index 4d588c0..0b9a67e 100644 --- a/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp +++ b/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.cpp @@ -32,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/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h b/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h index 0f6cff3..3dbbf96 100644 --- a/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h +++ b/ZAPD/ZRoom/Commands/SetAnimatedMaterialList.h @@ -1,7 +1,5 @@ #pragma once -#include <memory> - #include "ZRoom/ZRoomCommand.h" #include "ZTextureAnimation.h" diff --git a/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp b/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp index 96196a5..03aaa4b 100644 --- a/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp +++ b/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,20 +13,23 @@ SetCollisionHeader::SetCollisionHeader(ZFile* nParent) : ZRoomCommand(nParent) void SetCollisionHeader::ParseRawData() { ZRoomCommand::ParseRawData(); + collisionHeader = new ZCollisionHeader(parent); collisionHeader->SetName( StringHelper::Sprintf("%sCollisionHeader_%06X", parent->GetName().c_str(), segmentOffset)); collisionHeader->ExtractFromFile(segmentOffset); + parent->AddResource(collisionHeader); } -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/ZAPD/ZRoom/Commands/SetCollisionHeader.h b/ZAPD/ZRoom/Commands/SetCollisionHeader.h index b0a599f..f7d5ecf 100644 --- a/ZAPD/ZRoom/Commands/SetCollisionHeader.h +++ b/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/ZAPD/ZRoom/Commands/SetCsCamera.cpp b/ZAPD/ZRoom/Commands/SetCsCamera.cpp index 31bb6cf..5cf0a3d 100644 --- a/ZAPD/ZRoom/Commands/SetCsCamera.cpp +++ b/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" @@ -39,9 +40,6 @@ void SetCsCamera::ParseRawData() points.push_back(vec); } } - - if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); } void SetCsCamera::DeclareReferences(const std::string& prefix) @@ -52,9 +50,7 @@ void SetCsCamera::DeclareReferences(const std::string& prefix) 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"; @@ -73,7 +69,9 @@ void SetCsCamera::DeclareReferences(const std::string& prefix) if (!cameras.empty()) { - std::string camPointsName = parent->GetDeclarationName(cameras.at(0).GetSegmentOffset()); + std::string camPointsName; + Globals::Instance->GetSegmentedPtrName(cameras.at(0).GetCamAddress(), parent, "Vec3s", + camPointsName); std::string declaration; size_t index = 0; @@ -104,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/ZAPD/ZRoom/Commands/SetCutscenes.cpp b/ZAPD/ZRoom/Commands/SetCutscenes.cpp index 785a938..e51e550 100644 --- a/ZAPD/ZRoom/Commands/SetCutscenes.cpp +++ b/ZAPD/ZRoom/Commands/SetCutscenes.cpp @@ -85,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/ZAPD/ZRoom/Commands/SetEntranceList.cpp b/ZAPD/ZRoom/Commands/SetEntranceList.cpp index 468dc50..8099bac 100644 --- a/ZAPD/ZRoom/Commands/SetEntranceList.cpp +++ b/ZAPD/ZRoom/Commands/SetEntranceList.cpp @@ -1,5 +1,6 @@ #include "SetEntranceList.h" +#include "Globals.h" #include "SetStartPositionList.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -13,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() @@ -40,25 +45,25 @@ void SetEntranceList::DeclareReferencesLate([[maybe_unused]] const std::string& 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::Align4, 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/ZAPD/ZRoom/Commands/SetExitList.cpp b/ZAPD/ZRoom/Commands/SetExitList.cpp index f491eb4..ddc4c5d 100644 --- a/ZAPD/ZRoom/Commands/SetExitList.cpp +++ b/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() @@ -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/ZAPD/ZRoom/Commands/SetLightList.cpp b/ZAPD/ZRoom/Commands/SetLightList.cpp index 8ad08a3..2e023ff 100644 --- a/ZAPD/ZRoom/Commands/SetLightList.cpp +++ b/ZAPD/ZRoom/Commands/SetLightList.cpp @@ -1,4 +1,6 @@ #include "SetLightList.h" + +#include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" @@ -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/ZAPD/ZRoom/Commands/SetLightingSettings.cpp b/ZAPD/ZRoom/Commands/SetLightingSettings.cpp index 9c32bc2..08cd83d 100644 --- a/ZAPD/ZRoom/Commands/SetLightingSettings.cpp +++ b/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" @@ -25,9 +27,8 @@ void SetLightingSettings::DeclareReferences(const std::string& prefix) 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/ZAPD/ZRoom/Commands/SetMesh.cpp b/ZAPD/ZRoom/Commands/SetMesh.cpp index 676fedd..4fa1f05 100644 --- a/ZAPD/ZRoom/Commands/SetMesh.cpp +++ b/ZAPD/ZRoom/Commands/SetMesh.cpp @@ -22,15 +22,15 @@ void SetMesh::ParseRawData() switch (meshHeaderType) { case 0: - polyType = std::make_shared<PolygonType2>(parent, parentRawData, segmentOffset, zRoom); + polyType = std::make_shared<PolygonType2>(parent, segmentOffset, zRoom); break; case 1: - polyType = std::make_shared<PolygonType1>(parent, parentRawData, segmentOffset, zRoom); + polyType = std::make_shared<PolygonType1>(parent, segmentOffset, zRoom); break; case 2: - polyType = std::make_shared<PolygonType2>(parent, parentRawData, segmentOffset, zRoom); + polyType = std::make_shared<PolygonType2>(parent, segmentOffset, zRoom); break; default: @@ -49,29 +49,18 @@ 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) - { - parent->AddDeclarationArray( - vtxEntry.first, DeclarationAlignment::Align16, - dList->vertices[vtxEntry.first].size() * 16, "Vtx", - StringHelper::Sprintf("%sVtx_%06X", zRoom->GetName().c_str(), vtxEntry.first), - dList->vertices[vtxEntry.first].size(), vtxEntry.second); - } } std::string SetMesh::GenDListExterns(ZDisplayList* dList) @@ -84,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()); } @@ -105,15 +93,8 @@ RoomCommand SetMesh::GetRoomCommand() const return RoomCommand::SetMesh; } -PolygonDlist::PolygonDlist(const std::string& prefix, - [[maybe_unused]] const std::vector<uint8_t>& 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() @@ -144,109 +125,42 @@ void PolygonDlist::DeclareReferences(const std::string& prefix) xluDList = MakeDlist(xlu, prefix); } -ZDisplayList* PolygonDlist::MakeDlist(segptr_t ptr, [[maybe_unused]] const std::string& prefix) -{ - if (ptr == 0) - { - return nullptr; - } - - uint32_t dlistAddress = Seg2Filespace(ptr, parent->baseAddress); - - int32_t dlistLength = ZDisplayList::GetDListLength( - parent->GetRawData(), dlistAddress, - Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); - ZDisplayList* dlist = new ZDisplayList(parent); - dlist->ExtractFromBinary(dlistAddress, dlistLength); - dlist->SetName(dlist->GetDefaultName(prefix)); - GenDListDeclarations(zRoom, parent, dlist); - - return dlist; -} - -size_t PolygonDlist::GetRawDataSize() const -{ - switch (polyType) - { - case 2: - return 0x10; - - default: - return 0x08; - } -} - -void PolygonDlist::SetPolyType(uint8_t nPolyType) -{ - polyType = nPolyType; -} - -void PolygonDlist::DeclareVar(const std::string& prefix, const std::string& bodyStr) -{ - std::string auxName = name; - if (name == "") - { - auxName = GetDefaultName(prefix, rawDataIndex); - } - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(), - GetSourceTypeName(), auxName, bodyStr); -} - -std::string PolygonDlist::GetBodySourceCode(bool arrayElement) +std::string PolygonDlist::GetBodySourceCode() const { std::string bodyStr; - std::string opaStr = parent->GetDeclarationPtrName(opa); - std::string xluStr = parent->GetDeclarationPtrName(xlu); - if (arrayElement) - { - bodyStr += " { "; - } - else - { - bodyStr += "\n "; - } + std::string opaStr; + std::string xluStr; + Globals::Instance->GetSegmentedPtrName(opa, parent, "Gfx", opaStr); + Globals::Instance->GetSegmentedPtrName(xlu, parent, "Gfx", xluStr); if (polyType == 2) { bodyStr += StringHelper::Sprintf("{ %6i, %6i, %6i }, %6i, ", x, y, z, unk_06); } - bodyStr += StringHelper::Sprintf("%s, ", opaStr.c_str()); - bodyStr += StringHelper::Sprintf("%s", xluStr.c_str()); - - if (arrayElement) - { - bodyStr += " },"; - } - else - { - bodyStr += "\n"; - } + bodyStr += StringHelper::Sprintf("%s, %s", opaStr.c_str(), xluStr.c_str()); return bodyStr; } -void PolygonDlist::DeclareAndGenerateOutputCode() +std::string PolygonDlist::GetSourceOutputCode(const std::string& prefix) { - std::string bodyStr = GetBodySourceCode(false); + std::string bodyStr = StringHelper::Sprintf("\n\t%s\n", GetBodySourceCode().c_str()); Declaration* decl = parent->GetDeclaration(rawDataIndex); if (decl == nullptr) { - DeclareVar("", bodyStr); + DeclareVar(prefix, 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); + return ""; } -std::string PolygonDlist::GetSourceTypeName() +std::string PolygonDlist::GetSourceTypeName() const { switch (polyType) { @@ -258,20 +172,64 @@ std::string PolygonDlist::GetSourceTypeName() } } -std::string PolygonDlist::GetName() +ZResourceType PolygonDlist::GetResourceType() const { - return name; + // TODO + return ZResourceType::Error; } -BgImage::BgImage(bool nIsSubStruct, const std::string& prefix, - [[maybe_unused]] const std::vector<uint8_t>& nRawData, uint32_t nRawDataIndex, +size_t PolygonDlist::GetRawDataSize() const +{ + switch (polyType) + { + case 2: + return 0x10; + + default: + return 0x08; + } +} + +void PolygonDlist::SetPolyType(uint8_t nPolyType) +{ + polyType = nPolyType; +} + +ZDisplayList* PolygonDlist::MakeDlist(segptr_t ptr, [[maybe_unused]] const std::string& prefix) +{ + if (ptr == 0) + { + return nullptr; + } + + uint32_t dlistAddress = Seg2Filespace(ptr, parent->baseAddress); + + int32_t dlistLength = ZDisplayList::GetDListLength( + parent->GetRawData(), dlistAddress, + Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + ZDisplayList* dlist = new ZDisplayList(parent); + dlist->ExtractFromBinary(dlistAddress, dlistLength); + dlist->SetName(dlist->GetDefaultName(prefix)); + GenDListDeclarations(zRoom, parent, dlist); + + return dlist; +} + +/* BgImage */ + +BgImage::BgImage(ZFile* nParent) : ZResource(nParent) +{ +} + +BgImage::BgImage(bool nIsSubStruct, const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent) + : BgImage(nParent) { rawDataIndex = nRawDataIndex; parent = nParent; isSubStruct = nIsSubStruct; - name = GetDefaultName(prefix.c_str(), rawDataIndex); + name = GetDefaultName(prefix); ParseRawData(); sourceBackground = MakeBackground(source, prefix); @@ -319,15 +277,15 @@ ZBackground* BgImage::MakeBackground(segptr_t ptr, const std::string& prefix) 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 "; } @@ -337,16 +295,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 += " "; } @@ -354,7 +310,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 += " "; } @@ -362,7 +318,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 += " "; } @@ -370,14 +326,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 }, "; } @@ -389,41 +345,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<uint8_t>& 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(); @@ -454,25 +395,14 @@ std::string PolygonTypeBase::GetSourceTypeName() const } } -std::string PolygonTypeBase::GetName() const -{ - return name; -} - -void PolygonTypeBase::SetName(const std::string& newName) -{ - name = newName; -} - -std::string PolygonTypeBase::GetDefaultName(const std::string& prefix) const +ZResourceType PolygonTypeBase::GetResourceType() const { - return StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), GetSourceTypeName().c_str(), - rawDataIndex); + // TODO + return ZResourceType::Error; } -PolygonType1::PolygonType1(ZFile* nParent, const std::vector<uint8_t>& 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) { } @@ -491,10 +421,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); } @@ -502,26 +432,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; 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"; @@ -532,9 +463,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; @@ -566,26 +497,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; } @@ -604,9 +535,8 @@ std::string PolygonType1::GetSourceTypeName() const // return "PolygonType1"; } -PolygonType2::PolygonType2(ZFile* nParent, const std::vector<uint8_t>& nRawData, - uint32_t nRawDataIndex, ZRoom* nRoom) - : PolygonTypeBase(nParent, nRawData, nRawDataIndex, nRoom) +PolygonType2::PolygonType2(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom) + : PolygonTypeBase(nParent, nRawDataIndex, nRoom) { } @@ -622,9 +552,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(); @@ -639,7 +570,8 @@ void PolygonType2::DeclareReferences(const std::string& prefix) 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"; } @@ -662,7 +594,8 @@ void PolygonType2::DeclareReferences(const std::string& prefix) 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()); @@ -675,3 +608,8 @@ size_t PolygonType2::GetRawDataSize() const { return 0x0C; } + +DeclarationAlignment PolygonType2::GetDeclarationAlignment() const +{ + return DeclarationAlignment::Align4; +} diff --git a/ZAPD/ZRoom/Commands/SetMesh.h b/ZAPD/ZRoom/Commands/SetMesh.h index 6559196..566711a 100644 --- a/ZAPD/ZRoom/Commands/SetMesh.h +++ b/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<uint8_t>& 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; - size_t GetRawDataSize() const; - void SetPolyType(uint8_t nPolyType); + std::string GetBodySourceCode() const override; + + std::string GetSourceOutputCode(const std::string& prefix) override; - void DeclareVar(const std::string& prefix, const std::string& bodyStr); + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; - std::string GetBodySourceCode(bool arrayElement); - void DeclareAndGenerateOutputCode(); + size_t GetRawDataSize() const override; - static std::string GetDefaultName(const std::string& prefix, uint32_t address); - std::string GetSourceTypeName(); - std::string GetName(); + void SetPolyType(uint8_t nPolyType); 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; -protected: - void ParseRawData(); - ZBackground* MakeBackground(segptr_t ptr, const std::string& prefix); + BgImage(ZFile* nParent); + BgImage(bool nIsSubStruct, const std::string& prefix, uint32_t nRawDataIndex, ZFile* nParent); -public: - BgImage() = default; - BgImage(bool nIsSubStruct, const std::string& prefix, const std::vector<uint8_t>& nRawData, - uint32_t nRawDataIndex, ZFile* nParent); + void ParseRawData() override; - static size_t GetRawDataSize(); + std::string GetBodySourceCode() const override; - std::string GetBodySourceCode(bool arrayElement) const; + std::string GetSourceTypeName() const override; + ZResourceType GetResourceType() const override; - static std::string GetDefaultName(const std::string& prefix, uint32_t address); - static std::string GetSourceTypeName(); - std::string GetName(); + size_t GetRawDataSize() const override; + +protected: + ZBackground* MakeBackground(segptr_t ptr, const std::string& prefix); }; -class PolygonTypeBase +class PolygonTypeBase : public ZResource { public: uint8_t type; std::vector<PolygonDlist> polyDLists; - PolygonTypeBase(ZFile* nParent, const std::vector<uint8_t>& nRawData, uint32_t nRawDataIndex, - ZRoom* nRoom); - virtual ~PolygonTypeBase() = default; - - virtual void ParseRawData() = 0; - virtual void DeclareReferences(const std::string& prefix) = 0; + PolygonTypeBase(ZFile* nParent, uint32_t nRawDataIndex, ZRoom* nRoom); - 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<BgImage> multiList; - PolygonType1(ZFile* nParent, const std::vector<uint8_t>& 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<uint8_t>& 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/ZAPD/ZRoom/Commands/SetMinimapChests.cpp b/ZAPD/ZRoom/Commands/SetMinimapChests.cpp index 20a33ac..ec432b7 100644 --- a/ZAPD/ZRoom/Commands/SetMinimapChests.cpp +++ b/ZAPD/ZRoom/Commands/SetMinimapChests.cpp @@ -49,7 +49,8 @@ void SetMinimapChests::DeclareReferences(const std::string& prefix) 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/ZAPD/ZRoom/Commands/SetMinimapList.cpp b/ZAPD/ZRoom/Commands/SetMinimapList.cpp index 8c9917a..be5d8f1 100644 --- a/ZAPD/ZRoom/Commands/SetMinimapList.cpp +++ b/ZAPD/ZRoom/Commands/SetMinimapList.cpp @@ -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/ZAPD/ZRoom/Commands/SetObjectList.cpp b/ZAPD/ZRoom/Commands/SetObjectList.cpp index 35c0d44..fdd41e6 100644 --- a/ZAPD/ZRoom/Commands/SetObjectList.cpp +++ b/ZAPD/ZRoom/Commands/SetObjectList.cpp @@ -23,9 +23,6 @@ void SetObjectList::ParseRawData() objects.push_back(objectIndex); currentPtr += 2; } - - if (segmentOffset != 0) - parent->AddDeclarationPlaceholder(segmentOffset); } void SetObjectList::DeclareReferences(const std::string& prefix) @@ -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/ZAPD/ZRoom/Commands/SetPathways.cpp b/ZAPD/ZRoom/Commands/SetPathways.cpp index 1649685..52d400a 100644 --- a/ZAPD/ZRoom/Commands/SetPathways.cpp +++ b/ZAPD/ZRoom/Commands/SetPathways.cpp @@ -13,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() @@ -29,14 +33,16 @@ void SetPathways::ParseRawDataLate() 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/ZAPD/ZRoom/Commands/SetRoomList.cpp b/ZAPD/ZRoom/Commands/SetRoomList.cpp index 507d0ab..e038139 100644 --- a/ZAPD/ZRoom/Commands/SetRoomList.cpp +++ b/ZAPD/ZRoom/Commands/SetRoomList.cpp @@ -33,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()); } diff --git a/ZAPD/ZRoom/Commands/SetRoomList.h b/ZAPD/ZRoom/Commands/SetRoomList.h index d4edc80..4fb2ced 100644 --- a/ZAPD/ZRoom/Commands/SetRoomList.h +++ b/ZAPD/ZRoom/Commands/SetRoomList.h @@ -38,7 +38,6 @@ public: class SetRoomList : public ZRoomCommand { public: - std::vector<RoomEntry> rooms; // Borrowed reference. Don't delete. RomFile* romfile = nullptr; diff --git a/ZAPD/ZRoom/Commands/SetStartPositionList.cpp b/ZAPD/ZRoom/Commands/SetStartPositionList.cpp index 69434a4..ad1d0a9 100644 --- a/ZAPD/ZRoom/Commands/SetStartPositionList.cpp +++ b/ZAPD/ZRoom/Commands/SetStartPositionList.cpp @@ -50,7 +50,8 @@ void SetStartPositionList::DeclareReferences(const std::string& prefix) 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/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp b/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp index 2eba064..d47ca34 100644 --- a/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp +++ b/ZAPD/ZRoom/Commands/SetTransitionActorList.cpp @@ -51,7 +51,8 @@ void SetTransitionActorList::DeclareReferences(const std::string& prefix) 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/ZAPD/ZRoom/ZRoom.cpp b/ZAPD/ZRoom/ZRoom.cpp index af9122f..9f4d5a9 100644 --- a/ZAPD/ZRoom/ZRoom.cpp +++ b/ZAPD/ZRoom/ZRoom.cpp @@ -112,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") @@ -335,11 +334,11 @@ std::string ZRoom::GetDefaultName(const std::string& prefix) const */ 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()); } @@ -393,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/ZAPD/ZRoom/ZRoom.h b/ZAPD/ZRoom/ZRoom.h index cc4bc0c..0993a9d 100644 --- a/ZAPD/ZRoom/ZRoom.h +++ b/ZAPD/ZRoom/ZRoom.h @@ -14,8 +14,6 @@ public: std::vector<ZRoomCommand*> commands; int32_t roomCount; // Only valid for scenes - std::string extDefines; - std::string hackMode; ZResourceType zroomType = ZResourceType::Error; @@ -36,6 +34,8 @@ public: Declaration* DeclareVar(const std::string& prefix, const std::string& body) override; std::string GetBodySourceCode() const override; + 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); @@ -46,7 +46,5 @@ public: 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/ZAPD/ZScalar.cpp b/ZAPD/ZScalar.cpp index 87e206a..062fb0e 100644 --- a/ZAPD/ZScalar.cpp +++ b/ZAPD/ZScalar.cpp @@ -20,6 +20,10 @@ void ZScalar::ExtractFromBinary(uint32_t nRawDataIndex, ZScalarType nScalarType) rawDataIndex = nRawDataIndex; scalarType = nScalarType; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); } diff --git a/ZAPD/ZSkeleton.cpp b/ZAPD/ZSkeleton.cpp index 24950fd..ebdf645 100644 --- a/ZAPD/ZSkeleton.cpp +++ b/ZAPD/ZSkeleton.cpp @@ -27,12 +27,9 @@ 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; @@ -83,22 +80,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 @@ -241,7 +238,8 @@ std::string ZLimbTable::GetBodySourceCode() const 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) diff --git a/ZAPD/ZSymbol.cpp b/ZAPD/ZSymbol.cpp index feea005..b24c3de 100644 --- a/ZAPD/ZSymbol.cpp +++ b/ZAPD/ZSymbol.cpp @@ -63,6 +63,12 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) 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 { if (isArray) @@ -71,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/ZAPD/ZSymbol.h b/ZAPD/ZSymbol.h index 1094a02..7cb14aa 100644 --- a/ZAPD/ZSymbol.h +++ b/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/ZAPD/ZTexture.cpp b/ZAPD/ZTexture.cpp index 624a955..49ac16c 100644 --- a/ZAPD/ZTexture.cpp +++ b/ZAPD/ZTexture.cpp @@ -33,6 +33,10 @@ void ZTexture::ExtractFromBinary(uint32_t nRawDataIndex, int32_t nWidth, int32_t name = GetDefaultName(parent->GetName()); outName = name; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); CalcHash(); } @@ -327,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->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 { @@ -738,15 +737,32 @@ Declaration* ZTexture::DeclareVar(const std::string& prefix, [[maybe_unused]] const std::string& bodyStr) { std::string auxName = name; + std::string auxOutName = outName; - if (name == "") + if (auxName == "") auxName = GetDefaultName(prefix); - auto filepath = Globals::Instance->outputPath / fs::path(auxName).stem(); + 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, 0); decl->staticConf = staticConf; diff --git a/ZAPD/ZTextureAnimation.cpp b/ZAPD/ZTextureAnimation.cpp index 963a2f2..4332fcf 100644 --- a/ZAPD/ZTextureAnimation.cpp +++ b/ZAPD/ZTextureAnimation.cpp @@ -75,9 +75,11 @@ * Each of these will declare all its subsidiary arrays, using POD structs. */ #include "ZTextureAnimation.h" + #include <cassert> #include <memory> #include <vector> + #include "Globals.h" #include "Utils/BitConverter.h" #include "ZFile.h" @@ -189,7 +191,7 @@ std::string TextureScrollingParams::GetBodySourceCode() const 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); } @@ -297,7 +299,7 @@ void TextureColorChangingParams::DeclareReferences([[maybe_unused]] const std::s 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); } @@ -317,7 +319,7 @@ void TextureColorChangingParams::DeclareReferences([[maybe_unused]] const std::s 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); } @@ -333,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) { @@ -353,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; } @@ -437,12 +445,12 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& 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"; @@ -462,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(); @@ -478,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) { @@ -498,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; } @@ -677,8 +689,11 @@ std::string ZTextureAnimation::GetBodySourceCode() const 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(); diff --git a/ZAPD/ZTextureAnimation.h b/ZAPD/ZTextureAnimation.h index c69fb34..6b03eb7 100644 --- a/ZAPD/ZTextureAnimation.h +++ b/ZAPD/ZTextureAnimation.h @@ -136,7 +136,6 @@ public: ZTextureAnimation(ZFile* nParent); void ParseRawData() override; - void DeclareReferences(const std::string& prefix) override; std::string GetSourceTypeName() const override; @@ -149,4 +148,4 @@ public: private: std::vector<TextureAnimationEntry> entries; -};
\ No newline at end of file +}; diff --git a/ZAPD/ZVector.cpp b/ZAPD/ZVector.cpp index 3537750..c940b0b 100644 --- a/ZAPD/ZVector.cpp +++ b/ZAPD/ZVector.cpp @@ -26,6 +26,10 @@ void ZVector::ExtractFromBinary(uint32_t nRawDataIndex, ZScalarType nScalarType, scalarType = nScalarType; dimensions = nDimensions; + // Don't parse raw data of external files + if (parent->GetMode() == ZFileMode::ExternalFile) + return; + ParseRawData(); } @@ -115,5 +119,9 @@ ZResourceType ZVector::GetResourceType() const DeclarationAlignment ZVector::GetDeclarationAlignment() const { + if (scalars.size() == 0) + { + return DeclarationAlignment::Align4; + } return scalars.at(0).GetDeclarationAlignment(); } diff --git a/ZAPD/ZVtx.h b/ZAPD/ZVtx.h index 7bc2fdf..018a1d4 100644 --- a/ZAPD/ZVtx.h +++ b/ZAPD/ZVtx.h @@ -30,6 +30,4 @@ public: size_t GetRawDataSize() const override; DeclarationAlignment GetDeclarationAlignment() const override; - -protected: }; diff --git a/ZAPDUtils/Utils/Path.h b/ZAPDUtils/Utils/Path.h index e383f14..496a0ae 100644 --- a/ZAPDUtils/Utils/Path.h +++ b/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<std::string> 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<std::string> 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<std::string> 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/copycheck.py b/copycheck.py index d13f984..36288f6 100755 --- a/copycheck.py +++ b/copycheck.py @@ -1,3 +1,5 @@ +#!/usr/bin/env python3 + import os from shutil import copyfile |
