1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-05-11 11:33:48 +00:00

git subrepo pull --force tools/ZAPD (#718)

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "4bf6600a3"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "4bf6600a3"
git-subrepo:
  version:  "0.4.3"
  origin:   "https://github.com/ingydotnet/git-subrepo.git"
  commit:   "2f68596"
This commit is contained in:
fig02 2021-03-14 11:40:25 -04:00 committed by GitHub
parent 8a730123b6
commit 42af56b231
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 1854 additions and 445 deletions

View file

@ -333,3 +333,4 @@ ASALocalRun/
*.o
*.d
.vscode/
ZAPD/BuildInfo.h

View file

@ -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

View file

@ -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)

View file

@ -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++)
{

View file

@ -9,6 +9,7 @@
#include "File.h"
#include "Directory.h"
#include "Globals.h"
#include "BuildInfo.h"
#if !defined(_MSC_VER) && !defined(__CYGWIN__)
#include <execinfo.h>
@ -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)
{

View file

@ -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);
}

View file

@ -0,0 +1,38 @@
#pragma once
#include <vector>
#include <map>
#include <string>
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();
};

View file

@ -103,6 +103,10 @@
<Profile>true</Profile>
<AdditionalDependencies>assimp-vc142-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>cd ..
python3 ZAPD/genbuildinfo.py</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>

View file

@ -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));
}

View file

@ -1,6 +1,7 @@
#include "ZCollision.h"
#include "BitConverter.h"
#include "StringHelper.h"
#include "Globals.h"
#include <stdint.h>
#include <string>
@ -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<uint8_t>& 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<uint8_t>& 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;

View file

@ -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<VertexEntry*> vertices;
std::vector<PolygonEntry*> polygons;

View file

@ -913,7 +913,7 @@ CutsceneCommandSceneTransFX::CutsceneCommandSceneTransFX(const vector<uint8_t>&
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)

View file

@ -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 <chrono>
#include <algorithm>
#include <File.h>
@ -68,7 +70,7 @@ ZDisplayList::ZDisplayList(vector<uint8_t> nRawData, int nRawDataIndex, int rawD
{
fileData = nRawData;
rawDataIndex = nRawDataIndex;
name = StringHelper::Sprintf("Dlist0x%06X", rawDataIndex);
name = StringHelper::Sprintf("DL_%06X", rawDataIndex);
rawData = vector<uint8_t>(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<Vertex> vtxList = vector<Vertex>();
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<chrono::milliseconds>(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<uint8_t> fileData, map<uint32_t, ZTexture*>& 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)
{

View file

@ -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<uint64_t> 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<uint8_t> nRawData, int rawDataIndex, int rawDataSize);
static ZDisplayList* static_instance;
static ZDisplayList* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> nRawData, int rawDataIndex, int rawDataSize, std::string nRelPath);
static ZDisplayList* BuildFromXML(tinyxml2::XMLElement* reader, std::string inFolder, bool readFile);

View file

@ -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<int32_t, Declaration*> 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<int32_t, Declaration*> 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)

572
tools/ZAPD/ZAPD/ZLimb.cpp Normal file
View file

@ -0,0 +1,572 @@
#include "ZLimb.h"
#include "BitConverter.h"
#include "StringHelper.h"
#include "Globals.h"
#include <cassert>
using namespace std;
Struct_800A57C0::Struct_800A57C0(const std::vector<uint8_t>& 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<uint8_t>& rawData, uint32_t fileOffset, size_t index)
: Struct_800A57C0(rawData, fileOffset + index * GetRawDataSize())
{
}
std::string Struct_800A57C0::GetSourceOutputCode() const
{
return StringHelper::Sprintf("0x%02X, %i, %i, %i, %i, %i, 0x%02X",
unk_0, unk_2, unk_4, unk_6, unk_7, unk_8, unk_9);
}
size_t Struct_800A57C0::GetRawDataSize()
{
return 0x0A;
}
std::string Struct_800A57C0::GetSourceTypeName()
{
return "Struct_800A57C0";
}
Struct_800A598C_2::Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset)
{
unk_0 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x00);
x = BitConverter::ToInt16BE(rawData, fileOffset + 0x02);
y = BitConverter::ToInt16BE(rawData, fileOffset + 0x04);
z = BitConverter::ToInt16BE(rawData, fileOffset + 0x06);
unk_8 = BitConverter::ToUInt8BE(rawData, fileOffset + 0x08);
}
Struct_800A598C_2::Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index)
: Struct_800A598C_2(rawData, fileOffset + index * GetRawDataSize())
{
}
std::string Struct_800A598C_2::GetSourceOutputCode() const
{
return StringHelper::Sprintf("0x%02X, %i, %i, %i, 0x%02X",
unk_0, x, y, z, unk_8);
}
size_t Struct_800A598C_2::GetRawDataSize()
{
return 0x0A;
}
std::string Struct_800A598C_2::GetSourceTypeName()
{
return "Struct_800A598C_2";
}
Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset)
: parent(parent)
{
unk_0 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x00);
unk_2 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x02);
unk_4 = BitConverter::ToUInt16BE(rawData, fileOffset + 0x04);
unk_8 = BitConverter::ToUInt32BE(rawData, fileOffset + 0x08);
unk_C = BitConverter::ToUInt32BE(rawData, fileOffset + 0x0C);
if (unk_8 != 0) {
uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress);
for (size_t i = 0; i < unk_0; i++) {
unk_8_arr.emplace_back(rawData, unk_8_Offset, i);
}
}
if (unk_C != 0) {
uint32_t unk_C_Offset = Seg2Filespace(unk_C, parent->baseAddress);
for (size_t i = 0; i < unk_2; i++) {
unk_C_arr.emplace_back(rawData, unk_C_Offset, i);
}
}
}
Struct_800A598C::Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index)
: Struct_800A598C(parent, rawData, fileOffset + index * GetRawDataSize())
{
}
void Struct_800A598C::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<uint8_t>& 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<uint8_t>& 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<uint8_t>& 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<uint8_t>& 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 <Skeleton/>
const char* limbType = reader->Attribute("LimbType");
if (limbType == nullptr) {
// Reading from a <Limb/>
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<ZLimbSkinType>(BitConverter::ToInt32BE(rawData, rawDataIndex + 8));
skinSegment = BitConverter::ToUInt32BE(rawData, rawDataIndex + 12);
break;
}
}
ZLimb* ZLimb::FromXML(tinyxml2::XMLElement* reader, vector<uint8_t> 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<int32_t>(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<int32_t>(skinSegmentType));
skinSegmentStr = StringHelper::Sprintf("0x%08X", skinSegment);
break;
}
}
string entryStr = StringHelper::Sprintf(" 0x%02X, %s\n",
skinSegmentType, skinSegmentStr.c_str());
return entryStr;
}

