diff --git a/tools/ZAPD/.gitignore b/tools/ZAPD/.gitignore index 749e6a89b5..136ffb1b28 100644 --- a/tools/ZAPD/.gitignore +++ b/tools/ZAPD/.gitignore @@ -333,3 +333,4 @@ ASALocalRun/ *.o *.d .vscode/ +ZAPD/BuildInfo.h \ No newline at end of file diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo index e9c9dcfe8e..511240f54b 100644 --- a/tools/ZAPD/.gitrepo +++ b/tools/ZAPD/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/zeldaret/ZAPD.git branch = master - commit = f84d8337bdc55f39dfa5a6dbb39a4fcae0b24e1c - parent = 1d4d75f09bc6939438dd4b0fe6e1c212c3f1e198 + commit = 4bf6600a3b67223d5e28d6a1fccfeb54e37d7a77 + parent = 8e0fa07a7e03730951ba98a377cf7738e8f26295 method = merge cmdver = 0.4.3 diff --git a/tools/ZAPD/Makefile b/tools/ZAPD/Makefile index 4293459c0f..cd4cd2826a 100644 --- a/tools/ZAPD/Makefile +++ b/tools/ZAPD/Makefile @@ -4,7 +4,7 @@ ifneq (, $(shell which ccache)) CC := ccache $(CC) endif -CFLAGS := -g -std=c++17 -I ZAPD -I lib/assimp/include -I lib/elfio -I lib/json/include -I lib/stb -I lib/tinygltf -I lib/tinyxml2 -O2 -rdynamic +CFLAGS := -g -std=c++17 -I ZAPD -I lib/assimp/include -I lib/elfio -I lib/json/include -I lib/stb -I lib/tinygltf -I lib/libgfxd -I lib/tinyxml2 -O2 -rdynamic UNAME := $(shell uname) @@ -19,7 +19,10 @@ CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) CPP_FILES += lib/tinyxml2/tinyxml2.cpp O_FILES := $(CPP_FILES:.cpp=.o) -all: ZAPD.out +all: genbuildinfo ZAPD.out + +genbuildinfo: + python3 ZAPD/genbuildinfo.py clean: rm -f $(O_FILES) ZAPD.out @@ -30,4 +33,4 @@ rebuild: clean all $(CC) $(CFLAGS) -c $< -o $@ ZAPD.out: $(O_FILES) - $(CC) $(CFLAGS) $(O_FILES) -o $@ $(FS_INC) + $(CC) $(CFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a -o $@ $(FS_INC) diff --git a/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.cpp b/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.cpp index 037172ea9c..bd8ec784ee 100644 --- a/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.cpp +++ b/tools/ZAPD/ZAPD/HighLevel/HLModelIntermediette.cpp @@ -259,7 +259,7 @@ void HLModelIntermediette::FromZSkeleton(HLModelIntermediette* model, ZSkeleton* for (int i = 0; i < zSkeleton->limbs.size(); i++) { - ZLimbStandard* limb = zSkeleton->limbs[i]; + ZLimb* limb = zSkeleton->limbs[i]; for (int j = 0; j < model->blocks.size(); j++) { diff --git a/tools/ZAPD/ZAPD/Main.cpp b/tools/ZAPD/ZAPD/Main.cpp index 4ae1174510..9e0195c508 100644 --- a/tools/ZAPD/ZAPD/Main.cpp +++ b/tools/ZAPD/ZAPD/Main.cpp @@ -9,6 +9,7 @@ #include "File.h" #include "Directory.h" #include "Globals.h" +#include "BuildInfo.h" #if !defined(_MSC_VER) && !defined(__CYGWIN__) #include @@ -172,6 +173,7 @@ int NewMain(int argc, char* argv[]) { #if !defined(_MSC_VER) && !defined(__CYGWIN__) signal(SIGSEGV, ErrorHandler); + signal(SIGABRT, ErrorHandler); #endif } else if (arg == "-v") // Verbose @@ -181,7 +183,7 @@ int NewMain(int argc, char* argv[]) } if (Globals::Instance->verbosity >= VERBOSITY_INFO) - printf("ZAPD: Zelda Asset Processor For Decomp\n"); + printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash); if (fileMode == ZFileMode::Build || fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) { diff --git a/tools/ZAPD/ZAPD/OutputFormatter.cpp b/tools/ZAPD/ZAPD/OutputFormatter.cpp new file mode 100644 index 0000000000..5e7c35ccd4 --- /dev/null +++ b/tools/ZAPD/ZAPD/OutputFormatter.cpp @@ -0,0 +1,103 @@ +#include "OutputFormatter.h" + +int OutputFormatter::write(const char *buf, int count) +{ + for (int i = 0; i < count; i++) + { + char c = buf[i]; + + if (c == '\n') + { + col = 0; + current_indent = nest_indent[nest]; + } + else if (c == '\t') + { + int n = tab_size - (col % tab_size); + for (int j = 0; j < n - 1; j++) + *space_p++ = ' '; + c = ' '; + col += n; + } + else + { + col++; + } + + if (c == '(') + { + nest++; + nest_indent[nest] = col; + current_indent = col; + } + else if (c == ')') + { + nest--; + } + + if (c == ' ' || c == '\t' || c == '\n') + { + str.append(word, word_p - word); + word_p = word; + + *space_p++ = c; + } + else + { + if (col > line_limit) + { + str.append(1, '\n'); + str.append(current_indent, ' '); + col = current_indent + 1 + (word_p - word); + } + else + { + str.append(space, space_p - space); + } + space_p = space; + + *word_p++ = c; + } + } + + return count; +} + +OutputFormatter* OutputFormatter::static_instance; + +int OutputFormatter::write_static(const char *buf, int count) +{ + return static_instance->write(buf, count); +} + +int (*OutputFormatter::static_writer())(const char *buf, int count) +{ + static_instance = this; + return &write_static; +} + +OutputFormatter::OutputFormatter(int tab_size , int default_indent, + int line_limit) + : + tab_size{tab_size}, + default_indent{default_indent}, + line_limit{line_limit}, + col{0}, + nest{0}, + nest_indent{default_indent}, + current_indent{default_indent}, + word_p{word}, + space_p{space} +{ +} + +std::string OutputFormatter::get_output() +{ + str.append(space, space_p - space); + space_p = space; + + str.append(word, word_p - word); + word_p = word; + + return std::move(str); +} diff --git a/tools/ZAPD/ZAPD/OutputFormatter.h b/tools/ZAPD/ZAPD/OutputFormatter.h new file mode 100644 index 0000000000..d1cdc68f6e --- /dev/null +++ b/tools/ZAPD/ZAPD/OutputFormatter.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include + +class OutputFormatter +{ +private: + const int tab_size; + const int default_indent; + const int line_limit; + + int col; + int nest; + int nest_indent[8]; + int current_indent; + + char word[128]; + char space[128]; + char *word_p; + char *space_p; + + std::string str; + + int write(const char *buf, int count); + + static OutputFormatter *static_instance; + static int write_static(const char *buf, int count); + +public: + OutputFormatter(int tab_size = 4, int default_indent = 4, + int line_limit = 120); + + int (*static_writer())(const char *buf, int count); + + std::string get_output(); +}; \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj b/tools/ZAPD/ZAPD/ZAPD.vcxproj index 654159cb91..e270caeb7f 100644 --- a/tools/ZAPD/ZAPD/ZAPD.vcxproj +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj @@ -103,6 +103,10 @@ true assimp-vc142-mt.lib;%(AdditionalDependencies) + + cd .. +python3 ZAPD/genbuildinfo.py + diff --git a/tools/ZAPD/ZAPD/ZAnimation.cpp b/tools/ZAPD/ZAPD/ZAnimation.cpp index a130268772..21fdf3ffd9 100644 --- a/tools/ZAPD/ZAPD/ZAnimation.cpp +++ b/tools/ZAPD/ZAPD/ZAnimation.cpp @@ -183,6 +183,6 @@ void ZLinkAnimation::ParseRawData() const uint8_t* data = rawData.data(); - //segmentAddress = SEG2FILESPACE(BitConverter::ToInt32BE(data, rawDataIndex + 4)); + //segmentAddress = GETSEGOFFSET(BitConverter::ToInt32BE(data, rawDataIndex + 4)); segmentAddress = (BitConverter::ToInt32BE(data, rawDataIndex + 4)); } diff --git a/tools/ZAPD/ZAPD/ZCollision.cpp b/tools/ZAPD/ZAPD/ZCollision.cpp index d6af196780..35ecbca57c 100644 --- a/tools/ZAPD/ZAPD/ZCollision.cpp +++ b/tools/ZAPD/ZAPD/ZCollision.cpp @@ -1,6 +1,7 @@ #include "ZCollision.h" #include "BitConverter.h" #include "StringHelper.h" +#include "Globals.h" #include #include @@ -24,23 +25,29 @@ ZCollisionHeader::ZCollisionHeader(ZFile* parent, const std::string& prefix, con absMaxZ = BitConverter::ToInt16BE(data, rawDataIndex + 10); numVerts = BitConverter::ToInt16BE(data, rawDataIndex + 12); - vtxSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 16); + vtxAddress = BitConverter::ToInt32BE(data, rawDataIndex + 16); numPolygons = BitConverter::ToInt16BE(data, rawDataIndex + 20); - polySegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 24); - polyTypeDefSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 28); - camDataSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 32); + polyAddress = BitConverter::ToInt32BE(data, rawDataIndex + 24); + polyTypeDefAddress = BitConverter::ToInt32BE(data, rawDataIndex + 28); + camDataAddress = BitConverter::ToInt32BE(data, rawDataIndex + 32); numWaterBoxes = BitConverter::ToInt16BE(data, rawDataIndex + 36); - waterBoxSegmentOffset = BitConverter::ToInt32BE(data, rawDataIndex + 40) & 0x00FFFFFF; + waterBoxAddress = BitConverter::ToInt32BE(data, rawDataIndex + 40); + + uint32_t vtxSegmentOffset = Seg2Filespace(vtxAddress, parent->baseAddress); + uint32_t polySegmentOffset = Seg2Filespace(polyAddress, parent->baseAddress); + uint32_t polyTypeDefSegmentOffset = Seg2Filespace(polyTypeDefAddress, parent->baseAddress); + uint32_t camDataSegmentOffset = Seg2Filespace(camDataAddress, parent->baseAddress); + uint32_t waterBoxSegmentOffset = Seg2Filespace(waterBoxAddress, parent->baseAddress); // HOTSPOT for (int i = 0; i < numVerts; i++) - vertices.push_back(new VertexEntry(rawData, SEG2FILESPACE(vtxSegmentOffset) + (i * 6))); + vertices.push_back(new VertexEntry(rawData, vtxSegmentOffset + (i * 6))); // HOTSPOT for (int i = 0; i < numPolygons; i++) - polygons.push_back(new PolygonEntry(rawData, SEG2FILESPACE(polySegmentOffset) + (i * 16))); + polygons.push_back(new PolygonEntry(rawData, polySegmentOffset + (i * 16))); int highestPolyType = 0; @@ -53,7 +60,7 @@ ZCollisionHeader::ZCollisionHeader(ZFile* parent, const std::string& prefix, con //if (highestPolyType > 0) { for (int i = 0; i < highestPolyType + 1; i++) - polygonTypes.push_back(BitConverter::ToUInt64BE(data, SEG2FILESPACE(polyTypeDefSegmentOffset) + (i * 8))); + polygonTypes.push_back(BitConverter::ToUInt64BE(data, polyTypeDefSegmentOffset + (i * 8))); } //else //{ @@ -63,11 +70,11 @@ ZCollisionHeader::ZCollisionHeader(ZFile* parent, const std::string& prefix, con //polygonTypes.push_back(BitConverter::ToUInt64BE(data, polyTypeDefSegmentOffset + (i * 8))); //} - if (camDataSegmentOffset != 0) - camData = new CameraDataList(parent, prefix, rawData, SEG2FILESPACE(camDataSegmentOffset), SEG2FILESPACE(polyTypeDefSegmentOffset), polygonTypes.size()); + if (camDataAddress != 0) + camData = new CameraDataList(parent, prefix, rawData, camDataSegmentOffset, polyTypeDefSegmentOffset, polygonTypes.size()); for (int i = 0; i < numWaterBoxes; i++) - waterBoxes.push_back(new WaterBoxHeader(rawData, waterBoxSegmentOffset + (i * 16))); + waterBoxes.push_back(new WaterBoxHeader(rawData, waterBoxSegmentOffset + (i * (Globals::Instance->game == ZGame::OOT_SW97 ? 12 : 16)))); string declaration = ""; char line[2048]; @@ -81,7 +88,7 @@ ZCollisionHeader::ZCollisionHeader(ZFile* parent, const std::string& prefix, con } } - if (waterBoxSegmentOffset != 0) + if (waterBoxAddress != 0) parent->AddDeclarationArray(waterBoxSegmentOffset, DeclarationAlignment::None, 16 * waterBoxes.size(), "WaterBox", StringHelper::Sprintf("%s_waterBoxes_%08X", prefix.c_str(), waterBoxSegmentOffset), 0, declaration); @@ -91,29 +98,29 @@ ZCollisionHeader::ZCollisionHeader(ZFile* parent, const std::string& prefix, con for (int i = 0; i < polygons.size(); i++) { - sprintf(line, " { 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X }, // 0x%08X\n", + sprintf(line, " { 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X, 0x%04X },\n", (uint16_t)polygons[i]->type, (uint16_t)polygons[i]->vtxA, (uint16_t)polygons[i]->vtxB, (uint16_t)polygons[i]->vtxC, - (uint16_t)polygons[i]->a, (uint16_t)polygons[i]->b, (uint16_t)polygons[i]->c, (uint16_t)polygons[i]->d, SEG2FILESPACE(polySegmentOffset) + (i * 16)); + (uint16_t)polygons[i]->a, (uint16_t)polygons[i]->b, (uint16_t)polygons[i]->c, (uint16_t)polygons[i]->d); declaration += line; } - if (polySegmentOffset != 0) { - parent->AddDeclarationArray(SEG2FILESPACE(polySegmentOffset), DeclarationAlignment::None, polygons.size() * 16, "CollisionPoly", StringHelper::Sprintf("%s_polygons_%08X", prefix.c_str(), SEG2FILESPACE(polySegmentOffset)), 0, declaration); + if (polyAddress != 0) { + parent->AddDeclarationArray(polySegmentOffset, DeclarationAlignment::None, polygons.size() * 16, "CollisionPoly", StringHelper::Sprintf("%s_polygons_%08X", prefix.c_str(), polySegmentOffset), 0, declaration); } } declaration = ""; for (int i = 0; i < polygonTypes.size(); i++) { - declaration += StringHelper::Sprintf(" 0x%08lX, 0x%08lX,", polygonTypes[i] >> 32, polygonTypes[i] & 0xFFFFFFFF); + declaration += StringHelper::Sprintf(" { 0x%08lX, 0x%08lX },", polygonTypes[i] >> 32, polygonTypes[i] & 0xFFFFFFFF); if (i < polygonTypes.size() - 1) declaration += "\n"; } - if (polyTypeDefSegmentOffset != 0) - parent->AddDeclarationArray(SEG2FILESPACE(polyTypeDefSegmentOffset), DeclarationAlignment::None, polygonTypes.size() * 8, - "u32", StringHelper::Sprintf("%s_polygonTypes_%08X", prefix.c_str(), SEG2FILESPACE(polyTypeDefSegmentOffset)), 0, declaration); + if (polyTypeDefAddress != 0) + parent->AddDeclarationArray(polyTypeDefSegmentOffset, DeclarationAlignment::None, polygonTypes.size() * 8, + "SurfaceType", StringHelper::Sprintf("%s_surfaceType_%08X", prefix.c_str(), polyTypeDefSegmentOffset), 0, declaration); declaration = ""; @@ -123,15 +130,15 @@ ZCollisionHeader::ZCollisionHeader(ZFile* parent, const std::string& prefix, con for (int i = 0; i < vertices.size(); i++) { - declaration += StringHelper::Sprintf(" { %i, %i, %i }, // 0x%08X", vertices[i]->x, vertices[i]->y, vertices[i]->z, SEG2FILESPACE(vtxSegmentOffset) + (i * 6)); + declaration += StringHelper::Sprintf(" { %i, %i, %i },", vertices[i]->x, vertices[i]->y, vertices[i]->z); if (i < vertices.size() - 1) declaration += "\n"; } - if (vtxSegmentOffset != 0) - parent->AddDeclarationArray(SEG2FILESPACE(vtxSegmentOffset), DeclarationAlignment::None, vertices.size() * 6, - "Vec3s", StringHelper::Sprintf("%s_vtx_%08X", prefix.c_str(), SEG2FILESPACE(vtxSegmentOffset)), 0, declaration); + if (vtxAddress != 0) + parent->AddDeclarationArray(vtxSegmentOffset, DeclarationAlignment::None, vertices.size() * 6, + "Vec3s", StringHelper::Sprintf("%s_vtx_%08X", prefix.c_str(), vtxSegmentOffset), 0, declaration); declaration = ""; } @@ -139,17 +146,21 @@ ZCollisionHeader::ZCollisionHeader(ZFile* parent, const std::string& prefix, con declaration = ""; char waterBoxStr[2048]; - if (waterBoxSegmentOffset != 0) + if (waterBoxAddress != 0) sprintf(waterBoxStr, "%s_waterBoxes_%08X", prefix.c_str(), waterBoxSegmentOffset); else - sprintf(waterBoxStr, "0"); + sprintf(waterBoxStr, "NULL"); - declaration += StringHelper::Sprintf("%i, %i, %i, %i, %i, %i, %i, %s_vtx_%08X, %i, %s_polygons_%08X, %s_polygonTypes_%08X, &%s_camDataList_%08X, %i, %s", + declaration += "\n"; + + declaration += StringHelper::Sprintf(" { %i, %i, %i },\n { %i, %i, %i },\n", absMinX, absMinY, absMinZ, - absMaxX, absMaxY, absMaxZ, - numVerts, prefix.c_str(), SEG2FILESPACE(vtxSegmentOffset), numPolygons, - prefix.c_str(), SEG2FILESPACE(polySegmentOffset), prefix.c_str(), SEG2FILESPACE(polyTypeDefSegmentOffset), - prefix.c_str(), SEG2FILESPACE(camDataSegmentOffset), numWaterBoxes, waterBoxStr); + absMaxX, absMaxY, absMaxZ); + + declaration += StringHelper::Sprintf(" %i,\n %s_vtx_%08X,\n %i,\n %s_polygons_%08X,\n %s_surfaceType_%08X,\n &%s_camDataList_%08X,\n %i,\n %s\n", + numVerts, prefix.c_str(), vtxSegmentOffset, numPolygons, + prefix.c_str(), polySegmentOffset, prefix.c_str(), polyTypeDefSegmentOffset, + prefix.c_str(), camDataSegmentOffset, numWaterBoxes, waterBoxStr); parent->AddDeclaration(rawDataIndex, DeclarationAlignment::None, DeclarationPadding::Pad16, 44, "CollisionHeader", StringHelper::Sprintf("%s", prefix.c_str(), rawDataIndex), declaration); @@ -213,7 +224,14 @@ WaterBoxHeader::WaterBoxHeader(const std::vector& rawData, int rawDataI zMin = BitConverter::ToInt16BE(data, rawDataIndex + 4); xLength = BitConverter::ToInt16BE(data, rawDataIndex + 6); zLength = BitConverter::ToInt16BE(data, rawDataIndex + 8); - properties = BitConverter::ToInt32BE(data, rawDataIndex + 12); + if (Globals::Instance->game == ZGame::OOT_SW97) + { + properties = BitConverter::ToInt16BE(data, rawDataIndex + 10); + } + else + { + properties = BitConverter::ToInt32BE(data, rawDataIndex + 12); + } } CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, const std::vector& rawData, int rawDataIndex, int polyTypeDefSegmentOffset, int polygonTypesCnt) @@ -258,7 +276,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, const s else sprintf(camSegLine, "0x%08X", entries[i]->cameraPosDataSeg); - declaration += StringHelper::Sprintf("\t{ 0x%04X, %i, %s },", entries[i]->cameraSType, entries[i]->numData, camSegLine, rawDataIndex + (i * 8)); + declaration += StringHelper::Sprintf(" { 0x%04X, %i, %s },", entries[i]->cameraSType, entries[i]->numData, camSegLine, rawDataIndex + (i * 8)); if (i < entries.size() - 1) declaration += "\n"; @@ -276,7 +294,7 @@ CameraDataList::CameraDataList(ZFile* parent, const std::string& prefix, const s CameraPositionData* data = new CameraPositionData(rawData, cameraPosDataOffset + (i * 6)); cameraPositionData.push_back(data); - declaration += StringHelper::Sprintf("\t{ %6i, %6i, %6i }, // 0x%08X\n", data->x, data->y, data->z, cameraPosDataSeg + (i * 0x6));; + declaration += StringHelper::Sprintf(" { %6i, %6i, %6i },\n", data->x, data->y, data->z); } int cameraPosDataIndex = cameraPosDataSeg & 0x00FFFFFF; diff --git a/tools/ZAPD/ZAPD/ZCollision.h b/tools/ZAPD/ZAPD/ZCollision.h index aa0279d9b3..7f7b7150a9 100644 --- a/tools/ZAPD/ZAPD/ZCollision.h +++ b/tools/ZAPD/ZAPD/ZCollision.h @@ -67,14 +67,14 @@ public: int16_t absMinX, absMinY, absMinZ; int16_t absMaxX, absMaxY, absMaxZ; int16_t numVerts; - segptr_t vtxSegmentOffset; + segptr_t vtxAddress; int16_t numPolygons; - segptr_t polySegmentOffset; - segptr_t polyTypeDefSegmentOffset; - segptr_t camDataSegmentOffset; + segptr_t polyAddress; + segptr_t polyTypeDefAddress; + segptr_t camDataAddress; int32_t numWaterBoxes; - int32_t waterBoxSegmentOffset; + segptr_t waterBoxAddress; std::vector vertices; std::vector polygons; diff --git a/tools/ZAPD/ZAPD/ZCutscene.cpp b/tools/ZAPD/ZAPD/ZCutscene.cpp index 80ebeffbb6..d2ef633930 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.cpp +++ b/tools/ZAPD/ZAPD/ZCutscene.cpp @@ -913,7 +913,7 @@ CutsceneCommandSceneTransFX::CutsceneCommandSceneTransFX(const vector& string CutsceneCommandSceneTransFX::GenerateSourceCode(const std::string& roomName, int baseAddress) { - return StringHelper::Sprintf("CS_SCENE_TRANS_FX(%i, %i, %i, %i),\n", base, startFrame, endFrame); + return StringHelper::Sprintf("CS_SCENE_TRANS_FX(%i, %i, %i),\n", base, startFrame, endFrame); } string CutsceneCommandSceneTransFX::GetCName(const std::string& prefix) diff --git a/tools/ZAPD/ZAPD/ZDisplayList.cpp b/tools/ZAPD/ZAPD/ZDisplayList.cpp index 3bf96e168a..02e43d52fc 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.cpp +++ b/tools/ZAPD/ZAPD/ZDisplayList.cpp @@ -1,8 +1,10 @@ #include "ZDisplayList.h" #include "BitConverter.h" #include "StringHelper.h" +#include "OutputFormatter.h" #include "HighLevel/HLModelIntermediette.h" #include "Globals.h" +#include "gfxd.h" #include #include #include @@ -68,7 +70,7 @@ ZDisplayList::ZDisplayList(vector nRawData, int nRawDataIndex, int rawD { fileData = nRawData; rawDataIndex = nRawDataIndex; - name = StringHelper::Sprintf("Dlist0x%06X", rawDataIndex); + name = StringHelper::Sprintf("DL_%06X", rawDataIndex); rawData = vector(nRawData.data() + rawDataIndex, nRawData.data() + rawDataIndex + rawDataSize); ParseRawData(); } @@ -509,11 +511,8 @@ int ZDisplayList::OptimizationCheck_LoadTextureBlock(int startIndex, string& out fmt = (__ & 0xE0) >> 5; siz = (__ & 0x18) >> 3; - texAddr = SEG2FILESPACE(data); - int segmentNumber = (data & 0xFF000000) >> 24; - - if (segmentNumber == 0x80) // Is this texture defined in code? - texAddr -= SEG2FILESPACE(parent->baseAddress); + texAddr = Seg2Filespace(data, parent->baseAddress); + int segmentNumber = GETSEGNUM(data); lastTexSeg = (data & 0xFF000000); @@ -664,12 +663,12 @@ int ZDisplayList::OptimizationCheck_LoadTextureBlock(int startIndex, string& out void ZDisplayList::Opcode_G_DL(uint64_t data, int i, std::string prefix, char* line) { int pp = (data & 0x00FF000000000000) >> 56; - int segNum = (data & 0xFF000000) >> 24; + int segNum = GETSEGNUM(data); Declaration* dListDecl = nullptr; if (parent != nullptr) - dListDecl = parent->GetDeclaration(SEG2FILESPACE(data)); + dListDecl = parent->GetDeclaration(GETSEGOFFSET(data)); if (pp != 0) { @@ -678,7 +677,7 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, int i, std::string prefix, char* l else if (dListDecl != nullptr) sprintf(line, "gsSPBranchList(%s),", dListDecl->varName.c_str()); else - sprintf(line, "gsSPBranchList(%sDlist0x%06lX),", prefix.c_str(), SEG2FILESPACE(data)); + sprintf(line, "gsSPBranchList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data)); } else { @@ -687,10 +686,11 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, int i, std::string prefix, char* l else if (dListDecl != nullptr) sprintf(line, "gsSPDisplayList(%s),", dListDecl->varName.c_str()); else - sprintf(line, "gsSPDisplayList(%sDlist0x%06lX),", prefix.c_str(), SEG2FILESPACE(data)); + sprintf(line, "gsSPDisplayList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data)); } - int segmentNumber = (data & 0xFF000000) >> 24; + // TODO: This is the same as `segNum`. Consider resuing that variable instead of making a new one. + int segmentNumber = GETSEGNUM(data); if (segmentNumber == 8 || segmentNumber == 9 || segmentNumber == 10 || segmentNumber == 11 || segmentNumber == 12 || segmentNumber == 13) // Used for runtime-generated display lists { @@ -756,9 +756,11 @@ void ZDisplayList::Opcode_G_TRI2(uint64_t data, int i, std::string prefix, char* void ZDisplayList::Opcode_G_MTX(uint64_t data, int i, std::string prefix, char* line) { - // TODO: FINISH THIS uint32_t pp = 0; uint32_t mm = (data & 0x00000000FFFFFFFF); + bool push = false; + bool load = false; + bool projection = false; if (dListType == DListType::F3DEX) pp = (data & 0x00FF000000000000) >> 48; @@ -772,7 +774,21 @@ void ZDisplayList::Opcode_G_MTX(uint64_t data, int i, std::string prefix, char* else matrixRef = StringHelper::Sprintf("0x%08X", mm); - sprintf(line, "gsSPMatrix(%s, 0x%02X),", matrixRef.c_str(), pp ^ 0x01); + pp ^= 0x01; + + if (pp & 0x01) + push = true; + + if (pp & 0x02) + load = true; + + if (pp & 0x04) + projection = true; + + sprintf(line, "gsSPMatrix(%s, %s | %s | %s),", matrixRef.c_str(), + projection ? "G_MTX_PROJECTION" : "G_MTX_MODELVIEW", + push ? "G_MTX_PUSH" : "G_MTX_NOPUSH", + load ? "G_MTX_LOAD" : "G_MTX_MUL"); } void ZDisplayList::Opcode_G_VTX(uint64_t data, int i, std::string prefix, char* line) @@ -780,10 +796,7 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, int i, std::string prefix, char* int nn = (data & 0x000FF00000000000ULL) >> 44; int aa = (data & 0x000000FF00000000ULL) >> 32; - uint32_t vtxAddr = SEG2FILESPACE(data); - - if (GETSEGNUM(data) == 0x80) // Are these vertices defined in code? - vtxAddr -= SEG2FILESPACE(parent->baseAddress); + uint32_t vtxAddr = Seg2Filespace(data, parent->baseAddress); if (dListType == DListType::F3DZEX) sprintf(line, "gsSPVertex(@r, %i, %i),", nn, ((aa >> 1) - nn)); @@ -799,13 +812,17 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, int i, std::string prefix, char* sprintf(line, "gsSPVertex(@r, %i, %i),", nn, _SHIFTR(hi, 17, 7)); } + // Hack: Don't extract vertices from a unknown segment. + if (!Globals::Instance->HasSegment(GETSEGNUM(data))) { + segptr_t segmented = data & 0xFFFFFFFF; + references.push_back(segmented); + parent->AddDeclaration(segmented, DeclarationAlignment::Align16, 16, "Vtx", StringHelper::Sprintf("0x%08X", segmented), ""); + return; + } references.push_back(vtxAddr); { - uint32_t currentPtr = SEG2FILESPACE(data); - - if (GETSEGNUM(data) == 0x80) // Are these vertices defined in code? - currentPtr -= SEG2FILESPACE(parent->baseAddress); + uint32_t currentPtr = Seg2Filespace(data, parent->baseAddress); // Check for vertex intersections from other display lists // TODO: These two could probably be condenced to one... @@ -884,22 +901,16 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, int i, std::string prefix, ch lastTexFmt = (F3DZEXTexFormats)fmt; lastTexSiz = (F3DZEXTexSizes)siz; lastTexSeg = data; - lastTexAddr = data & 0x00FFFFFF; + lastTexAddr = Seg2Filespace(data, parent->baseAddress); - if (GETSEGNUM(lastTexSeg) == 0x80) // Is this texture defined in code? - lastTexAddr -= SEG2FILESPACE(parent->baseAddress); - - int segmentNumber = (data >> 24) & 0xFF; + int segmentNumber = GETSEGNUM(data); if (segmentNumber != 2) { char texStr[2048]; - int32_t texAddress = SEG2FILESPACE(data); + int32_t texAddress = Seg2Filespace(data, parent->baseAddress); Declaration* texDecl = nullptr; - if (segmentNumber == 0x80) // Is this texture defined in code? - texAddress -= SEG2FILESPACE(parent->baseAddress); - if (parent != nullptr) { if (Globals::Instance->HasSegment(segmentNumber)) @@ -932,7 +943,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, int i, std::string prefix, ch else { //sprintf(line, "gsDPSetTextureImage(%s, %s, %i, 0x%08X),", fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), www + 1, data & 0xFFFFFFFF); - sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %sTex_%06lX),", fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), www + 1, scene->GetName().c_str(), SEG2FILESPACE(data)); + sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %sTex_%06lX),", fmtTbl[fmt].c_str(), sizTbl[siz].c_str(), www + 1, scene->GetName().c_str(), GETSEGOFFSET(data)); } } @@ -1034,18 +1045,24 @@ void ZDisplayList::Opcode_G_SETCOMBINE(uint64_t data, int i, std::string prefix, int ab1 = (data & 0b00000000000000000000000000000000000000000000000000000000111000) >> 3; int ad1 = (data & 0b00000000000000000000000000000000000000000000000000000000000111) >> 0; - string modes[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "COMBINED_ALPHA", + string modesA[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "NOISE", + "0", "9", "10", "11", "12", "13", "14", "0"}; + string modesB[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "CENTER", "K4", + "8", "9", "10", "11", "12", "13", "14", "0"}; + string modesC[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "COMBINED_ALPHA", "TEXEL0_ALPHA", "TEXEL1_ALPHA", "PRIMITIVE_ALPHA", "SHADE_ALPHA", "ENV_ALPHA", "LOD_FRACTION", "PRIM_LOD_FRAC", "K5", - "17", "18", "19", "20", "21", "22", "23", "24", - "25", "26", "27", "28", "29", "30", "31", "0" }; + "16", "17", "18", "19", "20", "21", "22", "23", + "24", "25", "26", "27", "28", "29", "30", "0" }; + string modesD[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0"}; string modes2[] = { "COMBINED", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "1", "0" }; + string modes2C[] = { "LOD_FRACTION", "TEXEL0", "TEXEL1", "PRIMITIVE", "SHADE", "ENVIRONMENT", "PRIM_LOD_FRAC", "0" }; sprintf(line, "gsDPSetCombineLERP(%s, %s, %s, %s, %s, %s, %s, %s,\n %s, %s, %s, %s, %s, %s, %s, %s),", - modes[a0].c_str(), modes[b0].c_str(), modes[c0].c_str(), modes[d0].c_str(), - modes2[aa0].c_str(), modes2[ab0].c_str(), modes2[ac0].c_str(), modes2[ad0].c_str(), - modes[a1].c_str(), modes[b1].c_str(), modes[c1].c_str(), modes[d1].c_str(), - modes2[aa1].c_str(), modes2[ab1].c_str(), modes2[ac1].c_str(), modes2[ad1].c_str()); + modesA[a0].c_str(), modesB[b0].c_str(), modesC[c0].c_str(), modesD[d0].c_str(), + modes2[aa0].c_str(), modes2[ab0].c_str(), modes2C[ac0].c_str(), modes2[ad0].c_str(), + modesA[a1].c_str(), modesB[b1].c_str(), modesC[c1].c_str(), modesD[d1].c_str(), + modes2[aa1].c_str(), modes2[ab1].c_str(), modes2C[ac1].c_str(), modes2[ad1].c_str()); } void ZDisplayList::Opcode_G_SETPRIMCOLOR(uint64_t data, int i, std::string prefix, char* line) @@ -1420,48 +1437,241 @@ string ZDisplayList::GetSourceOutputHeader(const std::string& prefix) return ""; } +static int GfxdCallback_FormatSingleEntry(void) +{ + gfxd_puts("\t"); + gfxd_macro_dflt(); + gfxd_puts(","); + + // dont print a new line after the last command + if (gfxd_macro_id() != gfxd_SPEndDisplayList) { + gfxd_puts("\n"); + } + + return 0; +} + +static int GfxdCallback_Vtx(uint32_t seg, int32_t count) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t vtxOffset = Seg2Filespace(seg, instance->parent->baseAddress); + string vtxName = ""; + + if (!Globals::Instance->HasSegment(GETSEGNUM(seg))) // Probably an external asset we are unable to track + { + vtxName = StringHelper::Sprintf("0x%08X", seg); + } + else + { + instance->references.push_back(vtxOffset); + + // Check for vertex intersections from other display lists + // TODO: These two could probably be condenced to one... + if (instance->parent->GetDeclarationRanged(vtxOffset + (count * 16)) != nullptr) + { + Declaration* decl = instance->parent->GetDeclarationRanged(vtxOffset + (count * 16)); + uint32_t addr = instance->parent->GetDeclarationRangedAddress(vtxOffset + (count * 16)); + int diff = addr - vtxOffset; + + if (diff > 0) + count = diff / 16; + else + count = 0; + } + + if (instance->parent->GetDeclarationRanged(vtxOffset) != nullptr) + { + Declaration* decl = instance->parent->GetDeclarationRanged(vtxOffset); + uint32_t addr = instance->parent->GetDeclarationRangedAddress(vtxOffset); + int diff = addr - vtxOffset; + + if (diff > 0) + count = diff / 16; + else + count = 0; + } + + if (count > 0) + { + vector vtxList = vector(); + vtxList.reserve(count); + + uint32_t currentPtr = vtxOffset; + for (int i = 0; i < count; i++) + { + Vertex vtx = Vertex(instance->fileData, currentPtr); + vtxList.push_back(vtx); + currentPtr += 16; + } + instance->vertices[vtxOffset] = vtxList; + } + + vtxName = "@r"; + } + + gfxd_puts(vtxName.c_str()); + + return 1; +} + +static int GfxdCallback_Texture(uint32_t seg, int32_t fmt, int32_t siz, int32_t width, int32_t height, int32_t pal) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t texOffset = Seg2Filespace(seg, instance->parent->baseAddress); + uint32_t texSegNum = GETSEGNUM(seg); + Declaration* texDecl = nullptr; + string texName = ""; + + if (instance->parent != nullptr && texSegNum != 2) // HACK: Until we have declarations use segment addresses, we'll exclude scene references... + { + texDecl = instance->parent->GetDeclaration(texOffset); + + if (texDecl == nullptr) + texDecl = instance->parent->GetDeclaration(seg); + } + + if (!Globals::Instance->HasSegment(texSegNum)) // Probably an external asset we are unable to track + texName = StringHelper::Sprintf("0x%08X", seg); + else if (texDecl != nullptr) + texName = StringHelper::Sprintf("%s", texDecl->varName.c_str()); + else if (texSegNum == 2) + texName = StringHelper::Sprintf("%sTex_%06X", instance->scene->GetName().c_str(), texOffset); + else + texName = StringHelper::Sprintf("%sTex_%06X", instance->curPrefix.c_str(), texOffset); + + instance->lastTexWidth = width; + instance->lastTexHeight = height; + instance->lastTexAddr = texOffset; + instance->lastTexSeg = seg; + instance->lastTexFmt = (F3DZEXTexFormats)fmt; + instance->lastTexSiz = (F3DZEXTexSizes)siz; + instance->lastTexLoaded = true; + instance->lastTexIsPalette = false; + + instance->TextureGenCheck(instance->curPrefix); + gfxd_puts(texName.c_str()); + + return 1; +} + +static int GfxdCallback_Palette(uint32_t seg, int32_t idx, int32_t count) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t palOffset = Seg2Filespace(seg, instance->parent->baseAddress); + uint32_t palSegNum = GETSEGNUM(seg); + Declaration* palDecl = nullptr; + string palName = ""; + + if (instance->parent != nullptr && palSegNum != 2) // HACK: Until we have declarations use segment addresses, we'll exclude scene references... + { + palDecl = instance->parent->GetDeclaration(palOffset); + + if (palDecl == nullptr) + palDecl = instance->parent->GetDeclaration(seg); + } + + if (!Globals::Instance->HasSegment(palSegNum)) // Probably an external asset we are unable to track + palName = StringHelper::Sprintf("0x%08X", seg); + else if (palDecl != nullptr) + palName = StringHelper::Sprintf("%s", palDecl->varName.c_str()); + else if (palSegNum == 2) + palName = StringHelper::Sprintf("%sTex_%06X", instance->scene->GetName().c_str(), palOffset); + else + palName = StringHelper::Sprintf("%sTex_%06X", instance->curPrefix.c_str(), palOffset); + + instance->lastTexWidth = sqrt(count); + instance->lastTexHeight = sqrt(count); + instance->lastTexAddr = palOffset; + instance->lastTexSeg = seg; + instance->lastTexSiz = F3DZEXTexSizes::G_IM_SIZ_16b; + instance->lastTexFmt = F3DZEXTexFormats::G_IM_FMT_RGBA; + instance->lastTexLoaded = true; + instance->lastTexIsPalette = true; + + instance->TextureGenCheck(instance->curPrefix); + gfxd_puts(palName.c_str()); + + return 1; +} + +static int GfxdCallback_DisplayList(uint32_t seg) +{ + ZDisplayList* instance = ZDisplayList::static_instance; + uint32_t dListOffset = GETSEGOFFSET(seg); + uint32_t dListSegNum = GETSEGNUM(seg); + Declaration* dListDecl = nullptr; + string dListName = ""; + + if (instance->parent != nullptr) + dListDecl = instance->parent->GetDeclaration(dListOffset); + + if (!Globals::Instance->HasSegment(dListSegNum)) // Probably an external asset we are unable to track + dListName = StringHelper::Sprintf("0x%08X", seg); + else if (dListDecl != nullptr) + dListName = StringHelper::Sprintf("%s", dListDecl->varName.c_str()); + else + dListName = StringHelper::Sprintf("%sDL_%06X", instance->curPrefix.c_str(), dListOffset); + + if (dListSegNum <= 6) + { + ZDisplayList* newDList = new ZDisplayList(instance->fileData, dListOffset, instance->GetDListLength(instance->fileData, dListOffset, instance->dListType)); + newDList->scene = instance->scene; + newDList->parent = instance->parent; + instance->otherDLists.push_back(newDList); + } + + gfxd_puts(dListName.c_str()); + + return 1; +} + +static int GfxdCallback_Matrix(uint32_t seg) +{ + string mtxName = ""; + + if (Globals::Instance->symbolMap.find(seg) != Globals::Instance->symbolMap.end()) + mtxName = StringHelper::Sprintf("&%s", Globals::Instance->symbolMap[seg].c_str()); + else + mtxName = StringHelper::Sprintf("0x%08X", seg); + + gfxd_puts(mtxName.c_str()); + + return 1; +} + +ZDisplayList* ZDisplayList::static_instance; + string ZDisplayList::GetSourceOutputCode(const std::string& prefix) { - char line[4096]; + OutputFormatter outputformatter; string sourceOutput = ""; + int dListSize = instructions.size() * sizeof(instructions[0]); - for (int i = 0; i < instructions.size(); i++) - { - uint8_t opcode = (uint8_t)(instructions[i] >> 56); - uint64_t data = instructions[i]; - sourceOutput += " "; + gfxd_input_buffer(instructions.data(), dListSize); + gfxd_endian(gfxd_endian_little, sizeof(uint64_t)); // tell gfxdis what format the data is - auto start = chrono::steady_clock::now(); + gfxd_macro_fn(GfxdCallback_FormatSingleEntry); // format for each command entry + gfxd_vtx_callback(GfxdCallback_Vtx); // handle vertices + gfxd_timg_callback(GfxdCallback_Texture); // handle textures + gfxd_tlut_callback(GfxdCallback_Palette); // handle palettes + gfxd_dl_callback(GfxdCallback_DisplayList); // handle child display lists + gfxd_mtx_callback(GfxdCallback_Matrix); // handle matrices + gfxd_output_callback(outputformatter.static_writer()); // convert tabs to 4 spaces and enforce 120 line limit - int optimizationResult = OptimizationChecks(i, sourceOutput, prefix); + gfxd_enable(gfxd_emit_dec_color); // use decimal for colors - if (optimizationResult != -1) - { - i += optimizationResult - 1; - line[0] = '\0'; - } - else - { - if (dListType == DListType::F3DZEX) - ParseF3DZEX((F3DZEXOpcode)opcode, data, i, prefix, line); - else - ParseF3DEX((F3DEXOpcode)opcode, data, i, prefix, line); - } - - auto end = chrono::steady_clock::now(); - auto diff = chrono::duration_cast(end - start).count(); - -#if _MSC_VER - //if (diff > 5) - //printf("F3DOP: 0x%02X, TIME: %ims\n", opcode, diff); -#endif - - sourceOutput += line; - - if (i < instructions.size() - 1) - sourceOutput += "\n"; + // set microcode. see gfxd.h for more options. + if (dListType == DListType::F3DZEX) { + gfxd_target(gfxd_f3dex2); + } else { + gfxd_target(gfxd_f3dex); } + this->curPrefix = prefix; + static_instance = this; + gfxd_execute(); // generate display list + sourceOutput += outputformatter.get_output(); // write formatted display list + // Iterate through our vertex lists, connect intersecting lists. if (vertices.size() > 0) { @@ -1652,7 +1862,7 @@ void ZDisplayList::TextureGenCheck(string prefix) // HOTSPOT bool ZDisplayList::TextureGenCheck(vector fileData, map& textures, ZRoom* scene, ZFile* parent, string prefix, uint32_t texWidth, uint32_t texHeight, uint32_t texAddr, uint32_t texSeg, F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz, bool texLoaded, bool texIsPalette) { - int segmentNumber = (texSeg & 0xFF000000) >> 24; + int segmentNumber = GETSEGNUM(texSeg); if (Globals::Instance->verbosity >= VERBOSITY_DEBUG) printf("TextureGenCheck seg=%i width=%i height=%i ispal=%i addr=0x%06X\n", segmentNumber, texWidth, texHeight, texIsPalette, texAddr); @@ -1696,17 +1906,21 @@ TextureType ZDisplayList::TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSize else if (siz == F3DZEXTexSizes::G_IM_SIZ_32b) return TextureType::RGBA32bpp; } - else if (fmt == F3DZEXTexFormats::G_IM_FMT_CI) - { - //if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) - return TextureType::Palette8bpp; - } + else if (fmt == F3DZEXTexFormats::G_IM_FMT_CI) + { + if (siz == F3DZEXTexSizes::G_IM_SIZ_4b) + return TextureType::Palette4bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) + return TextureType::Palette8bpp; + } else if (fmt == F3DZEXTexFormats::G_IM_FMT_IA) { - if (siz == F3DZEXTexSizes::G_IM_SIZ_16b) - return TextureType::GrayscaleAlpha16bpp; + if (siz == F3DZEXTexSizes::G_IM_SIZ_4b) + return TextureType::Grayscale4bpp; else if (siz == F3DZEXTexSizes::G_IM_SIZ_8b) return TextureType::GrayscaleAlpha8bpp; + else if (siz == F3DZEXTexSizes::G_IM_SIZ_16b) + return TextureType::GrayscaleAlpha16bpp; } else if (fmt == F3DZEXTexFormats::G_IM_FMT_I) { diff --git a/tools/ZAPD/ZAPD/ZDisplayList.h b/tools/ZAPD/ZAPD/ZDisplayList.h index c3f7fa2aa4..66f2f4e2b5 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.h +++ b/tools/ZAPD/ZAPD/ZDisplayList.h @@ -297,12 +297,6 @@ public: class ZDisplayList : public ZResource { protected: - uint32_t lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg; - F3DZEXTexFormats lastTexFmt; - F3DZEXTexSizes lastTexSiz, lastTexSizTest, lastCISiz; - bool lastTexLoaded; - bool lastTexIsPalette; - static TextureType TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSizes siz); void ParseRawData(); @@ -341,6 +335,13 @@ public: std::string sceneSegName; ZRoom* scene; std::vector instructions; + std::string curPrefix; + + uint32_t lastTexWidth, lastTexHeight, lastTexAddr, lastTexSeg; + F3DZEXTexFormats lastTexFmt; + F3DZEXTexSizes lastTexSiz, lastTexSizTest, lastCISiz; + bool lastTexLoaded; + bool lastTexIsPalette; DListType dListType; @@ -361,6 +362,7 @@ public: ZDisplayList(); ZDisplayList(std::vector nRawData, int rawDataIndex, int rawDataSize); + static ZDisplayList* static_instance; static ZDisplayList* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, int rawDataSize, std::string nRelPath); static ZDisplayList* BuildFromXML(tinyxml2::XMLElement* reader, std::string inFolder, bool readFile); diff --git a/tools/ZAPD/ZAPD/ZFile.cpp b/tools/ZAPD/ZAPD/ZFile.cpp index 55a50668f7..5046ed1cbb 100644 --- a/tools/ZAPD/ZAPD/ZFile.cpp +++ b/tools/ZAPD/ZAPD/ZFile.cpp @@ -4,6 +4,7 @@ #include "ZRoom/ZRoom.h" #include "ZTexture.h" #include "ZAnimation.h" +#include "ZLimb.h" #include "ZSkeleton.h" #include "ZCollision.h" #include "ZScalar.h" @@ -237,10 +238,10 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b } else if (string(child->Name()) == "Limb") { - ZLimbStandard* limb = nullptr; + ZLimb* limb = nullptr; if (mode == ZFileMode::Extract) - limb = ZLimbStandard::FromXML(child, rawData, rawDataIndex, folderName, this); + limb = ZLimb::FromXML(child, rawData, rawDataIndex, folderName, this); resources.push_back(limb); @@ -977,6 +978,10 @@ string ZFile::ProcessDeclarations() // Next, output the actual declarations for (pair item : declarationKeysSorted) { + if (item.first < rangeStart || item.first >= rangeEnd) { + continue; + } + if (item.second->includePath != "") { //output += StringHelper::Sprintf("#include \"%s\"\n", item.second->includePath.c_str()); @@ -1080,6 +1085,10 @@ string ZFile::ProcessExterns() for (pair item : declarationKeysSorted) { + if (item.first < rangeStart || item.first >= rangeEnd) { + continue; + } + if (!StringHelper::StartsWith(item.second->varType, "static ") && item.second->varType != "")// && item.second->includePath == "") { if (item.second->isArray) diff --git a/tools/ZAPD/ZAPD/ZLimb.cpp b/tools/ZAPD/ZAPD/ZLimb.cpp new file mode 100644 index 0000000000..b7e63988cd --- /dev/null +++ b/tools/ZAPD/ZAPD/ZLimb.cpp @@ -0,0 +1,572 @@ +#include "ZLimb.h" +#include "BitConverter.h" +#include "StringHelper.h" +#include "Globals.h" +#include + +using namespace std; + + +Struct_800A57C0::Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset) +{ + unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00); + unk_2 = BitConverter::ToInt16BE(rawData, fileOffset + 0x02); + unk_4 = BitConverter::ToInt16BE(rawData, fileOffset + 0x04); + unk_6 = BitConverter::ToInt8BE(rawData, fileOffset + 0x06); + unk_7 = BitConverter::ToInt8BE(rawData, fileOffset + 0x07); + unk_8 = BitConverter::ToInt8BE(rawData, fileOffset + 0x08); + unk_9 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x09); +} +Struct_800A57C0::Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset, size_t index) + : Struct_800A57C0(rawData, fileOffset + index * GetRawDataSize()) +{ +} + +std::string Struct_800A57C0::GetSourceOutputCode() const +{ + return StringHelper::Sprintf("0x%02X, %i, %i, %i, %i, %i, 0x%02X", + unk_0, unk_2, unk_4, unk_6, unk_7, unk_8, unk_9); +} + +size_t Struct_800A57C0::GetRawDataSize() +{ + return 0x0A; +} + +std::string Struct_800A57C0::GetSourceTypeName() +{ + return "Struct_800A57C0"; +} + + +Struct_800A598C_2::Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset) +{ + unk_0 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x00); + x = BitConverter::ToInt16BE(rawData, fileOffset + 0x02); + y = BitConverter::ToInt16BE(rawData, fileOffset + 0x04); + z = BitConverter::ToInt16BE(rawData, fileOffset + 0x06); + unk_8 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x08); +} +Struct_800A598C_2::Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset, size_t index) + : Struct_800A598C_2(rawData, fileOffset + index * GetRawDataSize()) +{ +} + +std::string Struct_800A598C_2::GetSourceOutputCode() const +{ + return StringHelper::Sprintf("0x%02X, %i, %i, %i, 0x%02X", + unk_0, x, y, z, unk_8); +} + +size_t Struct_800A598C_2::GetRawDataSize() +{ + return 0x0A; +} + +std::string Struct_800A598C_2::GetSourceTypeName() +{ + return "Struct_800A598C_2"; +} + + +Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector& rawData, uint32_t fileOffset) + : parent(parent) +{ + unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00); + unk_2 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x02); + unk_4 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x04); + unk_8 = BitConverter::ToUInt32BE(rawData, fileOffset + 0x08); + unk_C = BitConverter::ToUInt32BE(rawData, fileOffset + 0x0C); + + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + for (size_t i = 0; i < unk_0; i++) { + unk_8_arr.emplace_back(rawData, unk_8_Offset, i); + } + } + + if (unk_C != 0) { + uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); + for (size_t i = 0; i < unk_2; i++) { + unk_C_arr.emplace_back(rawData, unk_C_Offset, i); + } + } +} +Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector& rawData, uint32_t fileOffset, size_t index) + : Struct_800A598C(parent, rawData, fileOffset + index * GetRawDataSize()) +{ +} + +void Struct_800A598C::PreGenSourceFiles(const std::string& prefix) +{ + string entryStr; + + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + string unk_8_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A57C0::GetSourceTypeName().c_str(), unk_8_Offset); + + size_t arrayItemCnt = unk_8_arr.size(); + entryStr = ""; + size_t i = 0; + for (auto& child: unk_8_arr) { + entryStr += StringHelper::Sprintf(" { %s },%s", + child.GetSourceOutputCode().c_str(), + (++i < arrayItemCnt) ? "\n" : ""); + } + + Declaration* decl = parent->GetDeclaration(unk_8_Offset); + if (decl == nullptr) { + parent->AddDeclarationArray( + unk_8_Offset, DeclarationAlignment::None, + arrayItemCnt * Struct_800A57C0::GetRawDataSize(), Struct_800A57C0::GetSourceTypeName(), + unk_8_Str, arrayItemCnt, entryStr); + } + else { + decl->text = entryStr; + } + } + + if (unk_C != 0) { + uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress); + string unk_C_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A598C_2::GetSourceTypeName().c_str(), unk_C_Offset); + + size_t arrayItemCnt = unk_C_arr.size(); + entryStr = ""; + size_t i = 0; + for (auto& child: unk_C_arr) { + entryStr += StringHelper::Sprintf(" { %s },%s", + child.GetSourceOutputCode().c_str(), + (++i < arrayItemCnt) ? "\n" : ""); + } + + Declaration* decl = parent->GetDeclaration(unk_C_Offset); + if (decl == nullptr) { + parent->AddDeclarationArray( + unk_C_Offset, DeclarationAlignment::None, + arrayItemCnt * Struct_800A598C_2::GetRawDataSize(), Struct_800A598C_2::GetSourceTypeName(), + unk_C_Str, arrayItemCnt, entryStr); + } + else { + decl->text = entryStr; + } + } +} + +std::string Struct_800A598C::GetSourceOutputCode(const std::string& prefix) const +{ + string entryStr; + + 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); + } + + 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()); + + return entryStr; +} + +size_t Struct_800A598C::GetRawDataSize() +{ + return 0x10; +} + +std::string Struct_800A598C::GetSourceTypeName() +{ + return "Struct_800A598C"; +} + + +Struct_800A5E28::Struct_800A5E28(ZFile* parent, const std::vector& nRawData, uint32_t fileOffset) + : parent(parent), rawData(nRawData) +{ + 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(ZFile* parent, const std::vector& rawData, uint32_t fileOffset, size_t index) + : Struct_800A5E28(parent, rawData, fileOffset + index * GetRawDataSize()) +{ +} + +Struct_800A5E28::~Struct_800A5E28() +{ + delete unk_8_dlist; +} + +void Struct_800A5E28::PreGenSourceFiles(const std::string& prefix) +{ + if (unk_4 != 0) { + uint32_t unk_4_Offset = Seg2Filespace(unk_4, parent->baseAddress); + string unk_4_Str = StringHelper::Sprintf("%sSkinLimb_%s_%06X", prefix.c_str(), Struct_800A598C::GetSourceTypeName().c_str(), unk_4_Offset); + + string entryStr = ""; + uint16_t arrayItemCnt = unk_4_arr.size(); + + size_t i = 0; + for (auto& child: unk_4_arr) { + child.PreGenSourceFiles(prefix); + + entryStr += StringHelper::Sprintf(" { %s },%s", + child.GetSourceOutputCode(prefix).c_str(), + (++i < arrayItemCnt) ? "\n" : ""); + } + + Declaration* decl = parent->GetDeclaration(unk_4_Offset); + if (decl == nullptr) { + parent->AddDeclarationArray( + unk_4_Offset, DeclarationAlignment::None, + arrayItemCnt * Struct_800A598C::GetRawDataSize(), Struct_800A598C::GetSourceTypeName(), + unk_4_Str, arrayItemCnt, entryStr); + } + else { + decl->text = entryStr; + } + } + + if (unk_8 != 0) { + uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); + + int dlistLength = ZDisplayList::GetDListLength(rawData, unk_8_Offset, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + unk_8_dlist = new ZDisplayList(rawData, unk_8_Offset, dlistLength); + unk_8_dlist->parent = parent; + + 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 +{ + string entryStr = ""; + + 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; + } + } + + 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(tinyxml2::XMLElement* reader, const std::vector& nRawData, int nRawDataIndex, ZFile* nParent) +{ + rawData.assign(nRawData.begin(), nRawData.end()); + rawDataIndex = nRawDataIndex; + parent = nParent; + + segAddress = nRawDataIndex; + + ParseXML(reader); + ParseRawData(); + + if (type == ZLimbType::Skin) { + if (skinSegmentType == ZLimbSkinType::SkinType_4 && skinSegment != 0) { + uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress); + segmentStruct = Struct_800A5E28(parent, rawData, skinSegmentOffset); + } + } +} + +ZLimb::ZLimb(ZLimbType limbType, const std::string& prefix, const std::vector& nRawData, int nRawDataIndex, ZFile* nParent) +{ + rawData.assign(nRawData.begin(), nRawData.end()); + rawDataIndex = nRawDataIndex; + parent = nParent; + type = limbType; + + segAddress = nRawDataIndex; + name = StringHelper::Sprintf("%sLimb_%06X", prefix.c_str(), GetFileAddress()); + + ParseRawData(); +} + +void ZLimb::ParseXML(tinyxml2::XMLElement* reader) +{ + ZResource::ParseXML(reader); + + // Reading from a + const char* limbType = reader->Attribute("LimbType"); + if (limbType == nullptr) { + // Reading from a + limbType = reader->Attribute("Type"); + } + + if (limbType == nullptr) { + fprintf(stderr, "ZLimb::ParseXML: Warning in '%s'.\n\t Missing 'LimbType' attribute in xml. Defaulting to 'Standard'.\n", name.c_str()); + type = ZLimbType::Standard; + } + else { + string limbTypeStr(limbType); + if (limbTypeStr == "Standard") { + type = ZLimbType::Standard; + } + else if(limbTypeStr == "LOD") { + type = ZLimbType::LOD; + } + else if(limbTypeStr == "Skin") { + type = ZLimbType::Skin; + } + else { + fprintf(stderr, "ZLimb::ParseXML: Warning in '%s'.\n\t Invalid LimbType found: '%s'. Defaulting to 'Standard'.\n", name.c_str(), limbType); + type = ZLimbType::Standard; + } + } +} + +void ZLimb::ParseRawData() +{ + transX = BitConverter::ToInt16BE(rawData, rawDataIndex + 0); + transY = BitConverter::ToInt16BE(rawData, rawDataIndex + 2); + transZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 4); + + childIndex = rawData.at(rawDataIndex + 6); + siblingIndex = rawData.at(rawDataIndex + 7); + + switch (type) { + case ZLimbType::LOD: + farDListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12); + case ZLimbType::Standard: + dListPtr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); + break; + case ZLimbType::Skin: + skinSegmentType = static_cast(BitConverter::ToInt32BE(rawData, rawDataIndex + 8)); + skinSegment = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12); + break; + } +} + +ZLimb* ZLimb::FromXML(tinyxml2::XMLElement* reader, vector nRawData, int rawDataIndex, string nRelPath, ZFile* parent) +{ + ZLimb* limb = new ZLimb(reader, nRawData, rawDataIndex, parent); + limb->relativePath = std::move(nRelPath); + + limb->parent->AddDeclaration( + limb->GetFileAddress(), DeclarationAlignment::None, limb->GetRawDataSize(), + limb->GetSourceTypeName(), limb->name, ""); + + return limb; +} + + +int ZLimb::GetRawDataSize() +{ + switch (type) { + case ZLimbType::Standard: + return 0x0C; + case ZLimbType::LOD: + case ZLimbType::Skin: + return 0x10; + } + return 0x0C; +} + +string ZLimb::GetSourceOutputCode(const std::string& prefix) +{ + string dListStr = "NULL"; + string dListStr2 = "NULL"; + + if (dListPtr != 0) { + dListStr = GetLimbDListSourceOutputCode(prefix, "", dListPtr); + } + if (farDListPtr != 0) { + dListStr2 = GetLimbDListSourceOutputCode(prefix, "Far", farDListPtr); + } + + string entryStr = StringHelper::Sprintf("\n { %i, %i, %i },\n 0x%02X, 0x%02X,\n", + transX, transY, transZ, childIndex, siblingIndex); + + switch (type) { + case ZLimbType::Standard: + entryStr += StringHelper::Sprintf(" %s\n", dListStr.c_str()); + break; + case ZLimbType::LOD: + entryStr += StringHelper::Sprintf(" { %s, %s }\n", + dListStr.c_str(), dListStr2.c_str()); + break; + case ZLimbType::Skin: + entryStr += GetSourceOutputCodeSkin(prefix); + break; + } + + Declaration* decl = parent->GetDeclaration(GetFileAddress()); + if (decl == nullptr) { + parent->AddDeclaration(GetFileAddress(), DeclarationAlignment::None, GetRawDataSize(), GetSourceTypeName(), name, entryStr); + } + else { + decl->text = entryStr; + } + + return ""; +} + +std::string ZLimb::GetSourceTypeName() +{ + return GetSourceTypeName(type); +} + +ZResourceType ZLimb::GetResourceType() +{ + return ZResourceType::Limb; +} + +ZLimbType ZLimb::GetLimbType() +{ + return type; +} + +const char* ZLimb::GetSourceTypeName(ZLimbType limbType) +{ + switch (limbType) { + case ZLimbType::Standard: + return "StandardLimb"; + case ZLimbType::LOD: + return "LodLimb"; + case ZLimbType::Skin: + return "SkinLimb"; + } + return "StandardLimb"; +} + +uint32_t ZLimb::GetFileAddress() +{ + return Seg2Filespace(segAddress, parent->baseAddress); +} + +std::string ZLimb::GetLimbDListSourceOutputCode(const std::string& prefix, const std::string& limbPrefix, segptr_t dListPtr) +{ + if (dListPtr == 0) { + return "NULL"; + } + + uint32_t dListOffset = Seg2Filespace(dListPtr, parent->baseAddress); + + string dListStr; + Declaration* decl = parent->GetDeclaration(dListOffset); + if (decl == nullptr) { + dListStr = StringHelper::Sprintf("%s%sLimbDL_%06X", prefix.c_str(), limbPrefix.c_str(), dListOffset); + + int dlistLength = ZDisplayList::GetDListLength(rawData, dListOffset, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + auto& dList = dLists.emplace_back(rawData, dListOffset, dlistLength); + dList.parent = parent; + dList.SetName(dListStr); + dList.GetSourceOutputCode(prefix); + } + else { + dListStr = decl->varName; + } + + return dListStr; +} + +std::string ZLimb::GetSourceOutputCodeSkin_Type_4(const std::string& prefix) +{ + assert(type == ZLimbType::Skin); + assert(skinSegmentType == ZLimbSkinType::SkinType_4); + + if (skinSegment == 0) { + return "NULL"; + } + + uint32_t skinSegmentOffset = Seg2Filespace(skinSegment, parent->baseAddress); + + 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.PreGenSourceFiles(prefix); + string entryStr = segmentStruct.GetSourceOutputCode(prefix); + + parent->AddDeclaration( + skinSegmentOffset, DeclarationAlignment::None, + Struct_800A5E28::GetRawDataSize(), Struct_800A5E28::GetSourceTypeName(), + struct_800A5E28_Str, entryStr); + } + else { + struct_800A5E28_Str = decl->varName; + } + + return struct_800A5E28_Str; +} + +std::string ZLimb::GetSourceOutputCodeSkin(const std::string& prefix) +{ + assert(type == ZLimbType::Skin); + + string skinSegmentStr = "NULL"; + + if (skinSegment != 0) { + switch (skinSegmentType) { + case ZLimbSkinType::SkinType_4: + skinSegmentStr = "&" + GetSourceOutputCodeSkin_Type_4(prefix); + break; + case ZLimbSkinType::SkinType_DList: + skinSegmentStr = GetLimbDListSourceOutputCode(prefix, "Skin", skinSegment); + break; + default: + fprintf(stderr, "ZLimb::GetSourceOutputCodeSkinType: Error in '%s'.\n\t Unknown segment type for SkinLimb: '%i'. \n\tPlease report this.\n", name.c_str(), static_cast(skinSegmentType)); + case ZLimbSkinType::SkinType_0: + case ZLimbSkinType::SkinType_5: + fprintf(stderr, "ZLimb::GetSourceOutputCodeSkinType: Error in '%s'.\n\t Segment type for SkinLimb not implemented: '%i'.\n", name.c_str(), static_cast(skinSegmentType)); + skinSegmentStr = StringHelper::Sprintf("0x%08X", skinSegment); + break; + } + } + + string entryStr = StringHelper::Sprintf(" 0x%02X, %s\n", + skinSegmentType, skinSegmentStr.c_str()); + + return entryStr; +} diff --git a/tools/ZAPD/ZAPD/ZLimb.h b/tools/ZAPD/ZAPD/ZLimb.h new file mode 100644 index 0000000000..cc5e9065d8 --- /dev/null +++ b/tools/ZAPD/ZAPD/ZLimb.h @@ -0,0 +1,166 @@ +#pragma once + +#include +#include +#include +#include "ZFile.h" +#include "ZDisplayList.h" + + +enum class ZLimbType +{ + Standard, + LOD, + Skin +}; + +// TODO: check if more types exists +enum class ZLimbSkinType +{ + SkinType_0, // Segment = 0 + SkinType_4 = 4, // Segment = segmented address // Struct_800A5E28 + SkinType_5 = 5, // Segment = 0 + SkinType_DList = 11, // Segment = DList address +}; + + +class Struct_800A57C0 +{ +protected: + uint16_t unk_0; + int16_t unk_2; + int16_t unk_4; + int8_t unk_6; + int8_t unk_7; + int8_t unk_8; + uint8_t unk_9; + +public: + Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset); + Struct_800A57C0(const std::vector& rawData, uint32_t fileOffset, size_t index); + + [[nodiscard]] + std::string GetSourceOutputCode() const; + + static size_t GetRawDataSize(); + static std::string GetSourceTypeName(); +}; + + +class Struct_800A598C_2 +{ +protected: + uint8_t unk_0; + int16_t x; + int16_t y; + int16_t z; + uint8_t unk_8; + +public: + Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset); + Struct_800A598C_2(const std::vector& rawData, uint32_t fileOffset, size_t index); + + [[nodiscard]] + std::string GetSourceOutputCode() const; + + static size_t GetRawDataSize(); + static std::string GetSourceTypeName(); +}; + + +class Struct_800A598C +{ +protected: + ZFile* parent; + + uint16_t unk_0; // Length of unk_8 + uint16_t unk_2; // Length of unk_C + uint16_t unk_4; // 0 or 1 // Used as an index for unk_C + segptr_t unk_8; // Struct_800A57C0* + segptr_t unk_C; // Struct_800A598C_2* + + std::vector unk_8_arr; + std::vector unk_C_arr; + +public: + Struct_800A598C(ZFile* parent, const std::vector& rawData, uint32_t fileOffset); + Struct_800A598C(ZFile* parent, const std::vector& rawData, uint32_t fileOffset, size_t index); + + void PreGenSourceFiles(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; + std::vector rawData; + + uint16_t unk_0; // Vtx count + uint16_t unk_2; // Length of unk_4 + segptr_t unk_4; // Struct_800A598C* + segptr_t unk_8; // Gfx* + + std::vector unk_4_arr; + ZDisplayList* unk_8_dlist = nullptr; + +public: + Struct_800A5E28() = default; + Struct_800A5E28(ZFile* parent, const std::vector& rawData, uint32_t fileOffset); + Struct_800A5E28(ZFile* parent, const std::vector& rawData, uint32_t fileOffset, size_t index); + ~Struct_800A5E28(); + + void PreGenSourceFiles(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: + segptr_t segAddress; + ZLimbType type = ZLimbType::Standard; + + int16_t transX, transY, transZ; + uint8_t childIndex, siblingIndex; + segptr_t dListPtr = 0; + + std::vector dLists; + + segptr_t farDListPtr = 0; // LOD only + + ZLimbSkinType skinSegmentType = ZLimbSkinType::SkinType_0; // Skin only + segptr_t skinSegment = 0; // Skin only + Struct_800A5E28 segmentStruct; // Skin only + + 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: + ZLimb(tinyxml2::XMLElement* reader, const std::vector& nRawData, int nRawDataIndex, ZFile* nParent); + ZLimb(ZLimbType limbType, const std::string& prefix, const std::vector& nRawData, int nRawDataIndex, ZFile* nParent); + + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; + static ZLimb* FromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); + int GetRawDataSize() override; + std::string GetSourceOutputCode(const std::string& prefix) override; + std::string GetSourceTypeName() override; + ZResourceType GetResourceType() override; + + ZLimbType GetLimbType(); + static const char* GetSourceTypeName(ZLimbType limbType); + + uint32_t GetFileAddress(); +}; diff --git a/tools/ZAPD/ZAPD/ZResource.cpp b/tools/ZAPD/ZAPD/ZResource.cpp index 3c7684c9eb..f906c7a794 100644 --- a/tools/ZAPD/ZAPD/ZResource.cpp +++ b/tools/ZAPD/ZAPD/ZResource.cpp @@ -124,3 +124,14 @@ void ZResource::CalcHash() { hash = 0; } + + +uint32_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress) +{ + uint32_t currentPtr = GETSEGOFFSET(segmentedAddress); + + if (GETSEGNUM(segmentedAddress) == 0x80) // Is defined in code? + currentPtr -= GETSEGOFFSET(parentBaseAddress); + + return currentPtr; +} diff --git a/tools/ZAPD/ZAPD/ZResource.h b/tools/ZAPD/ZAPD/ZResource.h index 02921969fd..b34ccdcd22 100644 --- a/tools/ZAPD/ZAPD/ZResource.h +++ b/tools/ZAPD/ZAPD/ZResource.h @@ -13,7 +13,7 @@ #define SEGMENT_OBJECT 6 #define SEGMENT_LINKANIMETION 7 -#define SEG2FILESPACE(x) (x & 0x00FFFFFF) +#define GETSEGOFFSET(x) (x & 0x00FFFFFF) #define GETSEGNUM(x) ((x >> 24) & 0xFF) typedef uint32_t segptr_t; @@ -125,3 +125,6 @@ public: protected: Declaration(DeclarationAlignment nAlignment, DeclarationPadding nPadding, uint32_t nSize, std::string nText); }; + + +uint32_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress); diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp index 35c2af5c79..30ed52e072 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetActorList.cpp @@ -11,7 +11,7 @@ using namespace std; SetActorList::SetActorList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) { numActors = rawData[rawDataIndex + 1]; - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); _rawData = rawData; _rawDataIndex = rawDataIndex; @@ -68,7 +68,7 @@ string SetActorList::GenerateSourceCodePass2(string roomName, int baseAddress) // SW97 Actor 0x22 was removed, so we want to not output a working actor. if (actorNum == 0x22 && Globals::Instance->game == ZGame::OOT_SW97) - declaration += StringHelper::Sprintf("\t//{ %s, %i, %i, %i, %i, %i, %i, 0x%04X }, //0x%06X", StringHelper::Sprintf("SW_REMOVED_0x%04X", actorNum), entry->posX, entry->posY, entry->posZ, entry->rotX, entry->rotY, entry->rotZ, (uint16_t)entry->initVar, segmentOffset + (index * 16)); + declaration += StringHelper::Sprintf("\t//{ %s, %i, %i, %i, %i, %i, %i, 0x%04X }, //0x%06X", /*StringHelper::Sprintf("SW_REMOVED_0x%04X", actorNum).c_str()*/ "ACTOR_DUNGEON_KEEP", entry->posX, entry->posY, entry->posZ, entry->rotX, entry->rotY, entry->rotZ, (uint16_t)entry->initVar, segmentOffset + (index * 16)); else { // SW97 Actor 0x23 and above are shifted up by one because 0x22 was removed between SW97 and retail. diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp index 767a9a9fd2..894a37c760 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetAlternateHeaders.cpp @@ -7,7 +7,7 @@ using namespace std; SetAlternateHeaders::SetAlternateHeaders(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) { - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); if (segmentOffset != 0) zRoom->parent->AddDeclarationPlaceholder(segmentOffset); diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp index 7141abf960..7f037086f3 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetCollisionHeader.cpp @@ -8,7 +8,7 @@ using namespace std; SetCollisionHeader::SetCollisionHeader(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) { - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); collisionHeader = ZCollisionHeader(nZRoom->parent, StringHelper::Sprintf("%sCollisionHeader0x%06X", nZRoom->GetName().c_str(), segmentOffset), rawData, segmentOffset); } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp index edb66f34ec..89c7ddb08f 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetExitList.cpp @@ -8,7 +8,7 @@ using namespace std; SetExitList::SetExitList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) { - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); exits = vector(); if (segmentOffset != 0) diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp index d7be8c9ec1..5f8d4d4145 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetLightingSettings.cpp @@ -9,7 +9,7 @@ using namespace std; SetLightingSettings::SetLightingSettings(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) { uint8_t numLights = rawData[rawDataIndex + 1]; - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); for (int i = 0; i < numLights; i++) settings.push_back(new LightingSettings(rawData, segmentOffset + (i * 22))); diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp index 7b1c6cbc1f..50baed3d72 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp @@ -11,7 +11,7 @@ using namespace std; SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, int segAddressOffset) : ZRoomCommand(nZRoom, rawData, rawDataIndex) { data = rawData[rawDataIndex + 1]; - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); string declaration = ""; int8_t meshHeaderType = rawData[segmentOffset + 0]; @@ -22,8 +22,8 @@ SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, meshHeader0->headerType = 0; meshHeader0->entries = vector(); - meshHeader0->dListStart = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, segmentOffset + 4)); - meshHeader0->dListEnd = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, segmentOffset + 8)); + meshHeader0->dListStart = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, segmentOffset + 4)); + meshHeader0->dListEnd = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, segmentOffset + 8)); int8_t numEntries = rawData[segmentOffset + 1]; uint32_t currentPtr = meshHeader0->dListStart; @@ -38,8 +38,8 @@ SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, for (int i = 0; i < numEntries; i++) { MeshEntry0* entry = new MeshEntry0(); - entry->opaqueDListAddr = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, currentPtr + 0)); - entry->translucentDListAddr = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, currentPtr + 4)); + entry->opaqueDListAddr = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, currentPtr + 0)); + entry->translucentDListAddr = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, currentPtr + 4)); if (entry->opaqueDListAddr != 0) { @@ -82,12 +82,12 @@ SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, for (int i = 0; i < meshHeader0->entries.size(); i++) { if (meshHeader0->entries[i]->opaqueDListAddr != 0) - declaration += StringHelper::Sprintf("\t{ (u32)%sDlist0x%06X, ", zRoom->GetName().c_str(), meshHeader0->entries[i]->opaqueDListAddr); + declaration += StringHelper::Sprintf("\t{ (u32)%sDL_%06X, ", zRoom->GetName().c_str(), meshHeader0->entries[i]->opaqueDListAddr); else declaration += "\t{ 0, "; if (meshHeader0->entries[i]->translucentDListAddr != 0) - declaration += StringHelper::Sprintf("(u32)%sDlist0x%06X },\n", zRoom->GetName().c_str(), meshHeader0->entries[i]->translucentDListAddr); + declaration += StringHelper::Sprintf("(u32)%sDL_%06X },\n", zRoom->GetName().c_str(), meshHeader0->entries[i]->translucentDListAddr); else declaration += "0 },\n"; } @@ -134,7 +134,7 @@ SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, StringHelper::Sprintf("%sMeshHeader0x%06X", zRoom->GetName().c_str(), segmentOffset), declaration); meshHeader1 = headerSingle; -; } + } else if (fmt == 2) // Multi-Format { MeshHeader1Multi* headerMulti = new MeshHeader1Multi(); @@ -173,8 +173,8 @@ SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, meshHeader2->headerType = 2; meshHeader2->entries = vector(); - meshHeader2->dListStart = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, segmentOffset + 4)); - meshHeader2->dListEnd = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, segmentOffset + 8)); + meshHeader2->dListStart = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, segmentOffset + 4)); + meshHeader2->dListEnd = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, segmentOffset + 8)); int8_t numEntries = rawData[segmentOffset + 1]; uint32_t currentPtr = meshHeader2->dListStart; @@ -234,12 +234,12 @@ SetMesh::SetMesh(ZRoom* nZRoom, std::vector rawData, int rawDataIndex, declaration += StringHelper::Sprintf("\t{ %i, %i, %i, %i, ", meshHeader2->entries[i]->playerXMax, meshHeader2->entries[i]->playerZMax, meshHeader2->entries[i]->playerXMin, meshHeader2->entries[i]->playerZMin); if (meshHeader2->entries[i]->opaqueDListAddr != 0) - declaration += StringHelper::Sprintf("(u32)%sDlist0x%06X, ", zRoom->GetName().c_str(), meshHeader2->entries[i]->opaqueDListAddr); + declaration += StringHelper::Sprintf("(u32)%sDL_%06X, ", zRoom->GetName().c_str(), meshHeader2->entries[i]->opaqueDListAddr); else declaration += "0, "; if (meshHeader2->entries[i]->translucentDListAddr != 0) - declaration += StringHelper::Sprintf("(u32)%sDlist0x%06X },\n", zRoom->GetName().c_str(), meshHeader2->entries[i]->translucentDListAddr); + declaration += StringHelper::Sprintf("(u32)%sDL_%06X },\n", zRoom->GetName().c_str(), meshHeader2->entries[i]->translucentDListAddr); else declaration += "0 },\n"; } @@ -306,9 +306,9 @@ std::string SetMesh::GenDListExterns(ZDisplayList* dList) string sourceOutput = ""; if (Globals::Instance->includeFilePrefix) - sourceOutput += StringHelper::Sprintf("extern Gfx %sDlist0x%06X[];\n", zRoom->GetName().c_str(), dList->GetRawDataIndex()); + sourceOutput += StringHelper::Sprintf("extern Gfx %sDL_%06X[];\n", zRoom->GetName().c_str(), dList->GetRawDataIndex()); else - sourceOutput += StringHelper::Sprintf("extern Gfx dlist0x%06X[];\n", dList->GetRawDataIndex()); + sourceOutput += StringHelper::Sprintf("extern Gfx DL_%06X[];\n", dList->GetRawDataIndex()); for (ZDisplayList* otherDList : dList->otherDLists) sourceOutput += GenDListExterns(otherDList); diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp index bec341fab9..e91b0e98e1 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetObjectList.cpp @@ -11,7 +11,7 @@ SetObjectList::SetObjectList(ZRoom* nZRoom, std::vector rawData, int ra { objects = vector(); uint8_t objectCnt = rawData[rawDataIndex + 1]; - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); uint32_t currentPtr = segmentOffset; for (int i = 0; i < objectCnt; i++) diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp index 08f745dd1c..6795d99e92 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetPathways.cpp @@ -14,7 +14,7 @@ SetPathways::SetPathways(ZRoom* nZRoom, std::vector rawData, int rawDat segmentOffset = 0; listSegmentOffset = 0; - InitList(SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4))); + InitList(GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4))); uint32_t currentPtr = listSegmentOffset; @@ -31,7 +31,7 @@ SetPathways::~SetPathways() void SetPathways::InitList(uint32_t address) { segmentOffset = address; - listSegmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(_rawData, address + 4)); + listSegmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(_rawData, address + 4)); numPoints = _rawData[address + 0]; } diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp index 0bdd67ef52..e16373f546 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetStartPositionList.cpp @@ -10,7 +10,7 @@ using namespace std; SetStartPositionList::SetStartPositionList(ZRoom* nZRoom, std::vector rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex) { int numActors = rawData[rawDataIndex + 1]; - segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); + segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4)); if (segmentOffset != 0) zRoom->parent->AddDeclarationPlaceholder(segmentOffset); diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp index aa9472328a..b8ea40b029 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp @@ -225,10 +225,8 @@ void ZRoom::ParseCommands(std::vector& commandList, CommandSet co { bool shouldContinue = true; int currentIndex = 0; - int rawDataIndex = commandSet.address; - int8_t segmentNumber = rawDataIndex >> 24; + int rawDataIndex = commandSet.address & 0x00FFFFFF; - rawDataIndex &= 0x00FFFFFF; int32_t commandsLeft = commandSet.commandCount; while (shouldContinue) @@ -305,7 +303,6 @@ void ZRoom::ProcessCommandSets() std::vector setCommands = std::vector(); int32_t commandSet = commandSets[0].address; - int8_t segmentNumber = commandSet >> 24; ParseCommands(setCommands, commandSets[0]); commandSets.erase(commandSets.begin()); diff --git a/tools/ZAPD/ZAPD/ZSkeleton.cpp b/tools/ZAPD/ZAPD/ZSkeleton.cpp index 485c5a7274..37d9f46ff1 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.cpp +++ b/tools/ZAPD/ZAPD/ZSkeleton.cpp @@ -1,89 +1,108 @@ #include "ZSkeleton.h" #include "BitConverter.h" #include "StringHelper.h" -#include "Globals.h" #include "HighLevel/HLModelIntermediette.h" -#include using namespace std; -using namespace tinyxml2; -ZLimbStandard::ZLimbStandard() + +ZSkeleton::ZSkeleton(tinyxml2::XMLElement* reader, const std::vector& nRawData, int nRawDataIndex, ZFile* nParent) { - name = ""; - transX = 0; - transY = 0; - transZ = 0; - childIndex = 0; - siblingIndex = 0; - dListPtr = 0; - children = vector(); + rawData.assign(nRawData.begin(), nRawData.end()); + rawDataIndex = nRawDataIndex; + parent = nParent; + + ParseXML(reader); + ParseRawData(); + + string defaultPrefix = name; + defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables + uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); + + for (size_t i = 0; i < limbCount; i++) { + uint32_t ptr2 = Seg2Filespace(BitConverter::ToUInt32BE(rawData, ptr), parent->baseAddress); + + ZLimb* limb = new ZLimb(reader, rawData, ptr2, parent); + limb->SetName(StringHelper::Sprintf("%sLimb_%06X", defaultPrefix.c_str(), limb->GetFileAddress())); + limbs.push_back(limb); + + ptr += 4; + } } -ZLimbStandard* ZLimbStandard::FromXML(XMLElement* reader, vector nRawData, int rawDataIndex, string nRelPath, ZFile* parent) +ZSkeleton::~ZSkeleton() { - ZLimbType limbType = ZLimbType::Standard; - string limbName = reader->Attribute("Name"); - int limbAddress = strtol(StringHelper::Split(reader->Attribute("Offset"), "0x")[1].c_str(), NULL, 16); - - if (string(reader->Attribute("Type")) == "LOD") - limbType = ZLimbType::LOD; - - ZLimbStandard* limb = ZLimbStandard::FromRawData(nRawData, rawDataIndex); - limb->ParseXML(reader); - limb->parent = parent; - limb->name = limbName; - limb->address = limbAddress; - - string entryType = limbType == ZLimbType::LOD ? "LodLimb" : "StandardLimb"; - - limb->parent->AddDeclaration(limb->address, DeclarationAlignment::None, 12, entryType, StringHelper::Sprintf("%s", limbName.c_str(), limb->address), ""); - - return limb; + for (auto& limb: limbs) { + delete limb; + } } -ZLimbStandard* ZLimbStandard::FromRawData(std::vector nRawData, int rawDataIndex) +void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) { - ZLimbStandard* limb = new ZLimbStandard(); + ZResource::ParseXML(reader); - limb->address = rawDataIndex; + const char* skelTypeXml = reader->Attribute("Type"); + if (skelTypeXml == nullptr) { + fprintf(stderr, "ZSkeleton::ParseXML: Warning in '%s'.\n\t Type not found found. Defaulting to 'Normal'.\n", name.c_str()); + type = ZSkeletonType::Normal; + } + else { + string skelTypeStr(skelTypeXml); + if (skelTypeStr == "Flex") { + type = ZSkeletonType::Flex; + } + else if (skelTypeStr != "Normal") { + fprintf(stderr, "ZSkeleton::ParseXML: Warning in '%s'.\n\t Invalid Type found: '%s'. Defaulting to 'Normal'.\n", name.c_str(), skelTypeXml); + type = ZSkeletonType::Normal; + } + } - limb->transX = BitConverter::ToInt16BE(nRawData, rawDataIndex + 0); - limb->transY = BitConverter::ToInt16BE(nRawData, rawDataIndex + 2); - limb->transZ = BitConverter::ToInt16BE(nRawData, rawDataIndex + 4); - - limb->childIndex = nRawData[rawDataIndex + 6]; - limb->siblingIndex = nRawData[rawDataIndex + 7]; - - limb->dListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 8) & 0x00FFFFFF; - - return limb; + const char* limbTypeXml = reader->Attribute("LimbType"); + if (limbTypeXml == nullptr) { + fprintf(stderr, "ZSkeleton::ParseXML: Warning in '%s'.\n\t LimbType not found found. Defaulting to 'Standard'.\n", name.c_str()); + limbType = ZLimbType::Standard; + } + else { + string limbTypeStr(limbTypeXml); + if (limbTypeStr == "Standard") { + limbType = ZLimbType::Standard; + } + else if (limbTypeStr == "LOD") { + limbType = ZLimbType::LOD; + } + else if (limbTypeStr == "Skin") { + limbType = ZLimbType::Skin; + } + else { + fprintf(stderr, "ZSkeleton::ParseXML: Warning in '%s'.\n\t Invalid LimbType found: '%s'. Defaulting to 'Standard'.\n", name.c_str(), limbTypeXml); + limbType = ZLimbType::Standard; + } + } } -string ZLimbStandard::GetSourceOutputCode(const std::string& prefix) +void ZSkeleton::ParseRawData() { - string dListStr = dListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetVarName(dListPtr).c_str()); + ZResource::ParseRawData(); - string entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, %s", - transX, transY, transZ, childIndex, siblingIndex, dListStr.c_str()); - - Declaration* decl = parent->GetDeclaration(address); - decl->text = entryStr; - - return ""; + limbsArrayAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex); + limbCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4); + dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8); } -int ZLimbStandard::GetRawDataSize() +ZSkeleton* ZSkeleton::FromXML(tinyxml2::XMLElement* reader, vector nRawData, int rawDataIndex, string nRelPath, ZFile* nParent) { - return 12; + ZSkeleton* skeleton = new ZSkeleton(reader, nRawData, rawDataIndex, nParent); + skeleton->relativePath = std::move(nRelPath); + + skeleton->parent->AddDeclaration( + skeleton->rawDataIndex, DeclarationAlignment::Align16, skeleton->GetRawDataSize(), + skeleton->GetSourceTypeName(), skeleton->name, ""); + + return skeleton; } -ZSkeleton::ZSkeleton() : ZResource() +void ZSkeleton::Save(const std::string& outFolder) { - type = ZSkeletonType::Normal; - limbs = vector(); - rootLimb = nullptr; - dListCount = 0; } void ZSkeleton::GenerateHLIntermediette(HLFileIntermediette& hlFile) @@ -93,176 +112,85 @@ void ZSkeleton::GenerateHLIntermediette(HLFileIntermediette& hlFile) //mdl->blocks.push_back(new HLTerminator()); } -ZSkeleton* ZSkeleton::FromXML(XMLElement* reader, vector nRawData, int rawDataIndex, string nRelPath, ZFile* nParent) +int ZSkeleton::GetRawDataSize() { - ZSkeleton* skeleton = new ZSkeleton(); - skeleton->name = reader->Attribute("Name"); - skeleton->parent = nParent; - ZLimbType limbType = ZLimbType::Standard; - ZSkeletonType skeletonType = ZSkeletonType::Normal; - int limbCount = 0; - - skeleton->rawData = nRawData; - skeleton->rawDataIndex = rawDataIndex; - - if (reader->Attribute("Type") != nullptr) - { - if (string(reader->Attribute("Type")) == "Flex") - skeletonType = ZSkeletonType::Flex; - else if (string(reader->Attribute("Type")) == "Skin") - skeletonType = ZSkeletonType::Skin; - else if (string(reader->Attribute("Type")) != "Normal") - { - // TODO: Print some error here... - } + switch (type) { + case ZSkeletonType::Normal: + return 0x8; + case ZSkeletonType::Flex: + return 0xC; + default: + return 0x8; } - - skeleton->type = skeletonType; - - if (reader->Attribute("LimbType") != nullptr) - { - //printf("C3\n"); - - if (string(reader->Attribute("LimbType")) == "LOD") - limbType = ZLimbType::LOD; - } - - limbCount = nRawData[rawDataIndex + 4]; - skeleton->dListCount = nRawData[rawDataIndex + 8]; - - ZLimbStandard* currentLimb = nullptr; - - uint32_t ptr = (uint32_t)BitConverter::ToInt32BE(nRawData, rawDataIndex) & 0x00FFFFFF; - - for (int i = 0; i < limbCount; i++) - { - uint32_t ptr2 = (uint32_t)BitConverter::ToInt32BE(nRawData, ptr) & 0x00FFFFFF; - - if (limbType == ZLimbType::Standard) - { - ZLimbStandard* limb = ZLimbStandard::FromRawData(nRawData, ptr2); - skeleton->limbs.push_back(limb); - } - else - { - ZLimbLOD* limb = ZLimbLOD::FromRawData(nRawData, ptr2); - skeleton->limbs.push_back(limb); - } - - ptr += 4; - } - - return skeleton; } std::string ZSkeleton::GetSourceOutputCode(const std::string& prefix) { - if (parent != nullptr) + if (parent == nullptr) { + return ""; + } + + string defaultPrefix = name.c_str(); + defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables + + for (auto& limb: limbs) { + limb->GetSourceOutputCode(defaultPrefix); + } + + uint32_t ptr = Seg2Filespace(limbsArrayAddress, parent->baseAddress); + if (!parent->HasDeclaration(ptr)) { - string defaultPrefix = name.c_str(); - defaultPrefix.replace(0, 1, "s"); // replace g prefix with s for local variables - - for (int i = 0; i < limbs.size(); i++) - { - ZLimbStandard* limb = limbs[i]; - - string defaultDLName = StringHelper::Sprintf("%sLimbDL_%06X", defaultPrefix.c_str(), limb->dListPtr); - string dListStr = limb->dListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetDeclarationName(limb->dListPtr, defaultDLName).c_str()); - - if (limb->dListPtr != 0 && parent->GetDeclaration(limb->dListPtr) == nullptr) - { - ZDisplayList* dList = new ZDisplayList(rawData, limb->dListPtr, ZDisplayList::GetDListLength(rawData, limb->dListPtr, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX)); - dList->parent = parent; - dList->SetName(StringHelper::Sprintf("%sLimbDL_%06X", defaultPrefix.c_str(), limb->dListPtr)); - dList->GetSourceOutputCode(defaultPrefix); - } - - string entryStr = ""; - string entryType = ""; - - if (typeid(*limb) == typeid(ZLimbLOD)) - { - ZLimbLOD* limbLOD = (ZLimbLOD*)limbs[i]; - string defaultFarDLName = StringHelper::Sprintf("%sFarLimbDlist0x%06X", defaultPrefix.c_str(), limbLOD->farDListPtr); - string dListStr2 = limbLOD->farDListPtr == 0 ? "NULL" : StringHelper::Sprintf("%s", parent->GetDeclarationName(limbLOD->farDListPtr, defaultFarDLName).c_str()); - - if (limbLOD->farDListPtr != 0 && parent->GetDeclaration(limbLOD->farDListPtr) == nullptr) - { - ZDisplayList* dList = new ZDisplayList(rawData, limbLOD->farDListPtr, ZDisplayList::GetDListLength(rawData, limbLOD->farDListPtr, Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX)); - dList->parent = parent; - dList->SetName(StringHelper::Sprintf("%s_farLimbDlist_%06X", defaultPrefix.c_str(), limbLOD->farDListPtr)); - dList->GetSourceOutputCode(defaultPrefix); - } - - entryType = "LodLimb"; - - entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, { %s, %s }", - limbLOD->transX, limbLOD->transY, limbLOD->transZ, limbLOD->childIndex, limbLOD->siblingIndex, dListStr.c_str(), dListStr2.c_str()); - } - else - { - entryType = "StandardLimb"; - - entryStr = StringHelper::Sprintf("{ %i, %i, %i }, %i, %i, %s", - limb->transX, limb->transY, limb->transZ, limb->childIndex, limb->siblingIndex, dListStr.c_str()); - } - - string limbName = StringHelper::Sprintf("%sLimb_%06X", defaultPrefix.c_str(), limb->address); - - if (parent->HasDeclaration(limb->address)) - limbName = parent->GetDeclarationName(limb->address); - - parent->AddDeclaration(limb->address, DeclarationAlignment::None, limb->GetRawDataSize(), entryType, limbName, entryStr); - } - // Table string tblStr = ""; - for (int i = 0; i < limbs.size(); i++) + for (size_t i = 0; i < limbs.size(); i++) { - ZLimbStandard* limb = limbs[i]; + ZLimb* limb = limbs.at(i); - //string decl = StringHelper::Sprintf(" &_%sLimb_%04X,\n", prefix.c_str(), limb->address); - string decl = ""; - - if (parent->HasDeclaration(limb->address)) { - decl = StringHelper::Sprintf(" &%s,", parent->GetDeclarationName(limb->address).c_str()); - if (i != (limbs.size() - 1)) { - decl += "\n"; - } + string decl = StringHelper::Sprintf(" &%s,", parent->GetDeclarationName(limb->GetFileAddress()).c_str()); + if (i != (limbs.size() - 1)) { + decl += "\n"; } tblStr += decl; } - uint32_t ptr = (uint32_t)BitConverter::ToInt32BE(rawData, rawDataIndex) & 0x00FFFFFF; + parent->AddDeclarationArray(ptr, DeclarationAlignment::None, 4 * limbCount, + StringHelper::Sprintf("static %s*", ZLimb::GetSourceTypeName(limbType)), + StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str()), limbCount, tblStr); + } - if (!parent->HasDeclaration(ptr)) - { - parent->AddDeclarationArray(ptr, DeclarationAlignment::None, 4 * limbs.size(), - "static void*", StringHelper::Sprintf("%sLimbs", defaultPrefix.c_str()), limbs.size(), tblStr); - } + string headerStr; + switch (type) { + case ZSkeletonType::Normal: + headerStr = StringHelper::Sprintf("%sLimbs, %i", defaultPrefix.c_str(), limbCount); + break; + case ZSkeletonType::Flex: + headerStr = StringHelper::Sprintf("%sLimbs, %i, %i", defaultPrefix.c_str(), limbCount, dListCount); + break; + } - if (type == ZSkeletonType::Normal) - { - string headerStr = StringHelper::Sprintf("%sLimbs, %i", defaultPrefix.c_str(), limbs.size()); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, 8, - "SkeletonHeader", StringHelper::Sprintf("%s", name.c_str()), headerStr); - } - else - { - string headerStr = StringHelper::Sprintf("%sLimbs, %i, %i", defaultPrefix.c_str(), limbs.size(), dListCount); - parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align16, 12, - "FlexSkeletonHeader", StringHelper::Sprintf("%s", name.c_str()), headerStr); - } + Declaration* decl = parent->GetDeclaration(GetAddress()); + if (decl == nullptr) { + parent->AddDeclaration(GetAddress(), DeclarationAlignment::Align16, + GetRawDataSize(), GetSourceTypeName(), name, headerStr); + } + else { + decl->text = headerStr; } return ""; } -void ZSkeleton::Save(const std::string& outFolder) +std::string ZSkeleton::GetSourceTypeName() { - + switch (type) { + case ZSkeletonType::Normal: + return "SkeletonHeader"; + case ZSkeletonType::Flex: + return "FlexSkeletonHeader"; + } + return "SkeletonHeader"; } ZResourceType ZSkeleton::GetResourceType() @@ -270,36 +198,7 @@ ZResourceType ZSkeleton::GetResourceType() return ZResourceType::Skeleton; } -ZLimbLOD::ZLimbLOD() : ZLimbStandard() +segptr_t ZSkeleton::GetAddress() { - farDListPtr = 0; -} - -ZLimbLOD* ZLimbLOD::FromRawData(vector nRawData, int rawDataIndex) -{ - ZLimbLOD* limb = new ZLimbLOD(); - - limb->address = rawDataIndex; - - limb->transX = BitConverter::ToInt16BE(nRawData, rawDataIndex + 0); - limb->transY = BitConverter::ToInt16BE(nRawData, rawDataIndex + 2); - limb->transZ = BitConverter::ToInt16BE(nRawData, rawDataIndex + 4); - - limb->childIndex = nRawData[rawDataIndex + 6]; - limb->siblingIndex = nRawData[rawDataIndex + 7]; - - limb->dListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 8) & 0x00FFFFFF; - limb->farDListPtr = BitConverter::ToInt32BE(nRawData, rawDataIndex + 12) & 0x00FFFFFF; - - return limb; -} - -string ZLimbLOD::GetSourceOutputCode(const std::string& prefix) -{ - return std::string(); -} - -int ZLimbLOD::GetRawDataSize() -{ - return 16; + return rawDataIndex; } diff --git a/tools/ZAPD/ZAPD/ZSkeleton.h b/tools/ZAPD/ZAPD/ZSkeleton.h index 836251a606..2cafd56ceb 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.h +++ b/tools/ZAPD/ZAPD/ZSkeleton.h @@ -2,64 +2,40 @@ #include #include -#include +#include #include "ZFile.h" - -enum class ZLimbType -{ - Standard, - LOD -}; - -struct ZLimbStandard : public ZResource -{ - uint32_t address; - std::string name; - - int16_t transX, transY, transZ; - uint8_t childIndex, siblingIndex; - uint32_t dListPtr; - - std::vector children; - - ZLimbStandard(); - static ZLimbStandard* FromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); - static ZLimbStandard* FromRawData(std::vector nRawData, int rawDataIndex); - std::string GetSourceOutputCode(const std::string& prefix) override; - int GetRawDataSize() override; -}; - -struct ZLimbLOD : ZLimbStandard -{ - uint32_t farDListPtr; - - ZLimbLOD(); - //static ZLimbLOD* FromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent); - static ZLimbLOD* FromRawData(std::vector nRawData, int rawDataIndex); - std::string GetSourceOutputCode(const std::string& prefix) override; - int GetRawDataSize() override; -}; +#include "ZDisplayList.h" +#include "ZLimb.h" enum ZSkeletonType { Normal, - Flex, - Skin + Flex }; class ZSkeleton : public ZResource { public: - ZSkeletonType type; - std::vector limbs; - ZLimbStandard* rootLimb; + ZSkeletonType type = ZSkeletonType::Normal; + ZLimbType limbType = ZLimbType::Standard; + std::vector limbs; + segptr_t limbsArrayAddress; + uint8_t limbCount; uint8_t dListCount; // FLEX SKELETON ONLY - ZSkeleton(); - virtual void GenerateHLIntermediette(HLFileIntermediette& hlFile); + ZSkeleton(tinyxml2::XMLElement* reader, const std::vector& nRawData, int nRawDataIndex, ZFile* nParent); + ~ZSkeleton(); + void ParseXML(tinyxml2::XMLElement* reader) override; + void ParseRawData() override; static ZSkeleton* FromXML(tinyxml2::XMLElement* reader, std::vector nRawData, int rawDataIndex, std::string nRelPath, ZFile* nParent); void Save(const std::string& outFolder) override; + void GenerateHLIntermediette(HLFileIntermediette& hlFile) override; + + int GetRawDataSize() override; + std::string GetSourceOutputCode(const std::string& prefix) override; + + std::string GetSourceTypeName() override; ZResourceType GetResourceType() override; - std::string GetSourceOutputCode(const std::string& prefix) override; + segptr_t GetAddress(); }; diff --git a/tools/ZAPD/ZAPD/ZTexture.cpp b/tools/ZAPD/ZAPD/ZTexture.cpp index ba58e98594..21d01df79a 100644 --- a/tools/ZAPD/ZAPD/ZTexture.cpp +++ b/tools/ZAPD/ZAPD/ZTexture.cpp @@ -792,6 +792,7 @@ TextureType ZTexture::GetTextureTypeFromString(string str) texType = TextureType::Palette4bpp; else if (str == "ci8") texType = TextureType::Palette8bpp; - + else + printf("Encountered Unknown Texture Type %s \n",str.c_str()); return texType; } diff --git a/tools/ZAPD/ZAPD/genbuildinfo.py b/tools/ZAPD/ZAPD/genbuildinfo.py new file mode 100644 index 0000000000..04925aa20c --- /dev/null +++ b/tools/ZAPD/ZAPD/genbuildinfo.py @@ -0,0 +1,12 @@ +#!/usr/bin/python3 + +from datetime import datetime +import getpass +import subprocess + +with open("ZAPD/BuildInfo.h", "w+") as buildFile: + label = subprocess.check_output(["git", "describe", "--always"]).strip().decode("utf-8") + now = datetime.now() + buildFile.write("const char gBuildHash[] = \"" + label + "\";\n") + #buildFile.write("const char gBuildDate[] = \"" + now.strftime("%Y-%m-%d %H:%M:%S") + "\";\n") + \ No newline at end of file diff --git a/tools/ZAPD/lib/libgfxd/gfxd.h b/tools/ZAPD/lib/libgfxd/gfxd.h new file mode 100644 index 0000000000..ee0fc64c9e --- /dev/null +++ b/tools/ZAPD/lib/libgfxd/gfxd.h @@ -0,0 +1,378 @@ +#ifndef GFXD_H +#define GFXD_H +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +enum +{ + gfxd_Word, /* generic word */ + gfxd_Coordi, /* integer coordinate */ + gfxd_Coordq, /* fractional (q10.2) coordinate */ + gfxd_Pal, /* palette index */ + gfxd_Tlut, /* tlut pointer */ + gfxd_Timg, /* texture image pointer */ + gfxd_Tmem, /* tmem address */ + gfxd_Tile, /* tile index */ + gfxd_Fmt, /* texture format */ + gfxd_Siz, /* texture pixel size */ + gfxd_Dim, /* integer dimension (width / height) */ + gfxd_Cm, /* clamp and mirror flags */ + gfxd_Tm, /* tile mask */ + gfxd_Ts, /* tile shift */ + gfxd_Dxt, /* texture dxt */ + gfxd_Tag, /* generic tag */ + gfxd_Pm, /* pipeline mode */ + gfxd_Colorpart, /* color component */ + gfxd_Color, /* color */ + gfxd_Lodfrac, /* lod fraction (q0.8) */ + gfxd_Cimg, /* color image pointer */ + gfxd_Zimg, /* depth image pointer */ + gfxd_Ac, /* alpha compare mode */ + gfxd_Ad, /* alpha dither mode */ + gfxd_Cd, /* color dither mode */ + gfxd_Ccpre, /* color combiner preset index */ + gfxd_Ccmuxa, /* color mux operand (a) */ + gfxd_Ccmuxb, /* color mux operand (b) */ + gfxd_Ccmuxc, /* color mux operand (c) */ + gfxd_Ccmuxd, /* color mux operand (d) */ + gfxd_Acmuxabd, /* alpha mux operand (a, b, or d) */ + gfxd_Acmuxc, /* alpha mux operand (c) */ + gfxd_Cv, /* color convert operand */ + gfxd_Tc, /* texture convert mode */ + gfxd_Cyc, /* cycle type */ + gfxd_Zs, /* depth source mode */ + gfxd_Ck, /* combine key mode */ + gfxd_Keyscale, /* combine key scale */ + gfxd_Keywidth, /* combine key width */ + gfxd_Zi, /* integer depth */ + gfxd_Rm1, /* cycle 1 render mode */ + gfxd_Rm2, /* cycle 2 render mode */ + gfxd_Sc, /* scissor mode */ + gfxd_Td, /* texture detail mode */ + gfxd_Tf, /* texture filter mode */ + gfxd_Tl, /* texture LOD mode */ + gfxd_Tt, /* textuure LUT mode */ + gfxd_Tp, /* texture perspective mode */ + gfxd_Line, /* texture line size */ + gfxd_Vtx, /* vertex index */ + gfxd_Vtxflag, /* vertex flag */ + gfxd_Dl, /* display list pointer */ + gfxd_Zraw, /* raw depth value (q16.16) */ + gfxd_Dlflag, /* display list flag */ + gfxd_Cr, /* clip ratio */ + gfxd_Num, /* element count */ + gfxd_Fogz, /* fog depth (0 - 1000) */ + gfxd_Mtxptr, /* matrix pointer */ + gfxd_Gm, /* geometry mode */ + gfxd_Mwo_matrix, /* matrix moveword offset */ + gfxd_Linewd, /* line width (1.5 + q7.1) */ + gfxd_Uctext, /* microcode text pointer */ + gfxd_Ucdata, /* microcode data pointer */ + gfxd_Size, /* data size */ + gfxd_Lookatptr, /* lookat pointer */ + gfxd_Mtxparam, /* matrix param */ + gfxd_Mtxstack, /* matrix param (stack select only) */ + gfxd_Mwo_point, /* vertex moveword offset */ + gfxd_Wscale, /* w-component scale (perspnorm) */ + gfxd_Seg, /* segment number */ + gfxd_Segptr, /* segment pointer */ + gfxd_Lightsn, /* dereferenced Lighstn pointer */ + gfxd_Numlights, /* light count (NUMLIGHTS_*) */ + gfxd_Lightnum, /* light number (LIGHT_*) */ + gfxd_Lightptr, /* light pointer */ + gfxd_Tcscale, /* texture coordinate scale */ + gfxd_Switch, /* on-off value */ + gfxd_St, /* vertex coordinate (q10.5) */ + gfxd_Stdelta, /* vertex coordinate delta (q5.10) */ + gfxd_Vtxptr, /* vertex pointer */ + gfxd_Vpptr, /* viewport pointer */ + gfxd_Dram, /* generic dram address */ + gfxd_Sftlo, /* othermode lo shift */ + gfxd_Othermodelo, /* othermode lo value */ + gfxd_Sfthi, /* othermode hi shift */ + gfxd_Othermodehi, /* othermode hi value */ + gfxd_Mw, /* moveword index */ + gfxd_Mwo, /* moveword offset */ + gfxd_Mwo_clip, /* clip ratio moveword offset */ + gfxd_Mwo_lightcol, /* light color moveword offset */ + gfxd_Mv, /* movemem index */ + gfxd_Mvo, /* movemem offset */ + gfxd_Dmem, /* dmem address */ + gfxd_Dmaflag, /* dma io flag */ +}; + +enum +{ + gfxd_Invalid, + gfxd_DPFillRectangle, + gfxd_DPFullSync, + gfxd_DPLoadSync, + gfxd_DPTileSync, + gfxd_DPPipeSync, + gfxd_DPLoadTLUT_pal16, + gfxd_DPLoadTLUT_pal256, + gfxd_DPLoadMultiBlockYuvS, + gfxd_DPLoadMultiBlockYuv, + gfxd_DPLoadMultiBlock_4bS, + gfxd_DPLoadMultiBlock_4b, + gfxd_DPLoadMultiBlockS, + gfxd_DPLoadMultiBlock, + gfxd__DPLoadTextureBlockYuvS, + gfxd__DPLoadTextureBlockYuv, + gfxd__DPLoadTextureBlock_4bS, + gfxd__DPLoadTextureBlock_4b, + gfxd__DPLoadTextureBlockS, + gfxd__DPLoadTextureBlock, + gfxd_DPLoadTextureBlockYuvS, + gfxd_DPLoadTextureBlockYuv, + gfxd_DPLoadTextureBlock_4bS, + gfxd_DPLoadTextureBlock_4b, + gfxd_DPLoadTextureBlockS, + gfxd_DPLoadTextureBlock, + gfxd_DPLoadMultiTileYuv, + gfxd_DPLoadMultiTile_4b, + gfxd_DPLoadMultiTile, + gfxd__DPLoadTextureTileYuv, + gfxd__DPLoadTextureTile_4b, + gfxd__DPLoadTextureTile, + gfxd_DPLoadTextureTileYuv, + gfxd_DPLoadTextureTile_4b, + gfxd_DPLoadTextureTile, + gfxd_DPLoadBlock, + gfxd_DPNoOp, + gfxd_DPNoOpTag, + gfxd_DPPipelineMode, + gfxd_DPSetBlendColor, + gfxd_DPSetEnvColor, + gfxd_DPSetFillColor, + gfxd_DPSetFogColor, + gfxd_DPSetPrimColor, + gfxd_DPSetColorImage, + gfxd_DPSetDepthImage, + gfxd_DPSetTextureImage, + gfxd_DPSetAlphaCompare, + gfxd_DPSetAlphaDither, + gfxd_DPSetColorDither, + gfxd_DPSetCombineMode, + gfxd_DPSetCombineLERP, + gfxd_DPSetConvert, + gfxd_DPSetTextureConvert, + gfxd_DPSetCycleType, + gfxd_DPSetDepthSource, + gfxd_DPSetCombineKey, + gfxd_DPSetKeyGB, + gfxd_DPSetKeyR, + gfxd_DPSetPrimDepth, + gfxd_DPSetRenderMode, + gfxd_DPSetScissor, + gfxd_DPSetScissorFrac, + gfxd_DPSetTextureDetail, + gfxd_DPSetTextureFilter, + gfxd_DPSetTextureLOD, + gfxd_DPSetTextureLUT, + gfxd_DPSetTexturePersp, + gfxd_DPSetTile, + gfxd_DPSetTileSize, + gfxd_SP1Triangle, + gfxd_SP2Triangles, + gfxd_SP1Quadrangle, + gfxd_SPBranchLessZraw, + gfxd_SPBranchList, + gfxd_SPClipRatio, + gfxd_SPCullDisplayList, + gfxd_SPDisplayList, + gfxd_SPEndDisplayList, + gfxd_SPFogPosition, + gfxd_SPForceMatrix, + gfxd_SPSetGeometryMode, + gfxd_SPClearGeometryMode, + gfxd_SPLoadGeometryMode, + gfxd_SPInsertMatrix, + gfxd_SPLine3D, + gfxd_SPLineW3D, + gfxd_SPLoadUcode, + gfxd_SPLookAtX, + gfxd_SPLookAtY, + gfxd_SPLookAt, + gfxd_SPMatrix, + gfxd_SPModifyVertex, + gfxd_SPPerspNormalize, + gfxd_SPPopMatrix, + gfxd_SPPopMatrixN, + gfxd_SPSegment, + gfxd_SPSetLights1, + gfxd_SPSetLights2, + gfxd_SPSetLights3, + gfxd_SPSetLights4, + gfxd_SPSetLights5, + gfxd_SPSetLights6, + gfxd_SPSetLights7, + gfxd_SPNumLights, + gfxd_SPLight, + gfxd_SPLightColor, + gfxd_SPTexture, + gfxd_SPTextureRectangle, + gfxd_SPTextureRectangleFlip, + gfxd_SPVertex, + gfxd_SPViewport, + gfxd_DPLoadTLUTCmd, + gfxd_DPLoadTLUT, + gfxd_BranchZ, + gfxd_DisplayList, + gfxd_DPHalf1, + gfxd_DPHalf2, + gfxd_DPLoadTile, + gfxd_SPGeometryMode, + gfxd_SPSetOtherModeLo, + gfxd_SPSetOtherModeHi, + gfxd_DPSetOtherMode, + gfxd_MoveWd, + gfxd_MoveMem, + gfxd_SPDma_io, + gfxd_SPDmaRead, + gfxd_SPDmaWrite, + gfxd_LoadUcode, + gfxd_SPLoadUcodeEx, + gfxd_TexRect, + gfxd_TexRectFlip, + gfxd_SPNoOp, + gfxd_Special3, + gfxd_Special2, + gfxd_Special1, +}; + +enum +{ + gfxd_stop_on_invalid, + gfxd_stop_on_end, + gfxd_emit_dec_color, + gfxd_emit_q_macro, +}; + +enum +{ + gfxd_endian_big, + gfxd_endian_little, +}; + +enum +{ + gfxd_argfmt_i, + gfxd_argfmt_u, + gfxd_argfmt_f, +}; + +typedef union +{ + int32_t i; + uint32_t u; + float f; +} gfxd_value_t; + +typedef const struct gfxd_ucode *gfxd_ucode_t; + +typedef int gfxd_input_fn_t(void *buf, int count); +void gfxd_input_buffer(const void *buf, int size); +void gfxd_input_fd(int fd); +void gfxd_input_callback(gfxd_input_fn_t *fn); + +typedef int gfxd_output_fn_t(const char *buf, int count); +void gfxd_output_buffer(char *buf, int size); +void gfxd_output_fd(int fd); +void gfxd_output_callback(gfxd_output_fn_t *fn); + +typedef int gfxd_macro_fn_t(void); +void gfxd_macro_fn(gfxd_macro_fn_t *fn); +gfxd_macro_fn_t gfxd_macro_dflt; + +typedef void gfxd_arg_fn_t(int arg_num); +void gfxd_arg_fn(gfxd_arg_fn_t *fn); +gfxd_arg_fn_t gfxd_arg_dflt; + +typedef int gfxd_tlut_fn_t(uint32_t tlut, int32_t idx, int32_t count); +void gfxd_tlut_callback(gfxd_tlut_fn_t *fn); + +typedef int gfxd_timg_fn_t(uint32_t timg, int32_t fmt, int32_t siz, + int32_t width, int32_t height, int32_t pal); +void gfxd_timg_callback(gfxd_timg_fn_t *fn); + +typedef int gfxd_cimg_fn_t(uint32_t cimg, int32_t fmt, int32_t siz, + int32_t width); +void gfxd_cimg_callback(gfxd_cimg_fn_t *fn); + +typedef int gfxd_zimg_fn_t(uint32_t zimg); +void gfxd_zimg_callback(gfxd_zimg_fn_t *fn); + +typedef int gfxd_dl_fn_t(uint32_t dl); +void gfxd_dl_callback(gfxd_dl_fn_t *fn); + +typedef int gfxd_mtx_fn_t(uint32_t mtx); +void gfxd_mtx_callback(gfxd_mtx_fn_t *fn); + +typedef int gfxd_lookat_fn_t(uint32_t lookat, int32_t count); +void gfxd_lookat_callback(gfxd_lookat_fn_t *fn); + +typedef int gfxd_light_fn_t(uint32_t light, int32_t count); +void gfxd_light_callback(gfxd_light_fn_t *fn); + +typedef int gfxd_seg_fn_t(uint32_t seg, int32_t num); +void gfxd_seg_callback(gfxd_seg_fn_t *fn); + +typedef int gfxd_vtx_fn_t(uint32_t vtx, int32_t num); +void gfxd_vtx_callback(gfxd_vtx_fn_t *fn); + +typedef int gfxd_vp_fn_t(uint32_t vp); +void gfxd_vp_callback(gfxd_vp_fn_t *fn); + +typedef int gfxd_uctext_fn_t(uint32_t text, uint32_t size); +void gfxd_uctext_callback(gfxd_uctext_fn_t *fn); + +typedef int gfxd_ucdata_fn_t(uint32_t data, uint32_t size); +void gfxd_ucdata_callback(gfxd_ucdata_fn_t *fn); + +typedef int gfxd_dram_fn_t(uint32_t dram, uint32_t size); +void gfxd_dram_callback(gfxd_dram_fn_t *fn); + +int gfxd_write(const void *buf, int count); +int gfxd_puts(const char *str); +int gfxd_printf(const char *fmt, ...); +int gfxd_print_value(int type, const gfxd_value_t *value); + +void gfxd_target(gfxd_ucode_t ucode); +void gfxd_endian(int endian, int wordsize); +void gfxd_dynamic(const char *arg); +void gfxd_enable(int cap); +void gfxd_disable(int cap); + +int gfxd_execute(void); + +int gfxd_macro_offset(void); +int gfxd_macro_packets(void); +const void *gfxd_macro_data(void); +int gfxd_macro_id(void); +const char *gfxd_macro_name(void); + +int gfxd_arg_count(void); +int gfxd_arg_type(int arg_num); +const char *gfxd_arg_name(int arg_num); +int gfxd_arg_fmt(int arg_num); +const gfxd_value_t *gfxd_arg_value(int arg_num); +const gfxd_value_t *gfxd_value_by_type(int type, int idx); +int gfxd_arg_valid(int arg_num); +int gfxd_arg_callbacks(int arg_num); + +extern const gfxd_ucode_t gfxd_f3d; +extern const gfxd_ucode_t gfxd_f3db; +extern const gfxd_ucode_t gfxd_f3dex; +extern const gfxd_ucode_t gfxd_f3dexb; +extern const gfxd_ucode_t gfxd_f3dex2; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/ZAPD/lib/libgfxd/libgfxd.a b/tools/ZAPD/lib/libgfxd/libgfxd.a new file mode 100644 index 0000000000..1f8c0e2736 Binary files /dev/null and b/tools/ZAPD/lib/libgfxd/libgfxd.a differ