166
tools/ZAPD/ZAPD/ZLimb.h Normal file
View file

@ -0,0 +1,166 @@
#pragma once
#include <vector>
#include <string>
#include <cstdint>
#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<uint8_t>& rawData, uint32_t fileOffset);
Struct_800A57C0(const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index);
[[nodiscard]]
std::string GetSourceOutputCode() const;
static size_t GetRawDataSize();
static std::string GetSourceTypeName();
};
class Struct_800A598C_2
{
protected:
uint8_t unk_0;
int16_t x;
int16_t y;
int16_t z;
uint8_t unk_8;
public:
Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset);
Struct_800A598C_2(const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index);
[[nodiscard]]
std::string GetSourceOutputCode() const;
static size_t GetRawDataSize();
static std::string GetSourceTypeName();
};
class Struct_800A598C
{
protected:
ZFile* parent;
uint16_t unk_0; // Length of unk_8
uint16_t unk_2; // Length of unk_C
uint16_t unk_4; // 0 or 1 // Used as an index for unk_C
segptr_t unk_8; // Struct_800A57C0*
segptr_t unk_C; // Struct_800A598C_2*
std::vector<Struct_800A57C0> unk_8_arr;
std::vector<Struct_800A598C_2> unk_C_arr;
public:
Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset);
Struct_800A598C(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index);
void 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<uint8_t> 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<Struct_800A598C> unk_4_arr;
ZDisplayList* unk_8_dlist = nullptr;
public:
Struct_800A5E28() = default;
Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset);
Struct_800A5E28(ZFile* parent, const std::vector<uint8_t>& rawData, uint32_t fileOffset, size_t index);
~Struct_800A5E28();
void 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<ZDisplayList> 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<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent);
ZLimb(ZLimbType limbType, const std::string& prefix, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent);
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
static ZLimb* FromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> 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();
};

View file

@ -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;
}

View file

@ -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);

View file

@ -11,7 +11,7 @@ using namespace std;
SetActorList::SetActorList(ZRoom* nZRoom, std::vector<uint8_t> 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.

View file

@ -7,7 +7,7 @@ using namespace std;
SetAlternateHeaders::SetAlternateHeaders(ZRoom* nZRoom, std::vector<uint8_t> 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);

View file

@ -8,7 +8,7 @@ using namespace std;
SetCollisionHeader::SetCollisionHeader(ZRoom* nZRoom, std::vector<uint8_t> 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);
}

View file

@ -8,7 +8,7 @@ using namespace std;
SetExitList::SetExitList(ZRoom* nZRoom, std::vector<uint8_t> rawData, int rawDataIndex) : ZRoomCommand(nZRoom, rawData, rawDataIndex)
{
segmentOffset = SEG2FILESPACE(BitConverter::ToInt32BE(rawData, rawDataIndex + 4));
segmentOffset = GETSEGOFFSET(BitConverter::ToInt32BE(rawData, rawDataIndex + 4));
exits = vector<uint16_t>();
if (segmentOffset != 0)

View file

@ -9,7 +9,7 @@ using namespace std;
SetLightingSettings::SetLightingSettings(ZRoom* nZRoom, std::vector<uint8_t> 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)));

View file

@ -11,7 +11,7 @@ using namespace std;
SetMesh::SetMesh(ZRoom* nZRoom, std::vector<uint8_t> 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<uint8_t> rawData, int rawDataIndex,
meshHeader0->headerType = 0;
meshHeader0->entries = vector<MeshEntry0*>();
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<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> rawData, int rawDataIndex,
meshHeader2->headerType = 2;
meshHeader2->entries = vector<MeshEntry2*>();
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<uint8_t> 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);

View file

@ -11,7 +11,7 @@ SetObjectList::SetObjectList(ZRoom* nZRoom, std::vector<uint8_t> rawData, int ra
{
objects = vector<uint16_t>();
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++)

View file

@ -14,7 +14,7 @@ SetPathways::SetPathways(ZRoom* nZRoom, std::vector<uint8_t> 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];
}

View file

@ -10,7 +10,7 @@ using namespace std;
SetStartPositionList::SetStartPositionList(ZRoom* nZRoom, std::vector<uint8_t> 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);

View file

@ -225,10 +225,8 @@ void ZRoom::ParseCommands(std::vector<ZRoomCommand*>& 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<ZRoomCommand*> setCommands = std::vector<ZRoomCommand*>();
int32_t commandSet = commandSets[0].address;
int8_t segmentNumber = commandSet >> 24;
ParseCommands(setCommands, commandSets[0]);
commandSets.erase(commandSets.begin());

View file

@ -1,89 +1,108 @@
#include "ZSkeleton.h"
#include "BitConverter.h"
#include "StringHelper.h"
#include "Globals.h"
#include "HighLevel/HLModelIntermediette.h"
#include <typeinfo>
using namespace std;
using namespace tinyxml2;
ZLimbStandard::ZLimbStandard()
ZSkeleton::ZSkeleton(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent)
{
name = "";
transX = 0;
transY = 0;
transZ = 0;
childIndex = 0;
siblingIndex = 0;
dListPtr = 0;
children = vector<ZLimbStandard*>();
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<uint8_t> 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<uint8_t> 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<uint8_t> 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<ZLimbStandard*>();
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<uint8_t> 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<uint8_t> 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;
}

View file

@ -2,64 +2,40 @@
#include <vector>
#include <string>
#include <stdint.h>
#include <cstdint>
#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<ZLimbStandard*> children;
ZLimbStandard();
static ZLimbStandard* FromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent);
static ZLimbStandard* FromRawData(std::vector<uint8_t> 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<uint8_t> nRawData, int rawDataIndex, std::string nRelPath, ZFile* parent);
static ZLimbLOD* FromRawData(std::vector<uint8_t> 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<ZLimbStandard*> limbs;
ZLimbStandard* rootLimb;
ZSkeletonType type = ZSkeletonType::Normal;
ZLimbType limbType = ZLimbType::Standard;
std::vector<ZLimb*> 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<uint8_t>& nRawData, int nRawDataIndex, ZFile* nParent);
~ZSkeleton();
void ParseXML(tinyxml2::XMLElement* reader) override;
void ParseRawData() override;
static ZSkeleton* FromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> 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();
};

View file

@ -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;
}

View file

@ -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")

View file

@ -0,0 +1,378 @@
#ifndef GFXD_H
#define GFXD_H
#include <stdint.h>
#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

Binary file not shown.