summaryrefslogtreecommitdiff
path: root/ZAPD
diff options
context:
space:
mode:
authorAnghelo Carvajal <angheloalf95@gmail.com>2021-05-07 17:35:00 -0400
committerGitHub <noreply@github.com>2021-05-07 17:35:00 -0400
commit547c9b200d1dff745dee694c20a9f9e8e409a11d (patch)
tree4eb2ec3fe46fb5709a43d268a2de74668839f2f1 /ZAPD
parent5a721d58d4b28f4797d6fdf29d9926e5e968a939 (diff)
Change image library to `libpng` and improve how palettized textures are extracted (#133)
* trying to change to libpng * It works again! * move the libpng abstraction to another file * GetBytesPerPixel * I'm dumb * fix warnings and remove dead code * Fix CRC being called multiples times and clean up code * textureDataRaw * code clean * Optimizations and removal of redundant data moves * ups * run format * use fs::path more * i'm dumb again * Add a Readme * remove texDeclarations * handle tluts better * vtx change and set segment file * small changes * Fix ZAPD ignoring textures declared in a scene in the XML * small cleanup before tluts * paletted images are broken * kinda works for automatic textures * fix automatic ci * TEXTURE_DEBUG * Remove extra `-j` * Fix extraction of ci4 * Finally palettes OK * ups * Move textures map to ZFile * Fix intersection warnings * Add `TlutOffset` attribute * Move Tlut declaration to a later step * Hopefully the last cleanup of this branch * Run format * Always calc hash * run format * Delete stb * fix merge issues * run format
Diffstat (limited to 'ZAPD')
-rw-r--r--ZAPD/Globals.cpp9
-rw-r--r--ZAPD/Globals.h5
-rw-r--r--ZAPD/HighLevel/HLModelIntermediette.cpp62
-rw-r--r--ZAPD/HighLevel/HLModelIntermediette.h4
-rw-r--r--ZAPD/HighLevel/HLTexture.cpp7
-rw-r--r--ZAPD/ImageBackend.cpp473
-rw-r--r--ZAPD/ImageBackend.h71
-rw-r--r--ZAPD/Main.cpp108
-rw-r--r--ZAPD/Path.h4
-rw-r--r--ZAPD/StringHelper.h5
-rw-r--r--ZAPD/ZAnimation.cpp4
-rw-r--r--ZAPD/ZAnimation.h2
-rw-r--r--ZAPD/ZBackground.cpp5
-rw-r--r--ZAPD/ZBackground.h2
-rw-r--r--ZAPD/ZBlob.cpp4
-rw-r--r--ZAPD/ZBlob.h2
-rw-r--r--ZAPD/ZDisplayList.cpp471
-rw-r--r--ZAPD/ZDisplayList.h37
-rw-r--r--ZAPD/ZFile.cpp225
-rw-r--r--ZAPD/ZFile.h27
-rw-r--r--ZAPD/ZResource.cpp23
-rw-r--r--ZAPD/ZResource.h24
-rw-r--r--ZAPD/ZRoom/Commands/SetCutscenes.cpp5
-rw-r--r--ZAPD/ZRoom/Commands/SetMesh.cpp9
-rw-r--r--ZAPD/ZRoom/ZRoom.cpp72
-rw-r--r--ZAPD/ZRoom/ZRoom.h3
-rw-r--r--ZAPD/ZSkeleton.cpp4
-rw-r--r--ZAPD/ZSkeleton.h1
-rw-r--r--ZAPD/ZTexture.cpp772
-rw-r--r--ZAPD/ZTexture.h98
-rw-r--r--ZAPD/ZVtx.cpp37
-rw-r--r--ZAPD/ZVtx.h16
32 files changed, 1477 insertions, 1114 deletions
diff --git a/ZAPD/Globals.cpp b/ZAPD/Globals.cpp
index 93e7fdf..060c59f 100644
--- a/ZAPD/Globals.cpp
+++ b/ZAPD/Globals.cpp
@@ -47,14 +47,12 @@ string Globals::FindSymbolSegRef(int32_t segNumber, uint32_t symbolAddress)
if (root == nullptr)
return "ERROR";
- // vector<ZFile*> files = vector<ZFile*>();
-
for (XMLElement* child = root->FirstChildElement(); child != NULL;
child = child->NextSiblingElement())
{
if (string(child->Name()) == "File")
{
- ZFile* file = new ZFile(fileMode, child, "", "", "", "", true);
+ ZFile* file = new ZFile(fileMode, child, "", "", "", filePath, true);
file->GeneratePlaceholderDeclarations();
segmentRefFiles[segNumber] = file;
break;
@@ -175,10 +173,13 @@ void Globals::GenSymbolMap(const std::string& symbolMapPath)
}
}
-void Globals::AddSegment(int32_t segment)
+void Globals::AddSegment(int32_t segment, ZFile* file)
{
if (std::find(segments.begin(), segments.end(), segment) == segments.end())
segments.push_back(segment);
+
+ segmentRefs[segment] = file->GetXmlFilePath();
+ segmentRefFiles[segment] = file;
}
bool Globals::HasSegment(int32_t segment)
diff --git a/ZAPD/Globals.h b/ZAPD/Globals.h
index 5186947..c830b9f 100644
--- a/ZAPD/Globals.h
+++ b/ZAPD/Globals.h
@@ -42,7 +42,8 @@ public:
bool genSourceFile; // Used for extraction
bool useExternalResources;
- bool testMode; // Enables certain experimental features
+ bool testMode; // Enables certain experimental features
+ bool outputCrc = false;
bool profile; // Measure performance of certain operations
bool includeFilePrefix; // Include the file prefix in symbols
bool useLegacyZDList;
@@ -66,7 +67,7 @@ public:
void ReadConfigFile(const std::string& configFilePath);
void ReadTexturePool(const std::string& texturePoolXmlPath);
void GenSymbolMap(const std::string& symbolMapPath);
- void AddSegment(int32_t segment);
+ void AddSegment(int32_t segment, ZFile* file);
bool HasSegment(int32_t segment);
};
diff --git a/ZAPD/HighLevel/HLModelIntermediette.cpp b/ZAPD/HighLevel/HLModelIntermediette.cpp
index b4eae32..1c0cd2f 100644
--- a/ZAPD/HighLevel/HLModelIntermediette.cpp
+++ b/ZAPD/HighLevel/HLModelIntermediette.cpp
@@ -66,16 +66,16 @@ void HLModelIntermediette::FromZDisplayList(HLModelIntermediette* model, ZDispla
limb->name = zDisplayList->GetName();
// Go through verts
- vector<Vertex> finalVerts = vector<Vertex>();
+ vector<ZVtx> finalVerts;
int32_t vStart = -1;
- for (pair<int32_t, vector<Vertex>> pair : zDisplayList->vertices)
+ for (auto& pair : zDisplayList->vertices)
{
if (vStart == -1) // TODO: Find a better way to do this
vStart = pair.first;
- for (Vertex v : pair.second)
+ for (auto& v : pair.second)
finalVerts.push_back(v);
}
@@ -85,14 +85,17 @@ void HLModelIntermediette::FromZDisplayList(HLModelIntermediette* model, ZDispla
model->blocks.push_back(vertIntr);
// Go through textures
+ // TODO: Textures are now stored directly in ZFile
+ /*
for (pair<uint32_t, ZTexture*> pair : zDisplayList->textures)
{
- HLTextureIntermediette* texIntr = new HLTextureIntermediette();
- texIntr->tex = pair.second;
- texIntr->name = texIntr->tex->GetName();
+ HLTextureIntermediette* texIntr = new HLTextureIntermediette();
+ texIntr->tex = pair.second;
+ texIntr->name = texIntr->tex->GetName();
- model->blocks.push_back(texIntr);
+ model->blocks.push_back(texIntr);
}
+ */
// Analyze display lists to determine components
HLDisplayListIntermediette* dList = new HLDisplayListIntermediette();
@@ -173,9 +176,10 @@ void HLModelIntermediette::FromZDisplayList(HLModelIntermediette* model, ZDispla
lastMat->clrM = lastClrM;
// Bit of a hack here...
- int32_t lastData = (int32_t)(zDisplayList->instructions[i - 1]);
- string texName = zDisplayList->textures[lastData & 0x00FFFFFF]->GetName();
- lastMat->textureName = texName;
+ // int32_t lastData = (int32_t)(zDisplayList->instructions[i - 1]);
+ // TODO
+ // string texName = zDisplayList->textures[lastData & 0x00FFFFFF]->GetName();
+ // lastMat->textureName = texName;
// --------------------------
model->blocks.push_back(mesh);
@@ -189,10 +193,11 @@ void HLModelIntermediette::FromZDisplayList(HLModelIntermediette* model, ZDispla
}
else if (opcode == F3DZEXOpcode::G_SETTIMG)
{
- int32_t texAddress = data & 0x00FFFFFF;
+ // int32_t texAddress = data & 0x00FFFFFF;
- string texName = zDisplayList->textures[texAddress]->GetName();
- lastMat->textureName = texName;
+ // TODO
+ // string texName = zDisplayList->textures[texAddress]->GetName();
+ // lastMat->textureName = texName;
}
else if (opcode == F3DZEXOpcode::G_VTX)
{
@@ -449,25 +454,27 @@ void HLMeshCommand::OutputXML(tinyxml2::XMLElement* parent)
HLVerticesIntermediette::HLVerticesIntermediette() : HLIntermediette()
{
- vertices = vector<Vertex>();
+ vertices = vector<ZVtx>();
}
void HLVerticesIntermediette::InitFromXML(XMLElement* verticesElement)
{
name = verticesElement->Attribute("Name");
+ /*
for (XMLElement* child = verticesElement->FirstChildElement(); child != NULL;
child = child->NextSiblingElement())
- vertices.push_back(Vertex(child->IntAttribute("X"), child->IntAttribute("Y"),
- child->IntAttribute("Z"), child->IntAttribute("Flags"),
- child->IntAttribute("S"), child->IntAttribute("T"),
- child->IntAttribute("R"), child->IntAttribute("G"),
- child->IntAttribute("B"), child->IntAttribute("A")));
+ vertices.push_back(ZVtx(child->IntAttribute("X"), child->IntAttribute("Y"),
+ child->IntAttribute("Z"), child->IntAttribute("Flags"),
+ child->IntAttribute("S"), child->IntAttribute("T"),
+ child->IntAttribute("R"), child->IntAttribute("G"),
+ child->IntAttribute("B"), child->IntAttribute("A")));
+ */
}
-void HLVerticesIntermediette::InitFromVertices(vector<Vertex> dispListVertices)
+void HLVerticesIntermediette::InitFromVertices(vector<ZVtx> dispListVertices)
{
- for (Vertex v : dispListVertices)
+ for (auto v : dispListVertices)
vertices.push_back(v);
}
@@ -477,7 +484,7 @@ string HLVerticesIntermediette::OutputCode(HLModelIntermediette* parent)
output += StringHelper::Sprintf("Vtx %s_verts[] = \n{\n", name.c_str());
- for (Vertex v : vertices)
+ for (auto v : vertices)
{
output += StringHelper::Sprintf(" { %i, %i, %i, %i, %i, %i, %i, %i, %i, %i },\n", v.x,
v.y, v.z, v.flag, v.s, v.t, v.r, v.g, v.b, v.a);
@@ -492,7 +499,7 @@ std::string HLVerticesIntermediette::OutputOBJ()
{
string output = "";
- for (Vertex v : vertices)
+ for (auto& v : vertices)
{
output += StringHelper::Sprintf("v %f %f %f %i %i %i %i\n", (float)v.x * 0.1f,
(float)v.y * 0.1f, (float)v.z * 0.1f, v.r, v.g, v.b, v.a);
@@ -517,7 +524,7 @@ void HLVerticesIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XM
element->SetAttribute("Name", name.c_str());
- for (Vertex v : vertices)
+ for (auto& v : vertices)
{
XMLElement* vElem = doc->NewElement("Vertex");
vElem->SetAttribute("X", v.x);
@@ -875,9 +882,10 @@ void HLTextureIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement)
// tex = HLTexture::FromPNG(fileName,
// (HLTextureType)ZTexture::GetTextureTypeFromString(format));
- tex = ZTexture::FromPNG(Path::GetDirectoryName(Globals::Instance->inputPath.string()) + "/" +
- fileName,
- ZTexture::GetTextureTypeFromString(format));
+ tex = new ZTexture(nullptr);
+ tex->ZTexture::FromPNG(Path::GetDirectoryName(Globals::Instance->inputPath.string()) + "/" +
+ fileName,
+ ZTexture::GetTextureTypeFromString(format));
}
std::string HLTextureIntermediette::OutputCode()
diff --git a/ZAPD/HighLevel/HLModelIntermediette.h b/ZAPD/HighLevel/HLModelIntermediette.h
index 5fda096..474b641 100644
--- a/ZAPD/HighLevel/HLModelIntermediette.h
+++ b/ZAPD/HighLevel/HLModelIntermediette.h
@@ -156,12 +156,12 @@ public:
class HLVerticesIntermediette : public HLIntermediette
{
public:
- std::vector<Vertex> vertices;
+ std::vector<ZVtx> vertices;
HLVerticesIntermediette();
virtual void InitFromXML(tinyxml2::XMLElement* verticesElement);
- void InitFromVertices(std::vector<Vertex> dispListVertices);
+ void InitFromVertices(std::vector<ZVtx> dispListVertices);
virtual std::string OutputCode(HLModelIntermediette* parent);
virtual std::string OutputOBJ();
virtual void OutputAssimp(aiScene* scene, std::vector<aiVector3D>* verts);
diff --git a/ZAPD/HighLevel/HLTexture.cpp b/ZAPD/HighLevel/HLTexture.cpp
index 0bf6b36..15abec9 100644
--- a/ZAPD/HighLevel/HLTexture.cpp
+++ b/ZAPD/HighLevel/HLTexture.cpp
@@ -1,16 +1,15 @@
#include "HLTexture.h"
-#include <stb_image.h>
#include "../StringHelper.h"
using namespace std;
HLTexture* HLTexture::FromPNG(std::string pngFilePath, HLTextureType texType)
{
- int32_t comp;
+ // int32_t comp;
HLTexture* tex = new HLTexture();
tex->type = texType;
- tex->bmpRgba = (uint8_t*)stbi_load((pngFilePath).c_str(), (int32_t*)&tex->width,
- (int32_t*)&tex->height, &comp, STBI_rgb_alpha);
+ // tex->bmpRgba = (uint8_t*)stbi_load((pngFilePath).c_str(), (int32_t*)&tex->width,
+ // (int32_t*)&tex->height, &comp, STBI_rgb_alpha);
return tex;
}
diff --git a/ZAPD/ImageBackend.cpp b/ZAPD/ImageBackend.cpp
new file mode 100644
index 0000000..0b4bce3
--- /dev/null
+++ b/ZAPD/ImageBackend.cpp
@@ -0,0 +1,473 @@
+#include "ImageBackend.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <png.h>
+#include <stdexcept>
+
+#include "StringHelper.h"
+
+/* ImageBackend */
+
+ImageBackend::~ImageBackend()
+{
+ FreeImageData();
+}
+
+void ImageBackend::ReadPng(const char* filename)
+{
+ FreeImageData();
+
+ FILE* fp = fopen(filename, "rb");
+ if (fp == nullptr)
+ throw std::runtime_error(StringHelper::Sprintf(
+ "ImageBackend::ReadPng: Error.\n\t Couldn't open file '%s'.", filename));
+
+ png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+ if (!png)
+ throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png struct.");
+
+ png_infop info = png_create_info_struct(png);
+ if (!info)
+ throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png info.");
+
+ if (setjmp(png_jmpbuf(png)))
+ throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t setjmp(png_jmpbuf(png)).");
+
+ png_init_io(png, fp);
+
+ png_read_info(png, info);
+
+ width = png_get_image_width(png, info);
+ height = png_get_image_height(png, info);
+ colorType = png_get_color_type(png, info);
+ bitDepth = png_get_bit_depth(png, info);
+
+#ifdef TEXTURE_DEBUG
+ printf("Width: %u\n", width);
+ printf("Height: %u\n", height);
+ printf("ColorType: ");
+ switch (colorType)
+ {
+ case PNG_COLOR_TYPE_RGBA:
+ printf("PNG_COLOR_TYPE_RGBA\n");
+ break;
+
+ case PNG_COLOR_TYPE_RGB:
+ printf("PNG_COLOR_TYPE_RGB\n");
+ break;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ printf("PNG_COLOR_TYPE_PALETTE\n");
+ break;
+
+ default:
+ printf("%u\n", colorType);
+ break;
+ }
+ printf("BitDepth: %u\n", bitDepth);
+ printf("\n");
+#endif
+
+ // Read any color_type into 8bit depth, RGBA format.
+ // See http://www.libpng.org/pub/png/libpng-manual.txt
+
+ if (bitDepth == 16)
+ png_set_strip_16(png);
+
+ if (colorType == PNG_COLOR_TYPE_PALETTE)
+ {
+ // png_set_palette_to_rgb(png);
+ isColorIndexed = true;
+ }
+
+ // PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
+ if (colorType == PNG_COLOR_TYPE_GRAY && bitDepth < 8)
+ png_set_expand_gray_1_2_4_to_8(png);
+
+ /*if (png_get_valid(png, info, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(png);*/
+
+ // These color_type don't have an alpha channel then fill it with 0xff.
+ /*if(*color_type == PNG_COLOR_TYPE_RGB ||
+ *color_type == PNG_COLOR_TYPE_GRAY ||
+ *color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_filler(png, 0xFF, PNG_FILLER_AFTER);*/
+
+ if (colorType == PNG_COLOR_TYPE_GRAY || colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
+ png_set_gray_to_rgb(png);
+
+ png_read_update_info(png, info);
+
+ size_t rowBytes = png_get_rowbytes(png, info);
+ pixelMatrix = (uint8_t**)malloc(sizeof(uint8_t*) * height);
+ for (size_t y = 0; y < height; y++)
+ {
+ pixelMatrix[y] = (uint8_t*)malloc(rowBytes);
+ }
+
+ png_read_image(png, pixelMatrix);
+
+#ifdef TEXTURE_DEBUG
+ printf("rowBytes: %zu\n", rowBytes);
+
+ size_t bytePerPixel = GetBytesPerPixel();
+ printf("imgData\n");
+ for (size_t y = 0; y < height; y++)
+ {
+ for (size_t x = 0; x < width; x++)
+ {
+ for (size_t z = 0; z < bytePerPixel; z++)
+ {
+ printf("%02X ", pixelMatrix[y][x * bytePerPixel + z]);
+ }
+ printf(" ");
+ }
+ printf("\n");
+ }
+ printf("\n");
+#endif
+
+ fclose(fp);
+
+ png_destroy_read_struct(&png, &info, nullptr);
+
+ hasImageData = true;
+}
+
+void ImageBackend::ReadPng(const fs::path& filename)
+{
+ ReadPng(filename.c_str());
+}
+
+void ImageBackend::WritePng(const char* filename)
+{
+ assert(hasImageData);
+
+ FILE* fp = fopen(filename, "wb");
+ if (!fp)
+ throw std::runtime_error(StringHelper::Sprintf(
+ "ImageBackend::WritePng: Error.\n\t Couldn't open file '%s' in write mode.", filename));
+
+ png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+ if (!png)
+ throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png struct.");
+
+ png_infop info = png_create_info_struct(png);
+ if (!info)
+ throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png info.");
+
+ if (setjmp(png_jmpbuf(png)))
+ throw std::runtime_error("ImageBackend::WritePng: Error.\n\t setjmp(png_jmpbuf(png)).");
+
+ png_init_io(png, fp);
+
+ png_set_IHDR(png, info, width, height,
+ bitDepth, // 8,
+ colorType, // PNG_COLOR_TYPE_RGBA,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
+
+ if (isColorIndexed)
+ {
+ png_set_PLTE(png, info, static_cast<png_color*>(colorPalette), paletteSize);
+
+#ifdef TEXTURE_DEBUG
+ printf("palette\n");
+ png_color* aux = (png_color*)colorPalette;
+ for (size_t y = 0; y < paletteSize; y++)
+ {
+ printf("#%02X%02X%02X ", aux[y].red, aux[y].green, aux[y].blue);
+ if ((y + 1) % 8 == 0)
+ printf("\n");
+ }
+ printf("\n");
+#endif
+
+ png_set_tRNS(png, info, alphaPalette, paletteSize, nullptr);
+ }
+
+ png_write_info(png, info);
+
+ // To remove the alpha channel for PNG_COLOR_TYPE_RGB format,
+ // Use png_set_filler().
+ // png_set_filler(png, 0, PNG_FILLER_AFTER);
+
+#ifdef TEXTURE_DEBUG
+ size_t bytePerPixel = GetBytesPerPixel();
+ printf("imgData\n");
+ for (size_t y = 0; y < height; y++)
+ {
+ for (size_t x = 0; x < width * bytePerPixel; x++)
+ {
+ printf("%02X ", pixelMatrix[y][x]);
+ }
+ printf("\n");
+ }
+ printf("\n");
+#endif
+
+ png_write_image(png, pixelMatrix);
+ png_write_end(png, nullptr);
+
+ fclose(fp);
+
+ png_destroy_write_struct(&png, &info);
+}
+
+void ImageBackend::WritePng(const fs::path& filename)
+{
+ WritePng(filename.c_str());
+}
+
+void ImageBackend::SetTextureData(const std::vector<std::vector<RGBAPixel>>& texData,
+ uint32_t nWidth, uint32_t nHeight, uint8_t nColorType,
+ uint8_t nBitDepth)
+{
+ FreeImageData();
+
+ width = nWidth;
+ height = nHeight;
+ colorType = nColorType;
+ bitDepth = nBitDepth;
+
+ size_t bytePerPixel = GetBytesPerPixel();
+
+ pixelMatrix = static_cast<uint8_t**>(malloc(sizeof(uint8_t*) * height));
+ for (size_t y = 0; y < height; y++)
+ {
+ pixelMatrix[y] = static_cast<uint8_t*>(malloc(sizeof(uint8_t*) * width * bytePerPixel));
+ for (size_t x = 0; x < width; x++)
+ {
+ pixelMatrix[y][x * bytePerPixel + 0] = texData.at(y).at(x).r;
+ pixelMatrix[y][x * bytePerPixel + 1] = texData.at(y).at(x).g;
+ pixelMatrix[y][x * bytePerPixel + 2] = texData.at(y).at(x).b;
+
+ if (colorType == PNG_COLOR_TYPE_RGBA)
+ pixelMatrix[y][x * bytePerPixel + 3] = texData.at(y).at(x).a;
+ }
+ }
+ hasImageData = true;
+}
+
+void ImageBackend::InitEmptyRGBImage(uint32_t nWidth, uint32_t nHeight, bool alpha)
+{
+ FreeImageData();
+
+ width = nWidth;
+ height = nHeight;
+ colorType = PNG_COLOR_TYPE_RGB;
+ if (alpha)
+ colorType = PNG_COLOR_TYPE_RGBA;
+ bitDepth = 8; // nBitDepth;
+
+ size_t bytePerPixel = GetBytesPerPixel();
+
+ pixelMatrix = static_cast<uint8_t**>(malloc(sizeof(uint8_t*) * height));
+ for (size_t y = 0; y < height; y++)
+ {
+ pixelMatrix[y] = static_cast<uint8_t*>(calloc(width * bytePerPixel, sizeof(uint8_t*)));
+ }
+
+ hasImageData = true;
+}
+
+void ImageBackend::InitEmptyPaletteImage(uint32_t nWidth, uint32_t nHeight)
+{
+ FreeImageData();
+
+ width = nWidth;
+ height = nHeight;
+ colorType = PNG_COLOR_TYPE_PALETTE;
+ bitDepth = 8;
+
+ size_t bytePerPixel = GetBytesPerPixel();
+
+ pixelMatrix = (uint8_t**)malloc(sizeof(uint8_t*) * height);
+ for (size_t y = 0; y < height; y++)
+ {
+ pixelMatrix[y] = static_cast<uint8_t*>(calloc(width * bytePerPixel, sizeof(uint8_t*)));
+ }
+ colorPalette = calloc(paletteSize, sizeof(png_color));
+ alphaPalette = static_cast<uint8_t*>(calloc(paletteSize, sizeof(uint8_t)));
+
+ hasImageData = true;
+ isColorIndexed = true;
+}
+
+RGBAPixel ImageBackend::GetPixel(size_t y, size_t x) const
+{
+ assert(y < height);
+ assert(x < width);
+ assert(!isColorIndexed);
+
+ RGBAPixel pixel;
+ size_t bytePerPixel = GetBytesPerPixel();
+ pixel.r = pixelMatrix[y][x * bytePerPixel + 0];
+ pixel.g = pixelMatrix[y][x * bytePerPixel + 1];
+ pixel.b = pixelMatrix[y][x * bytePerPixel + 2];
+ if (colorType == PNG_COLOR_TYPE_RGBA)
+ pixel.a = pixelMatrix[y][x * bytePerPixel + 3];
+ return pixel;
+}
+
+uint8_t ImageBackend::GetIndexedPixel(size_t y, size_t x) const
+{
+ assert(y < height);
+ assert(x < width);
+ assert(isColorIndexed);
+
+ return pixelMatrix[y][x];
+}
+
+void ImageBackend::SetRGBPixel(size_t y, size_t x, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
+{
+ assert(hasImageData);
+ assert(y < height);
+ assert(x < width);
+
+ size_t bytePerPixel = GetBytesPerPixel();
+ pixelMatrix[y][x * bytePerPixel + 0] = nR;
+ pixelMatrix[y][x * bytePerPixel + 1] = nG;
+ pixelMatrix[y][x * bytePerPixel + 2] = nB;
+ if (colorType == PNG_COLOR_TYPE_RGBA)
+ pixelMatrix[y][x * bytePerPixel + 3] = nA;
+}
+
+void ImageBackend::SetGrayscalePixel(size_t y, size_t x, uint8_t grayscale, uint8_t alpha)
+{
+ assert(hasImageData);
+ assert(y < height);
+ assert(x < width);
+
+ size_t bytePerPixel = GetBytesPerPixel();
+ pixelMatrix[y][x * bytePerPixel + 0] = grayscale;
+ pixelMatrix[y][x * bytePerPixel + 1] = grayscale;
+ pixelMatrix[y][x * bytePerPixel + 2] = grayscale;
+ if (colorType == PNG_COLOR_TYPE_RGBA)
+ pixelMatrix[y][x * bytePerPixel + 3] = alpha;
+}
+
+void ImageBackend::SetIndexedPixel(size_t y, size_t x, uint8_t index, uint8_t grayscale)
+{
+ assert(hasImageData);
+ assert(y < height);
+ assert(x < width);
+
+ size_t bytePerPixel = GetBytesPerPixel();
+ pixelMatrix[y][x * bytePerPixel + 0] = index;
+
+ assert(index < paletteSize);
+ png_color* pal = static_cast<png_color*>(colorPalette);
+ pal[index].red = grayscale;
+ pal[index].green = grayscale;
+ pal[index].blue = grayscale;
+ alphaPalette[index] = 255;
+}
+
+void ImageBackend::SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
+{
+ assert(isColorIndexed);
+ assert(index < paletteSize);
+
+ png_color* pal = static_cast<png_color*>(colorPalette);
+ pal[index].red = nR;
+ pal[index].green = nG;
+ pal[index].blue = nB;
+ alphaPalette[index] = nA;
+}
+
+void ImageBackend::SetPalette(const ImageBackend& pal)
+{
+ assert(isColorIndexed);
+ size_t bytePerPixel = pal.GetBytesPerPixel();
+
+ for (size_t y = 0; y < pal.height; y++)
+ {
+ for (size_t x = 0; x < pal.width; x++)
+ {
+ uint8_t r = pal.pixelMatrix[y][x * bytePerPixel + 0];
+ uint8_t g = pal.pixelMatrix[y][x * bytePerPixel + 1];
+ uint8_t b = pal.pixelMatrix[y][x * bytePerPixel + 2];
+ uint8_t a = pal.pixelMatrix[y][x * bytePerPixel + 3];
+ SetPaletteIndex(y * pal.width + x, r, g, b, a);
+ }
+ }
+}
+
+uint32_t ImageBackend::GetWidth() const
+{
+ return width;
+}
+
+uint32_t ImageBackend::GetHeight() const
+{
+ return height;
+}
+
+uint8_t ImageBackend::GetColorType() const
+{
+ return colorType;
+}
+
+uint8_t ImageBackend::GetBitDepth() const
+{
+ return bitDepth;
+}
+
+double ImageBackend::GetBytesPerPixel() const
+{
+ switch (colorType)
+ {
+ case PNG_COLOR_TYPE_RGBA:
+ return 4 * bitDepth / 8;
+
+ case PNG_COLOR_TYPE_RGB:
+ return 3 * bitDepth / 8;
+
+ case PNG_COLOR_TYPE_PALETTE:
+ return 1 * bitDepth / 8;
+
+ default:
+ throw std::invalid_argument("ImageBackend::GetBytesPerPixel():\n\t Invalid color type.");
+ }
+}
+
+void ImageBackend::FreeImageData()
+{
+ if (hasImageData)
+ {
+ for (size_t y = 0; y < height; y++)
+ free(pixelMatrix[y]);
+ free(pixelMatrix);
+ pixelMatrix = nullptr;
+ }
+
+ if (isColorIndexed)
+ {
+ free(colorPalette);
+ free(alphaPalette);
+ colorPalette = nullptr;
+ alphaPalette = nullptr;
+ isColorIndexed = false;
+ }
+
+ hasImageData = false;
+}
+
+/* RGBAPixel */
+
+void RGBAPixel::SetRGBA(uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
+{
+ r = nR;
+ g = nG;
+ b = nB;
+ a = nA;
+}
+
+void RGBAPixel::SetGrayscale(uint8_t grayscale, uint8_t alpha)
+{
+ r = grayscale;
+ g = grayscale;
+ b = grayscale;
+ a = alpha;
+}
diff --git a/ZAPD/ImageBackend.h b/ZAPD/ImageBackend.h
new file mode 100644
index 0000000..25ab832
--- /dev/null
+++ b/ZAPD/ImageBackend.h
@@ -0,0 +1,71 @@
+#pragma once
+
+#include <cstdint>
+#include <vector>
+
+#include "Directory.h"
+
+class RGBAPixel
+{
+public:
+ RGBAPixel() = default;
+
+ void SetRGBA(uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA);
+ void SetGrayscale(uint8_t grayscale, uint8_t alpha = 0);
+
+ uint8_t r = 0;
+ uint8_t g = 0;
+ uint8_t b = 0;
+ uint8_t a = 0;
+};
+
+class ImageBackend
+{
+public:
+ ImageBackend() = default;
+ ~ImageBackend();
+
+ void ReadPng(const char* filename);
+ void ReadPng(const fs::path& filename);
+ void WritePng(const char* filename);
+ void WritePng(const fs::path& filename);
+
+ void SetTextureData(const std::vector<std::vector<RGBAPixel>>& texData, uint32_t nWidth,
+ uint32_t nHeight, uint8_t nColorType, uint8_t nBitDepth);
+ void InitEmptyRGBImage(uint32_t nWidth, uint32_t nHeight, bool alpha);
+ void InitEmptyPaletteImage(uint32_t nWidth, uint32_t nHeight);
+
+ RGBAPixel GetPixel(size_t y, size_t x) const;
+ uint8_t GetIndexedPixel(size_t y, size_t x) const;
+
+ void SetRGBPixel(size_t y, size_t x, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA = 0);
+ void SetGrayscalePixel(size_t y, size_t x, uint8_t grayscale, uint8_t alpha = 0);
+
+ void SetIndexedPixel(size_t y, size_t x, uint8_t index, uint8_t grayscale);
+ void SetPaletteIndex(size_t index, uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA);
+ void SetPalette(const ImageBackend& pal);
+
+ uint32_t GetWidth() const;
+ uint32_t GetHeight() const;
+ uint8_t GetColorType() const;
+ uint8_t GetBitDepth() const;
+
+protected:
+ uint8_t** pixelMatrix = nullptr; // height * [width * bytePerPixel]
+
+ void* colorPalette = nullptr;
+ uint8_t* alphaPalette = nullptr;
+ size_t paletteSize = 16 * 16;
+
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint8_t colorType = 0;
+ uint8_t bitDepth = 0;
+
+ bool hasImageData = false;
+ bool isColorIndexed = false;
+
+ double GetBytesPerPixel() const;
+
+ void FreeImageData();
+};
diff --git a/ZAPD/Main.cpp b/ZAPD/Main.cpp
index 16e5960..51af8a6 100644
--- a/ZAPD/Main.cpp
+++ b/ZAPD/Main.cpp
@@ -43,9 +43,15 @@ void ErrorHandler(int sig)
size_t size = backtrace(array, nMaxFrames);
char** symbols = backtrace_symbols(array, nMaxFrames);
- // To prevent unused parameter warning
- (void)sig;
+ fprintf(stderr, "\nZAPD crashed. (Signal: %i)\n", sig);
+ fprintf(stderr, "\n\t\tYou've met with a terrible fate, haven't you?\n\n");
+ /**
+ * Other possible options:
+ * - SEA BEARS FOAM. SLEEP BEARS DREAMS. \n BOTH END IN THE SAME WAY: CRASSSH!
+ */
+
+ fprintf(stderr, "Traceback:\n");
for (size_t i = 1; i < size; i++)
{
Dl_info info;
@@ -71,7 +77,8 @@ void ErrorHandler(int sig)
fprintf(stderr, "%-3zd %s\n", i, functionName.c_str());
}
- // backtrace_symbols_fd(array, size, STDERR_FILENO);
+ fprintf(stderr, "\n");
+
free(symbols);
exit(1);
}
@@ -160,6 +167,11 @@ int main(int argc, char* argv[])
Globals::Instance->testMode = string(argv[i + 1]) == "1";
i++;
}
+ else if (arg == "-crc" ||
+ arg == "--output-crc") // Outputs a CRC file for each extracted texture.
+ {
+ Globals::Instance->outputCrc = true;
+ }
else if (arg == "-ulzdl") // Use Legacy ZDisplay List
{
Globals::Instance->useLegacyZDList = string(argv[i + 1]) == "1";
@@ -200,7 +212,8 @@ int main(int argc, char* argv[])
signal(SIGSEGV, ErrorHandler);
signal(SIGABRT, ErrorHandler);
#else
- printf("Warning: Tried to set error handler, but this build lacks support for one.\n");
+ fprintf(stderr,
+ "Warning: Tried to set error handler, but this build lacks support for one.\n");
#endif
}
else if (arg == "-v") // Verbose
@@ -216,55 +229,47 @@ int main(int argc, char* argv[])
if (Globals::Instance->verbosity >= VERBOSITY_INFO)
printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash);
- try
+ if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile)
{
- if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile)
- {
- bool parseSuccessful =
- Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath,
- Globals::Instance->outputPath, fileMode);
+ bool parseSuccessful = Parse(Globals::Instance->inputPath, Globals::Instance->baseRomPath,
+ Globals::Instance->outputPath, fileMode);
- if (!parseSuccessful)
- return 1;
- }
- else if (fileMode == ZFileMode::BuildTexture)
- {
- TextureType texType = Globals::Instance->texType;
-
- BuildAssetTexture(Globals::Instance->inputPath, texType, Globals::Instance->outputPath);
- }
- else if (fileMode == ZFileMode::BuildBackground)
- {
- BuildAssetBackground(Globals::Instance->inputPath, Globals::Instance->outputPath);
- }
- else if (fileMode == ZFileMode::BuildBlob)
- {
- BuildAssetBlob(Globals::Instance->inputPath, Globals::Instance->outputPath);
- }
- else if (fileMode == ZFileMode::BuildModelIntermediette)
- {
- BuildAssetModelIntermediette(Globals::Instance->outputPath);
- }
- else if (fileMode == ZFileMode::BuildAnimationIntermediette)
- {
- BuildAssetAnimationIntermediette(Globals::Instance->inputPath,
- Globals::Instance->outputPath);
- }
- else if (fileMode == ZFileMode::BuildOverlay)
- {
- ZOverlay* overlay =
- ZOverlay::FromBuild(Path::GetDirectoryName(Globals::Instance->inputPath.string()),
- Path::GetDirectoryName(Globals::Instance->cfgPath.string()));
-
- if (overlay)
- File::WriteAllText(Globals::Instance->outputPath.string(),
- overlay->GetSourceOutputCode(""));
- }
+ if (!parseSuccessful)
+ return 1;
+ }
+ else if (fileMode == ZFileMode::BuildTexture)
+ {
+ TextureType texType = Globals::Instance->texType;
+ BuildAssetTexture(Globals::Instance->inputPath, texType, Globals::Instance->outputPath);
+ }
+ else if (fileMode == ZFileMode::BuildBackground)
+ {
+ BuildAssetBackground(Globals::Instance->inputPath, Globals::Instance->outputPath);
+ }
+ else if (fileMode == ZFileMode::BuildBlob)
+ {
+ BuildAssetBlob(Globals::Instance->inputPath, Globals::Instance->outputPath);
+ }
+ else if (fileMode == ZFileMode::BuildModelIntermediette)
+ {
+ BuildAssetModelIntermediette(Globals::Instance->outputPath);
+ }
+ else if (fileMode == ZFileMode::BuildAnimationIntermediette)
+ {
+ BuildAssetAnimationIntermediette(Globals::Instance->inputPath,
+ Globals::Instance->outputPath);
}
- catch (std::runtime_error& e)
+ else if (fileMode == ZFileMode::BuildOverlay)
{
- printf("Exception occurred: %s\n", e.what());
+ ZOverlay* overlay =
+ ZOverlay::FromBuild(Path::GetDirectoryName(Globals::Instance->inputPath),
+ Path::GetDirectoryName(Globals::Instance->cfgPath));
+
+ if (overlay)
+ File::WriteAllText(Globals::Instance->outputPath.string(),
+ overlay->GetSourceOutputCode(""));
}
+
delete g;
return 0;
}
@@ -327,17 +332,16 @@ void BuildAssetTexture(const fs::path& pngFilePath, TextureType texType, const f
{
string name = outPath.stem().string();
- ZTexture* tex = ZTexture::FromPNG(pngFilePath.string(), texType);
+ ZTexture tex(nullptr);
+ tex.FromPNG(pngFilePath, texType);
string cfgPath = StringHelper::Split(pngFilePath.string(), ".")[0] + ".cfg";
if (File::Exists(cfgPath))
name = File::ReadAllText(cfgPath);
- string src = tex->GetSourceOutputCode(name);
+ string src = tex.GetBodySourceCode();
File::WriteAllText(outPath.string(), src);
-
- delete tex;
}
void BuildAssetBackground(const fs::path& imageFilePath, const fs::path& outPath)
diff --git a/ZAPD/Path.h b/ZAPD/Path.h
index a5c073c..68cfaea 100644
--- a/ZAPD/Path.h
+++ b/ZAPD/Path.h
@@ -46,8 +46,8 @@ public:
return output;
};
- static std::string GetDirectoryName(const std::string& path)
+ static std::string GetDirectoryName(const fs::path& path)
{
- return fs::path(path).parent_path().u8string();
+ return path.parent_path().u8string();
};
};
diff --git a/ZAPD/StringHelper.h b/ZAPD/StringHelper.h
index 3d63a74..e04bc08 100644
--- a/ZAPD/StringHelper.h
+++ b/ZAPD/StringHelper.h
@@ -92,4 +92,9 @@ public:
return ss.empty() ? s : ss + separator + s;
});
}
+
+ static int64_t StrToL(const std::string& str, int32_t base = 10)
+ {
+ return std::strtoull(str.c_str(), nullptr, base);
+ }
};
diff --git a/ZAPD/ZAnimation.cpp b/ZAPD/ZAnimation.cpp
index e111dc5..3274cb3 100644
--- a/ZAPD/ZAnimation.cpp
+++ b/ZAPD/ZAnimation.cpp
@@ -26,13 +26,13 @@ void ZAnimation::ParseRawData()
frameCount = BitConverter::ToInt16BE(data, rawDataIndex + 0);
}
-void ZAnimation::Save(const std::string& outFolder)
+void ZAnimation::Save(const fs::path& outFolder)
{
if (Globals::Instance->testMode)
{
HLAnimationIntermediette* anim = HLAnimationIntermediette::FromZAnimation(this);
string xml = anim->OutputXML();
- File::WriteAllText(outFolder + "/" + name + ".anmi", xml);
+ File::WriteAllText(outFolder / (name + ".anmi"), xml);
delete anim;
}
diff --git a/ZAPD/ZAnimation.h b/ZAPD/ZAnimation.h
index de57bca..b79d780 100644
--- a/ZAPD/ZAnimation.h
+++ b/ZAPD/ZAnimation.h
@@ -33,7 +33,7 @@ public:
protected:
void ParseRawData() override;
- void Save(const std::string& outFolder) override;
+ void Save(const fs::path& outFolder) override;
void ParseXML(tinyxml2::XMLElement* reader) override;
};
diff --git a/ZAPD/ZBackground.cpp b/ZAPD/ZBackground.cpp
index a877c70..a3c9a1b 100644
--- a/ZAPD/ZBackground.cpp
+++ b/ZAPD/ZBackground.cpp
@@ -156,10 +156,9 @@ std::string ZBackground::GetExternalExtension()
return "jpg";
}
-void ZBackground::Save(const std::string& outFolder)
+void ZBackground::Save(const fs::path& outFolder)
{
- fs::path folder(outFolder);
- fs::path filepath = folder / (outName + "." + GetExternalExtension());
+ fs::path filepath = outFolder / (outName + "." + GetExternalExtension());
File::WriteAllBytes(filepath.string(), data);
}
diff --git a/ZAPD/ZBackground.h b/ZAPD/ZBackground.h
index 000a2a1..4b4897f 100644
--- a/ZAPD/ZBackground.h
+++ b/ZAPD/ZBackground.h
@@ -26,7 +26,7 @@ public:
bool IsExternalResource() override;
std::string GetExternalExtension() override;
- void Save(const std::string& outFolder) override;
+ void Save(const fs::path& outFolder) override;
std::string GetBodySourceCode();
std::string GetSourceOutputCode(const std::string& prefix) override;
diff --git a/ZAPD/ZBlob.cpp b/ZAPD/ZBlob.cpp
index 171433e..3b060f4 100644
--- a/ZAPD/ZBlob.cpp
+++ b/ZAPD/ZBlob.cpp
@@ -85,9 +85,9 @@ string ZBlob::GetSourceOutputHeader(const std::string& prefix)
return StringHelper::Sprintf("extern u8 %s[];\n", name.c_str());
}
-void ZBlob::Save(const std::string& outFolder)
+void ZBlob::Save(const fs::path& outFolder)
{
- File::WriteAllBytes(outFolder + "/" + name + ".bin", rawData);
+ File::WriteAllBytes(outFolder / (name + ".bin"), rawData);
}
bool ZBlob::IsExternalResource()
diff --git a/ZAPD/ZBlob.h b/ZAPD/ZBlob.h
index bfc8a30..e17327e 100644
--- a/ZAPD/ZBlob.h
+++ b/ZAPD/ZBlob.h
@@ -18,7 +18,7 @@ public:
static ZBlob* FromFile(const std::string& filePath);
std::string GetSourceOutputCode(const std::string& prefix) override;
std::string GetSourceOutputHeader(const std::string& prefix) override;
- void Save(const std::string& outFolder) override;
+ void Save(const fs::path& outFolder) override;
bool IsExternalResource() override;
std::string GetExternalExtension() override;
std::string GetSourceTypeName() override;
diff --git a/ZAPD/ZDisplayList.cpp b/ZAPD/ZDisplayList.cpp
index fafdd99..9d71bff 100644
--- a/ZAPD/ZDisplayList.cpp
+++ b/ZAPD/ZDisplayList.cpp
@@ -34,20 +34,12 @@ ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent)
fileData = vector<uint8_t>();
instructions = vector<uint64_t>();
- vertices = map<uint32_t, vector<Vertex>>();
vtxDeclarations = map<uint32_t, string>();
otherDLists = vector<ZDisplayList*>();
- textures = map<uint32_t, ZTexture*>();
- texDeclarations = map<uint32_t, std::string>();
}
ZDisplayList::~ZDisplayList()
{
- for (auto t : textures)
- {
- delete t.second;
- }
-
for (auto o : otherDLists)
{
delete o;
@@ -62,7 +54,6 @@ void ZDisplayList::ExtractFromXML(tinyxml2::XMLElement* reader,
rawDataIndex = nRawDataIndex;
ParseXML(reader);
- // name = reader->Attribute("Name");
fileData = nRawData;
int32_t rawDataSize = ZDisplayList::GetDListLength(
nRawData, rawDataIndex,
@@ -511,36 +502,19 @@ int32_t ZDisplayList::OptimizationCheck_LoadTextureBlock(int32_t startIndex, str
texAddr = Seg2Filespace(data, parent->baseAddress);
int32_t segmentNumber = GETSEGNUM(data);
- lastTexSeg = (data & 0xFF000000);
-
- Declaration* texDecl = nullptr;
+ lastTexSeg = segmentNumber;
- if (parent != nullptr &&
- segmentNumber != 2) // HACK: Until we have declarations use segment addresses,
- // we'll exclude scene references...
- {
- texDecl = parent->GetDeclaration(texAddr);
-
- if (texDecl == nullptr)
- texDecl = parent->GetDeclaration(data);
- }
+ ZFile* auxParent = parent;
+ if (parent->segment != segmentNumber && Globals::Instance->HasSegment(segmentNumber))
+ auxParent = Globals::Instance->segmentRefFiles.at(segmentNumber);
- if (texAddr != 0)
- {
- if (texDecl != nullptr)
- texStr = StringHelper::Sprintf("%s", texDecl->varName.c_str());
- else if (segmentNumber == 2)
- texStr = StringHelper::Sprintf("%sTex_%06X", scene->GetName().c_str(), texAddr);
- else if (!Globals::Instance->HasSegment(
- segmentNumber)) // Probably an external asset we are unable to track
- texStr = StringHelper::Sprintf("0x%06X", data);
- else
- texStr = StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), texAddr);
- }
- else if (segmentNumber != 3)
- texStr = StringHelper::Sprintf("0x%06X", data);
+ Declaration* decl = auxParent->GetDeclaration(texAddr);
+ if (Globals::Instance->HasSegment(segmentNumber) && decl != nullptr)
+ texStr = decl->varName;
+ else if (lastTexture != nullptr)
+ texStr = lastTexture->GetName();
else
- texStr = StringHelper::Sprintf("0");
+ texStr = auxParent->GetDeclarationPtrName(data & 0xFFFFFFFF);
}
// gsDPSetTile
@@ -879,12 +853,15 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, char* line)
if (nn > 0)
{
- vector<Vertex> vtxList = vector<Vertex>();
+ std::vector<ZVtx> vtxList;
vtxList.reserve(nn);
for (int32_t i = 0; i < nn; i++)
{
- Vertex vtx = Vertex(fileData, currentPtr);
+ ZVtx vtx(parent);
+ vtx.SetRawData(fileData);
+ vtx.SetRawDataIndex(currentPtr);
+ vtx.ParseRawData();
vtxList.push_back(vtx);
currentPtr += 16;
@@ -955,9 +932,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, std::string prefix, char* lin
sprintf(texStr, "%sTex_%06X", prefix.c_str(), texAddress);
else
{
- {
- sprintf(texStr, "0x%08lX", data & 0xFFFFFFFF);
- }
+ sprintf(texStr, "0x%08lX", data & 0xFFFFFFFF);
}
sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt].c_str(),
@@ -1559,12 +1534,42 @@ string ZDisplayList::GetSourceOutputHeader(const std::string& prefix)
static int32_t GfxdCallback_FormatSingleEntry(void)
{
+ ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get());
gfxd_puts("\t");
gfxd_macro_dflt();
gfxd_puts(",");
+ auto macroId = gfxd_macro_id();
+
+ switch (macroId)
+ {
+ case gfxd_SP1Triangle:
+ case gfxd_SP2Triangles:
+ if (self->lastTexture != nullptr && self->lastTexture->IsColorIndexed() &&
+ !self->lastTexture->HasTlut())
+ {
+ auto tex = self->lastTexture;
+ auto tlut = self->lastTlut;
+
+ if (Globals::Instance->verbosity >= VERBOSITY_DEBUG)
+ {
+ if (tlut != nullptr)
+ printf("CI texture '%s' (0x%X), TLUT: '%s' (0x%X)\n", tex->GetName().c_str(),
+ tex->GetRawDataIndex(), tlut->GetName().c_str(),
+ tlut->GetRawDataIndex());
+ else
+ printf("CI texture '%s' (0x%X), TLUT: null\n", tex->GetName().c_str(),
+ tex->GetRawDataIndex());
+ }
+
+ if (tlut != nullptr && !tex->HasTlut())
+ tex->SetTlut(tlut);
+ }
+ break;
+ }
+
// dont print a new line after the last command
- if (gfxd_macro_id() != gfxd_SPEndDisplayList)
+ if (macroId != gfxd_SPEndDisplayList)
{
gfxd_puts("\n");
}
@@ -1578,8 +1583,8 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count)
uint32_t vtxOffset = Seg2Filespace(seg, self->parent->baseAddress);
string vtxName = "";
- if (!Globals::Instance->HasSegment(
- GETSEGNUM(seg))) // Probably an external asset we are unable to track
+ // Probably an external asset we are unable to track
+ if (!Globals::Instance->HasSegment(GETSEGNUM(seg)))
{
vtxName = StringHelper::Sprintf("0x%08X", seg);
}
@@ -1615,13 +1620,17 @@ static int32_t GfxdCallback_Vtx(uint32_t seg, int32_t count)
if (count > 0)
{
- vector<Vertex> vtxList = vector<Vertex>();
+ std::vector<ZVtx> vtxList;
vtxList.reserve(count);
uint32_t currentPtr = vtxOffset;
for (int32_t i = 0; i < count; i++)
{
- Vertex vtx = Vertex(self->fileData, currentPtr);
+ ZVtx vtx(self->parent);
+ vtx.SetRawData(self->fileData);
+ vtx.SetRawDataIndex(currentPtr);
+ vtx.ParseRawData();
+
vtxList.push_back(vtx);
currentPtr += 16;
}
@@ -1641,29 +1650,7 @@ static int32_t GfxdCallback_Texture(segptr_t seg, int32_t fmt, int32_t siz, int3
{
ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get());
uint32_t texOffset = Seg2Filespace(seg, self->parent->baseAddress);
- uint32_t texSegNum = GETSEGNUM(seg);
- Declaration* texDecl = nullptr;
- string texName = "";
-
- if (self->parent != nullptr &&
- texSegNum != SEGMENT_SCENE) // HACK: Until we have declarations use segment addresses,
- // we'll exclude scene references...
- {
- texDecl = self->parent->GetDeclaration(texOffset);
-
- if (texDecl == nullptr)
- texDecl = self->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", self->scene->GetName().c_str(), texOffset);
- else
- texName = StringHelper::Sprintf("%sTex_%06X", self->curPrefix.c_str(), texOffset);
+ int32_t texSegNum = GETSEGNUM(seg);
self->lastTexWidth = width;
self->lastTexHeight = height;
@@ -1676,6 +1663,20 @@ static int32_t GfxdCallback_Texture(segptr_t seg, int32_t fmt, int32_t siz, int3
self->TextureGenCheck(self->curPrefix);
+ std::string texName = "";
+
+ ZFile* auxParent = self->parent;
+ if (self->parent->segment != texSegNum && Globals::Instance->HasSegment(texSegNum))
+ auxParent = Globals::Instance->segmentRefFiles.at(texSegNum);
+
+ Declaration* decl = auxParent->GetDeclaration(texOffset);
+ if (Globals::Instance->HasSegment(texSegNum) && decl != nullptr)
+ texName = decl->varName;
+ else if (self->lastTexture != nullptr)
+ texName = self->lastTexture->GetName();
+ else
+ texName = auxParent->GetDeclarationPtrName(seg);
+
gfxd_puts(texName.c_str());
return 1;
@@ -1685,28 +1686,7 @@ static int32_t GfxdCallback_Palette(uint32_t seg, int32_t idx, int32_t count)
{
ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get());
uint32_t palOffset = Seg2Filespace(seg, self->parent->baseAddress);
- uint32_t palSegNum = GETSEGNUM(seg);
- Declaration* palDecl = nullptr;
- string palName = "";
-
- if (self->parent != nullptr && palSegNum != 2) // HACK: Until we have declarations use segment
- // addresses, we'll exclude scene references...
- {
- palDecl = self->parent->GetDeclaration(palOffset);
-
- if (palDecl == nullptr)
- palDecl = self->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", self->scene->GetName().c_str(), palOffset);
- else
- palName = StringHelper::Sprintf("%sTex_%06X", self->curPrefix.c_str(), palOffset);
+ int32_t palSegNum = GETSEGNUM(seg);
self->lastTexWidth = sqrt(count);
self->lastTexHeight = sqrt(count);
@@ -1718,6 +1698,21 @@ static int32_t GfxdCallback_Palette(uint32_t seg, int32_t idx, int32_t count)
self->lastTexIsPalette = true;
self->TextureGenCheck(self->curPrefix);
+
+ std::string palName = "";
+
+ ZFile* auxParent = self->parent;
+ if (self->parent->segment != palSegNum && Globals::Instance->HasSegment(palSegNum))
+ auxParent = Globals::Instance->segmentRefFiles.at(palSegNum);
+
+ Declaration* decl = auxParent->GetDeclaration(palOffset);
+ if (Globals::Instance->HasSegment(palSegNum) && decl != nullptr)
+ palName = decl->varName;
+ else if (self->lastTlut != nullptr)
+ palName = self->lastTlut->GetName();
+ else
+ palName = auxParent->GetDeclarationPtrName(seg);
+
gfxd_puts(palName.c_str());
return 1;
@@ -1727,20 +1722,7 @@ static int32_t GfxdCallback_DisplayList(uint32_t seg)
{
ZDisplayList* self = static_cast<ZDisplayList*>(gfxd_udata_get());
uint32_t dListOffset = GETSEGOFFSET(seg);
- uint32_t dListSegNum = GETSEGNUM(seg);
- Declaration* dListDecl = nullptr;
- string dListName = "";
-
- if (self->parent != nullptr)
- dListDecl = self->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", self->curPrefix.c_str(), dListOffset);
+ int32_t dListSegNum = GETSEGNUM(seg);
if ((dListSegNum <= 6) && Globals::Instance->HasSegment(dListSegNum))
{
@@ -1752,6 +1734,12 @@ static int32_t GfxdCallback_DisplayList(uint32_t seg)
self->otherDLists.push_back(newDList);
}
+ ZFile* auxParent = self->parent;
+ if (self->parent->segment != dListSegNum && Globals::Instance->HasSegment(dListSegNum))
+ auxParent = Globals::Instance->segmentRefFiles.at(dListSegNum);
+
+ std::string dListName = auxParent->GetDeclarationPtrName(seg);
+
gfxd_puts(dListName.c_str());
return 1;
@@ -1802,10 +1790,7 @@ string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
// Iterate through our vertex lists, connect intersecting lists.
if (vertices.size() > 0)
{
- vector<pair<int32_t, vector<Vertex>>> verticesSorted(vertices.begin(), vertices.end());
-
- sort(verticesSorted.begin(), verticesSorted.end(),
- [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; });
+ vector<pair<int32_t, vector<ZVtx>>> verticesSorted(vertices.begin(), vertices.end());
for (size_t i = 0; i < verticesSorted.size() - 1; i++)
{
@@ -1840,20 +1825,18 @@ string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
parent->defines += defines;
// Generate Vertex Declarations
- for (pair<int32_t, vector<Vertex>> item : vertices)
+ for (auto& item : vertices)
{
string declaration = "";
- int32_t curAddr = item.first;
+ uint32_t curAddr = item.first;
- for (Vertex vtx : item.second)
+ for (auto vtx : item.second)
{
if (curAddr != item.first)
declaration += "\n";
- declaration +=
- StringHelper::Sprintf(" VTX(%i, %i, %i, %i, %i, %i, %i, %i, %i),", vtx.x,
- vtx.y, vtx.z, vtx.s, vtx.t, vtx.r, vtx.g, vtx.b, vtx.a);
+ declaration += vtx.GetBodySourceCode();
curAddr += 16;
}
@@ -1873,116 +1856,9 @@ string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
// Check for texture intersections
{
- if (scene != nullptr && scene->textures.size() != 0)
+ if (scene != nullptr)
{
- vector<pair<uint32_t, ZTexture*>> texturesSorted(scene->textures.begin(),
- scene->textures.end());
-
- sort(texturesSorted.begin(), texturesSorted.end(),
- [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; });
-
- for (size_t i = 0; i < texturesSorted.size() - 1; i++)
- {
- int32_t texSize = scene->textures[texturesSorted[i].first]->GetRawDataSize();
-
- if ((texturesSorted[i].first + texSize) > texturesSorted[i + 1].first)
- {
- defines += StringHelper::Sprintf(
- "#define %sTex_%06X ((u32)%sTex_%06X + 0x%06X)\n", scene->GetName().c_str(),
- texturesSorted[i + 1].first, scene->GetName().c_str(),
- texturesSorted[i].first,
- texturesSorted[i + 1].first - texturesSorted[i].first);
-
- scene->parent->declarations.erase(texturesSorted[i + 1].first);
- scene->textures.erase(texturesSorted[i + 1].first);
- texturesSorted.erase(texturesSorted.begin() + i + 1);
-
- i--;
- }
- }
-
- scene->extDefines += defines;
- }
-
- {
- vector<pair<uint32_t, ZTexture*>> texturesSorted(textures.begin(), textures.end());
-
- sort(texturesSorted.begin(), texturesSorted.end(),
- [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; });
-
- for (size_t i = 0; i < texturesSorted.size() - 1; i++)
- {
- if (texturesSorted.size() == 0) // ?????
- break;
-
- int32_t texSize = textures[texturesSorted[i].first]->GetRawDataSize();
-
- if ((texturesSorted[i].first + texSize) > texturesSorted[i + 1].first)
- {
- // int32_t intersectAmt = (texturesSorted[i].first + texSize) - texturesSorted[i
- // + 1].first;
-
- // If we're working with a palette, resize it to its "real" dimensions
- if (texturesSorted[i].second->isPalette)
- {
- texturesSorted[i].second->SetWidth(
- (texturesSorted[i + 1].first - texturesSorted[i].first) / 2);
- texturesSorted[i].second->SetHeight(1);
- }
- else
- {
- defines += StringHelper::Sprintf(
- "#define %sTex_%06X ((u32)%sTex_%06X + 0x%06X)\n", prefix.c_str(),
- texturesSorted[i + 1].first, prefix.c_str(), texturesSorted[i].first,
- texturesSorted[i + 1].first - texturesSorted[i].first);
-
- textures.erase(texturesSorted[i + 1].first);
- texturesSorted.erase(texturesSorted.begin() + i + 1);
-
- i--;
- }
- }
- }
- }
-
- // Generate Texture Declarations
- for (pair<int32_t, ZTexture*> item : textures)
- {
- string declaration = "";
-
- declaration += item.second->GetSourceOutputCode(prefix);
- texDeclarations[item.first] = declaration;
-
- if (parent != nullptr)
- {
- if (parent->GetDeclaration(item.first) == nullptr)
- {
- // TEXTURE POOL CHECK
- std::string texOutPath =
- item.second->GetPoolOutPath(Globals::Instance->outputPath.string());
- std::string texOutName = item.second->GetName();
-
- auto start = chrono::steady_clock::now();
- item.second->Save(texOutPath);
- auto end = chrono::steady_clock::now();
- auto diff = chrono::duration_cast<chrono::milliseconds>(end - start).count();
-
- if (Globals::Instance->verbosity >= VERBOSITY_DEBUG)
- printf("SAVED IMAGE TO %s in %ims\n", Globals::Instance->outputPath.c_str(),
- (int32_t)diff);
-
- auto filepath = Globals::Instance->outputPath /
- Path::GetFileNameWithoutExtension(item.second->GetName());
- std::string incStr =
- StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(),
- item.second->GetExternalExtension().c_str());
- std::string texName =
- StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), item.first);
-
- parent->AddDeclarationIncludeArray(
- item.first, incStr, item.second->GetRawDataSize(), "u64", texName, 0);
- }
- }
+ defines += scene->extDefines;
}
}
@@ -1999,10 +1875,7 @@ string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
// Iterate through our vertex lists, connect intersecting lists.
if (vertices.size() > 0)
{
- vector<pair<uint32_t, vector<Vertex>>> verticesSorted(vertices.begin(), vertices.end());
-
- sort(verticesSorted.begin(), verticesSorted.end(),
- [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; });
+ vector<pair<uint32_t, vector<ZVtx>>> verticesSorted(vertices.begin(), vertices.end());
for (size_t i = 0; i < verticesSorted.size() - 1; i++)
{
@@ -2031,19 +1904,19 @@ string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
// Generate Vertex Declarations
vector<int32_t> vtxKeys;
- for (pair<int32_t, vector<Vertex>> item : vertices)
+ for (auto& item : vertices)
vtxKeys.push_back(item.first);
// for (pair<int32_t, vector<Vertex>> item : vertices)
for (size_t i = 0; i < vtxKeys.size(); i++)
{
- vector<Vertex> item = vertices[vtxKeys[i]];
+ auto& item = vertices[vtxKeys[i]];
string declaration = "";
int32_t curAddr = vtxKeys[i];
- for (Vertex vtx : item)
+ for (auto& vtx : item)
{
if (curAddr != vtxKeys[i])
declaration += "\n";
@@ -2167,9 +2040,8 @@ std::string ZDisplayList::ProcessGfxDis(const std::string& prefix)
void ZDisplayList::TextureGenCheck(string prefix)
{
- if (TextureGenCheck(fileData, textures, scene, parent, prefix, lastTexWidth, lastTexHeight,
- lastTexAddr, lastTexSeg, lastTexFmt, lastTexSiz, lastTexLoaded,
- lastTexIsPalette))
+ if (TextureGenCheck(fileData, scene, parent, prefix, lastTexWidth, lastTexHeight, lastTexAddr,
+ lastTexSeg, lastTexFmt, lastTexSiz, lastTexLoaded, lastTexIsPalette, this))
{
lastTexAddr = 0;
lastTexLoaded = false;
@@ -2177,14 +2049,19 @@ void ZDisplayList::TextureGenCheck(string prefix)
}
}
-bool ZDisplayList::TextureGenCheck(vector<uint8_t> fileData, map<uint32_t, ZTexture*>& textures,
- ZRoom* scene, ZFile* parent, string prefix, int32_t texWidth,
- int32_t texHeight, uint32_t texAddr, uint32_t texSeg,
- F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz, bool texLoaded,
- bool texIsPalette)
+bool ZDisplayList::TextureGenCheck(vector<uint8_t> fileData, ZRoom* scene, ZFile* parent,
+ string prefix, int32_t texWidth, int32_t texHeight,
+ uint32_t texAddr, uint32_t texSeg, F3DZEXTexFormats texFmt,
+ F3DZEXTexSizes texSiz, bool texLoaded, bool texIsPalette,
+ ZDisplayList* self)
{
int32_t segmentNumber = GETSEGNUM(texSeg);
+ if (!texIsPalette)
+ self->lastTexture = nullptr;
+ else
+ self->lastTlut = nullptr;
+
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);
@@ -2194,36 +2071,55 @@ bool ZDisplayList::TextureGenCheck(vector<uint8_t> fileData, map<uint32_t, ZText
{
if (segmentNumber != SEGMENT_SCENE)
{
- ZTexture* tex =
- ZTexture::FromBinary(TexFormatToTexType(texFmt, texSiz), fileData, texAddr,
- StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), texAddr),
- texWidth, texHeight, parent);
- tex->isPalette = texIsPalette;
- textures[texAddr] = tex;
- return true;
+ if (texAddr < parent->GetRawData().size())
+ {
+ ZTexture* tex = parent->GetTextureResource(texAddr);
+ if (tex != nullptr)
+ tex->isPalette = texIsPalette;
+ else
+ {
+ tex = new ZTexture(parent);
+ tex->FromBinary(fileData, texAddr, texWidth, texHeight,
+ TexFormatToTexType(texFmt, texSiz), texIsPalette);
+ parent->AddTextureResource(texAddr, tex);
+ }
+
+ if (!texIsPalette)
+ self->lastTexture = tex;
+ else
+ self->lastTlut = tex;
+
+ return true;
+ }
}
- else
+ else if (scene != nullptr)
{
- ZTexture* tex = ZTexture::FromBinary(
- TexFormatToTexType(texFmt, texSiz), scene->GetRawData(), texAddr,
- StringHelper::Sprintf("%sTex_%06X", Globals::Instance->lastScene->GetName().c_str(),
- texAddr),
- texWidth, texHeight, parent);
-
- if (scene != nullptr)
+ if (scene->parent->GetDeclaration(texAddr) == nullptr)
{
- scene->textures[texAddr] = tex;
+ ZTexture* tex = scene->parent->GetTextureResource(texAddr);
+ if (tex != nullptr)
+ tex->isPalette = texIsPalette;
+ else
+ {
+ tex = new ZTexture(scene->parent);
+ tex->FromBinary(scene->GetRawData(), texAddr, texWidth, texHeight,
+ TexFormatToTexType(texFmt, texSiz), texIsPalette);
+
+ scene->parent->AddTextureResource(texAddr, tex);
+ }
+
+ if (!texIsPalette)
+ self->lastTexture = tex;
+ else
+ self->lastTlut = tex;
auto filepath = Globals::Instance->outputPath /
Path::GetFileNameWithoutExtension(tex->GetName());
- scene->parent->AddDeclarationIncludeArray(
- texAddr,
- StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(),
- tex->GetExternalExtension().c_str()),
- tex->GetRawDataSize(), "u64",
- StringHelper::Sprintf("%sTex_%06X",
- Globals::Instance->lastScene->GetName().c_str(), texAddr),
- 0);
+ auto filename = StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(),
+ tex->GetExternalExtension().c_str());
+ scene->parent->AddDeclarationIncludeArray(texAddr, filename, tex->GetRawDataSize(),
+ tex->GetSourceTypeName(), tex->GetName(),
+ 0);
}
return true;
}
@@ -2275,10 +2171,6 @@ TextureType ZDisplayList::TexFormatToTexType(F3DZEXTexFormats fmt, F3DZEXTexSize
return TextureType::RGBA16bpp;
}
-void ZDisplayList::Save(const std::string& outFolder)
-{
-}
-
void ZDisplayList::GenerateHLIntermediette(HLFileIntermediette& hlFile)
{
HLModelIntermediette* mdl = (HLModelIntermediette*)&hlFile;
@@ -2310,48 +2202,3 @@ size_t ZDisplayList::GetRawDataSize()
{
return instructions.size() * 8;
}
-
-Vertex::Vertex()
-{
- x = 0;
- y = 0;
- z = 0;
- flag = 0;
- s = 0;
- t = 0;
- r = 0;
- g = 0;
- b = 0;
- a = 0;
-}
-
-Vertex::Vertex(int16_t nX, int16_t nY, int16_t nZ, uint16_t nFlag, int16_t nS, int16_t nT,
- uint8_t nR, uint8_t nG, uint8_t nB, uint8_t nA)
-{
- x = nX;
- y = nY;
- z = nZ;
- flag = nFlag;
- s = nS;
- t = nT;
- r = nR;
- g = nG;
- b = nB;
- a = nA;
-}
-
-Vertex::Vertex(std::vector<uint8_t> rawData, uint32_t rawDataIndex)
-{
- const uint8_t* data = rawData.data();
-
- x = BitConverter::ToInt16BE(data, rawDataIndex + 0);
- y = BitConverter::ToInt16BE(data, rawDataIndex + 2);
- z = BitConverter::ToInt16BE(data, rawDataIndex + 4);
- flag = BitConverter::ToInt16BE(data, rawDataIndex + 6);
- s = BitConverter::ToInt16BE(data, rawDataIndex + 8);
- t = BitConverter::ToInt16BE(data, rawDataIndex + 10);
- r = data[rawDataIndex + 12];
- g = data[rawDataIndex + 13];
- b = data[rawDataIndex + 14];
- a = data[rawDataIndex + 15];
-}
diff --git a/ZAPD/ZDisplayList.h b/ZAPD/ZDisplayList.h
index 41166ba..d53626e 100644
--- a/ZAPD/ZDisplayList.h
+++ b/ZAPD/ZDisplayList.h
@@ -4,6 +4,7 @@
#include "ZResource.h"
#include "ZRoom/ZRoom.h"
#include "ZTexture.h"
+#include "ZVtx.h"
#include "tinyxml2.h"
#include <map>
@@ -282,20 +283,6 @@ enum class OoTSegments
#define FORCE_BL 0x4000
#define TEX_EDGE 0x0000
-class Vertex
-{
-public:
- int16_t x, y, z;
- uint16_t flag;
- int16_t s, t;
- uint8_t r, g, b, a;
-
- Vertex();
- Vertex(int16_t nX, int16_t nY, int16_t nZ, uint16_t nFlag, int16_t nS, int16_t nT, uint8_t nR,
- uint8_t nG, uint8_t nB, uint8_t nA);
- Vertex(std::vector<uint8_t> rawData, uint32_t rawDataIndex);
-};
-
class ZDisplayList : public ZResource
{
protected:
@@ -350,14 +337,12 @@ public:
DListType dListType;
- // int32_t dListAddress;
-
- std::map<uint32_t, std::vector<Vertex>> vertices;
+ std::map<uint32_t, std::vector<ZVtx>> vertices;
std::map<uint32_t, std::string> vtxDeclarations;
std::vector<ZDisplayList*> otherDLists;
- std::map<uint32_t, ZTexture*> textures;
- std::map<uint32_t, std::string> texDeclarations;
+ ZTexture* lastTexture = nullptr;
+ ZTexture* lastTlut = nullptr;
std::vector<uint32_t> references;
@@ -372,16 +357,13 @@ public:
void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex) override;
- // static ZDisplayList* BuildFromXML(tinyxml2::XMLElement* reader, std::string inFolder, bool
- // readFile, ZFile* nParent);
void TextureGenCheck(std::string prefix);
- static bool TextureGenCheck(std::vector<uint8_t> fileData,
- std::map<uint32_t, ZTexture*>& textures, ZRoom* scene,
- ZFile* parent, std::string prefix, int32_t texWidth,
- int32_t texHeight, uint32_t texAddr, uint32_t texSeg,
- F3DZEXTexFormats texFmt, F3DZEXTexSizes texSiz, bool texLoaded,
- bool texIsPalette);
+ static bool TextureGenCheck(std::vector<uint8_t> fileData, ZRoom* scene, ZFile* parent,
+ std::string prefix, int32_t texWidth, int32_t texHeight,
+ uint32_t texAddr, uint32_t texSeg, F3DZEXTexFormats texFmt,
+ F3DZEXTexSizes texSiz, bool texLoaded, bool texIsPalette,
+ ZDisplayList* self);
static int32_t GetDListLength(std::vector<uint8_t> rawData, uint32_t rawDataIndex,
DListType dListType);
@@ -391,7 +373,6 @@ public:
std::string ProcessLegacy(const std::string& prefix);
std::string ProcessGfxDis(const std::string& prefix);
- void Save(const std::string& outFolder) override;
virtual void GenerateHLIntermediette(HLFileIntermediette& hlFile) override;
bool IsExternalResource() override;
virtual std::string GetExternalExtension() override;
diff --git a/ZAPD/ZFile.cpp b/ZAPD/ZFile.cpp
index b2a3996..bfb76eb 100644
--- a/ZAPD/ZFile.cpp
+++ b/ZAPD/ZFile.cpp
@@ -63,6 +63,7 @@ ZFile::ZFile(ZFileMode mode, tinyxml2::XMLElement* reader, const fs::path& nBase
outputPath = nOutPath;
ParseXML(mode, reader, filename, placeholderMode);
+ DeclareResourceSubReferences();
}
ZFile::~ZFile()
@@ -85,8 +86,6 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
else
name = filename;
- int32_t segment = -1;
-
// TODO: This should be a variable on the ZFile, but it is a large change in order to force all
// ZResource types to have a parent ZFile.
const char* gameStr = reader->Attribute("Game");
@@ -103,24 +102,28 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
StringHelper::Sprintf("Error: Game type %s not supported.", gameStr));
}
- if (reader->Attribute("BaseAddress") != NULL)
- baseAddress = (uint32_t)strtoul(
- StringHelper::Split(reader->Attribute("BaseAddress"), "0x")[1].c_str(), NULL, 16);
+ if (reader->Attribute("BaseAddress") != nullptr)
+ baseAddress = StringHelper::StrToL(reader->Attribute("BaseAddress"), 16);
- if (reader->Attribute("RangeStart") != NULL)
- rangeStart = (uint32_t)strtoul(
- StringHelper::Split(reader->Attribute("RangeStart"), "0x")[1].c_str(), NULL, 16);
+ if (reader->Attribute("RangeStart") != nullptr)
+ rangeStart = StringHelper::StrToL(reader->Attribute("RangeStart"), 16);
- if (reader->Attribute("RangeEnd") != NULL)
- rangeEnd = (uint32_t)strtoul(
- StringHelper::Split(reader->Attribute("RangeEnd"), "0x")[1].c_str(), NULL, 16);
+ if (reader->Attribute("RangeEnd") != nullptr)
+ rangeEnd = StringHelper::StrToL(reader->Attribute("RangeEnd"), 16);
- if (reader->Attribute("Segment") != NULL)
- segment = strtol(reader->Attribute("Segment"), NULL, 10);
+ // Commented until ZArray doesn't use a ZFile to parse it's contents anymore.
+ /*
+ if (reader->Attribute("Segment") == nullptr)
+ throw std::runtime_error(StringHelper::Sprintf(
+ "ZFile::ParseXML: Error in '%s'.\n"
+ "\t Missing 'Segment' attribute in File node. \n",
+ name.c_str()));
+ */
- if (segment != -1)
+ if (reader->Attribute("Segment") != nullptr)
{
- Globals::Instance->AddSegment(segment);
+ segment = StringHelper::StrToL(reader->Attribute("Segment"), 10);
+ Globals::Instance->AddSegment(segment, this);
}
string folderName = (basePath / Path::GetFileNameWithoutExtension(name)).string();
@@ -151,7 +154,8 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
if (Globals::Instance->verbosity >= VERBOSITY_INFO)
printf("%s: 0x%06X\n", nameXml, rawDataIndex);
- if (offsetXml != NULL)
+ // Check for repeated attributes.
+ if (offsetXml != nullptr)
{
rawDataIndex = strtol(StringHelper::Split(offsetXml, "0x")[1].c_str(), NULL, 16);
@@ -163,7 +167,7 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
}
offsetSet.insert(offsetXml);
}
- if (outNameXml != NULL)
+ if (outNameXml != nullptr)
{
if (outNameSet.find(outNameXml) != outNameSet.end())
{
@@ -173,7 +177,7 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
}
outNameSet.insert(outNameXml);
}
- if (nameXml != NULL)
+ if (nameXml != nullptr)
{
if (nameSet.find(nameXml) != nameSet.end())
{
@@ -194,27 +198,12 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
if (mode == ZFileMode::Extract)
nRes->ExtractFromXML(child, rawData, rawDataIndex);
- // TODO: See if we can make this part of the ZRoom code...
- if (nRes->GetResourceType() == ZResourceType::Room)
- {
- if (nodeName == "Scene")
- {
- Globals::Instance->lastScene = (ZRoom*)nRes;
-
- if (segment == -1)
- segment = SEGMENT_SCENE;
- }
- else
- {
- if (segment == -1)
- segment = SEGMENT_ROOM;
- }
-
- if (segment != -1)
- Globals::Instance->AddSegment(segment);
- }
+ auto resType = nRes->GetResourceType();
+ if (resType == ZResourceType::Texture)
+ AddTextureResource(rawDataIndex, static_cast<ZTexture*>(nRes));
+ else
+ resources.push_back(nRes);
- resources.push_back(nRes);
rawDataIndex += nRes->GetRawDataSize();
}
else if (string(child->Name()) == "File")
@@ -233,6 +222,14 @@ void ZFile::ParseXML(ZFileMode mode, XMLElement* reader, std::string filename, b
}
}
+void ZFile::DeclareResourceSubReferences()
+{
+ for (size_t i = 0; i < resources.size(); i++)
+ {
+ resources.at(i)->DeclareReferences(name);
+ }
+}
+
void ZFile::BuildSourceFile(fs::path outputDir)
{
string folderName = Path::GetFileNameWithoutExtension(outputPath.string());
@@ -259,6 +256,16 @@ std::string ZFile::GetName()
return name;
}
+const fs::path& ZFile::GetXmlFilePath() const
+{
+ return xmlFilePath;
+}
+
+const std::vector<uint8_t>& ZFile::GetRawData() const
+{
+ return rawData;
+}
+
void ZFile::ExtractResources(fs::path outputDir)
{
string folderName = Path::GetFileNameWithoutExtension(outputPath.string());
@@ -280,8 +287,7 @@ void ZFile::ExtractResources(fs::path outputDir)
if (Globals::Instance->verbosity >= VERBOSITY_INFO)
printf("Saving resource %s\n", res->GetName().c_str());
- res->CalcHash();
- res->Save(outputPath.string());
+ res->Save(outputPath);
}
if (Globals::Instance->testMode)
@@ -460,30 +466,46 @@ void ZFile::AddDeclarationDebugChecks(uint32_t address)
#endif
}
-std::string ZFile::GetDeclarationName(uint32_t address)
+std::string ZFile::GetDeclarationName(uint32_t address) const
{
return GetDeclarationName(address,
"ERROR_COULD_NOT_FIND_DECLARATION"); // Note: For now that default
// message is just for testing
}
-std::string ZFile::GetDeclarationName(uint32_t address, std::string defaultResult)
+std::string ZFile::GetDeclarationName(uint32_t address, std::string defaultResult) const
{
if (declarations.find(address) != declarations.end())
- return declarations[address]->varName;
+ return declarations.at(address)->varName;
return defaultResult;
}
-Declaration* ZFile::GetDeclaration(uint32_t address)
+std::string ZFile::GetDeclarationPtrName(segptr_t segAddress) const
+{
+ if (segAddress == 0)
+ return "NULL";
+
+ Declaration* decl = GetDeclaration(Seg2Filespace(segAddress, baseAddress));
+
+ if (!Globals::Instance->HasSegment(GETSEGNUM(segAddress)) || decl == nullptr)
+ return StringHelper::Sprintf("0x%08X", segAddress);
+
+ if (!decl->isArray)
+ return "&" + decl->varName;
+
+ return decl->varName;
+}
+
+Declaration* ZFile::GetDeclaration(uint32_t address) const
{
if (declarations.find(address) != declarations.end())
- return declarations[address];
+ return declarations.at(address);
return nullptr;
}
-Declaration* ZFile::GetDeclarationRanged(uint32_t address)
+Declaration* ZFile::GetDeclarationRanged(uint32_t address) const
{
for (const auto decl : declarations)
{
@@ -494,7 +516,7 @@ Declaration* ZFile::GetDeclarationRanged(uint32_t address)
return nullptr;
}
-uint32_t ZFile::GetDeclarationRangedAddress(uint32_t address)
+uint32_t ZFile::GetDeclarationRangedAddress(uint32_t address) const
{
for (const auto decl : declarations)
{
@@ -522,8 +544,9 @@ void ZFile::GenerateSourceFiles(fs::path outputDir)
GeneratePlaceholderDeclarations();
// Generate Code
- for (ZResource* res : resources)
+ for (size_t i = 0; i < resources.size(); i++)
{
+ ZResource* res = resources.at(i);
string resSrc = res->GetSourceOutputCode(name);
if (res->IsExternalResource())
@@ -539,16 +562,19 @@ void ZFile::GenerateSourceFiles(fs::path outputDir)
if (res->GetResourceType() == ZResourceType::Texture)
{
- ZTexture* tex = (ZTexture*)res;
-
- tex->CalcHash();
+ ZTexture* tex = static_cast<ZTexture*>(res);
- // TEXTURE POOL CHECK
- if (Globals::Instance->cfg.texturePool.find(tex->hash) !=
- Globals::Instance->cfg.texturePool.end())
+ if (!Globals::Instance->cfg.texturePool.empty())
{
- incStr = Globals::Instance->cfg.texturePool[tex->hash].path.string() + "." +
- res->GetExternalExtension() + ".inc";
+ tex->CalcHash();
+
+ // TEXTURE POOL CHECK
+ if (Globals::Instance->cfg.texturePool.find(tex->hash) !=
+ Globals::Instance->cfg.texturePool.end())
+ {
+ incStr = Globals::Instance->cfg.texturePool[tex->hash].path.string() + "." +
+ res->GetExternalExtension() + ".inc";
+ }
}
incStr += ".c";
@@ -639,6 +665,24 @@ void ZFile::GeneratePlaceholderDeclarations()
}
}
+void ZFile::AddTextureResource(uint32_t offset, ZTexture* tex)
+{
+ for (auto res : resources)
+ assert(res->GetRawDataIndex() != offset);
+
+ resources.push_back(tex);
+ texturesResources[offset] = tex;
+}
+
+ZTexture* ZFile::GetTextureResource(uint32_t offset) const
+{
+ auto tex = texturesResources.find(offset);
+ if (tex != texturesResources.end())
+ return tex->second;
+
+ return nullptr;
+}
+
std::map<std::string, ZResourceFactoryFunc*>* ZFile::GetNodeMap()
{
static std::map<std::string, ZResourceFactoryFunc*> nodeMap;
@@ -658,6 +702,8 @@ string ZFile::ProcessDeclarations()
if (declarations.size() == 0)
return output;
+ defines += ProcessTextureIntersections(name);
+
// Account for padding/alignment
uint32_t lastAddr = 0;
uint32_t lastSize = 0;
@@ -665,12 +711,10 @@ string ZFile::ProcessDeclarations()
// printf("RANGE START: 0x%06X - RANGE END: 0x%06X\n", rangeStart, rangeEnd);
// Optimization: See if there are any arrays side by side that can be merged...
- auto declarationKeys =
- vector<pair<int32_t, Declaration*>>(declarations.begin(), declarations.end());
- sort(declarationKeys.begin(), declarationKeys.end(),
- [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; });
+ std::vector<pair<int32_t, Declaration*>> declarationKeys(declarations.begin(),
+ declarations.end());
- pair<int32_t, Declaration*> lastItem = declarationKeys[0];
+ pair<int32_t, Declaration*> lastItem = declarationKeys.at(0);
for (size_t i = 1; i < declarationKeys.size(); i++)
{
@@ -1153,4 +1197,61 @@ string ZFile::ProcessExterns()
output += defines;
return output;
-} \ No newline at end of file
+}
+
+std::string ZFile::ProcessTextureIntersections(std::string prefix)
+{
+ if (texturesResources.empty())
+ return "";
+
+ std::string defines = "";
+ vector<pair<uint32_t, ZTexture*>> texturesSorted(texturesResources.begin(),
+ texturesResources.end());
+
+ for (size_t i = 0; i < texturesSorted.size() - 1; i++)
+ {
+ uint32_t currentOffset = texturesSorted[i].first;
+ uint32_t nextOffset = texturesSorted[i + 1].first;
+ auto& currentTex = texturesResources.at(currentOffset);
+ int texSize = currentTex->GetRawDataSize();
+
+ if (currentTex->WasDeclaredInXml())
+ {
+ // We believe the user is right.
+ continue;
+ }
+
+ if ((currentOffset + texSize) > nextOffset)
+ {
+ uint32_t offsetDiff = nextOffset - currentOffset;
+ if (currentTex->isPalette)
+ {
+ // Shrink palette so it doesn't overlap
+ currentTex->SetDimensions(offsetDiff / currentTex->GetPixelMultiplyer(), 1);
+ declarations.at(currentOffset)->size = currentTex->GetRawDataSize();
+ }
+ else
+ {
+ std::string texName = GetDeclarationPtrName(currentOffset);
+ std::string texNextName;
+
+ Declaration* nextDecl = GetDeclaration(nextOffset);
+ if (nextDecl == nullptr)
+ texNextName = texturesResources.at(nextOffset)->GetName();
+ else
+ texNextName = nextDecl->varName;
+
+ defines += StringHelper::Sprintf("#define %s ((u32)%s + 0x%06X)\n",
+ texNextName.c_str(), texName.c_str(), offsetDiff);
+
+ declarations.erase(nextOffset);
+ texturesResources.erase(nextOffset);
+ texturesSorted.erase(texturesSorted.begin() + i + 1);
+
+ i--;
+ }
+ }
+ }
+
+ return defines;
+}
diff --git a/ZAPD/ZFile.h b/ZAPD/ZFile.h
index 365bf43..278c80c 100644
--- a/ZAPD/ZFile.h
+++ b/ZAPD/ZFile.h
@@ -4,6 +4,7 @@
#include <vector>
#include "Directory.h"
#include "ZResource.h"
+#include "ZTexture.h"
#include "tinyxml2.h"
enum class ZFileMode
@@ -32,6 +33,7 @@ public:
std::map<uint32_t, Declaration*> declarations;
std::string defines;
std::vector<ZResource*> resources;
+ int32_t segment;
uint32_t baseAddress, rangeStart, rangeEnd;
ZFile(const fs::path& nOutPath, std::string nName);
@@ -42,6 +44,8 @@ public:
std::string GetVarName(uint32_t address);
std::string GetName();
+ const fs::path& GetXmlFilePath() const;
+ const std::vector<uint8_t>& GetRawData() const;
void ExtractResources(fs::path outputDir);
void BuildSourceFile(fs::path outputDir);
void AddResource(ZResource* res);
@@ -72,15 +76,19 @@ public:
Declaration* AddDeclarationIncludeArray(uint32_t address, std::string includePath, size_t size,
std::string varType, std::string varName,
size_t arrayItemCnt);
- std::string GetDeclarationName(uint32_t address);
- std::string GetDeclarationName(uint32_t address, std::string defaultResult);
- Declaration* GetDeclaration(uint32_t address);
- Declaration* GetDeclarationRanged(uint32_t address);
- uint32_t GetDeclarationRangedAddress(uint32_t address);
+ std::string GetDeclarationName(uint32_t address) const;
+ std::string GetDeclarationName(uint32_t address, std::string defaultResult) const;
+ std::string GetDeclarationPtrName(segptr_t segAddress) const;
+ Declaration* GetDeclaration(uint32_t address) const;
+ Declaration* GetDeclarationRanged(uint32_t address) const;
+ uint32_t GetDeclarationRangedAddress(uint32_t address) const;
bool HasDeclaration(uint32_t address);
std::string GetHeaderInclude();
void GeneratePlaceholderDeclarations();
+ void AddTextureResource(uint32_t offset, ZTexture* tex);
+ ZTexture* GetTextureResource(uint32_t offset) const;
+
static std::map<std::string, ZResourceFactoryFunc*>* GetNodeMap();
static void RegisterNode(std::string nodeName, ZResourceFactoryFunc* nodeFunc);
@@ -90,10 +98,15 @@ protected:
fs::path basePath;
fs::path outputPath;
fs::path xmlFilePath;
+ // Keep track of every texture of this ZFile.
+ // The pointers declared here are "borrowed" (somebody else is the owner),
+ // so ZFile shouldn't delete/free those textures.
+ std::map<uint32_t, ZTexture*> texturesResources;
ZFile();
void ParseXML(ZFileMode mode, tinyxml2::XMLElement* reader, std::string filename,
bool placeholderMode);
+ void DeclareResourceSubReferences();
void GenerateSourceFiles(fs::path outputDir);
void GenerateSourceHeaderFiles();
void GenerateHLIntermediette();
@@ -101,4 +114,6 @@ protected:
std::string ProcessDeclarations();
void ProcessDeclarationText(Declaration* decl);
std::string ProcessExterns();
-}; \ No newline at end of file
+
+ std::string ProcessTextureIntersections(std::string prefix);
+};
diff --git a/ZAPD/ZResource.cpp b/ZAPD/ZResource.cpp
index 466b3ab..fb76605 100644
--- a/ZAPD/ZResource.cpp
+++ b/ZAPD/ZResource.cpp
@@ -26,6 +26,7 @@ void ZResource::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<u
ParseXML(reader);
ParseRawData();
+ CalcHash();
}
void ZResource::ExtractFromFile(const std::vector<uint8_t>& nRawData, uint32_t nRawDataIndex)
@@ -34,6 +35,7 @@ void ZResource::ExtractFromFile(const std::vector<uint8_t>& nRawData, uint32_t n
rawDataIndex = nRawDataIndex;
ParseRawData();
+ CalcHash();
}
void ZResource::ParseXML(tinyxml2::XMLElement* reader)
@@ -74,10 +76,12 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader)
"with inner element/child detected.\n",
name.c_str(), reader->Name()));
}
+
+ declaredInXml = true;
}
}
-void ZResource::Save(const std::string& outFolder)
+void ZResource::Save(const fs::path& outFolder)
{
}
@@ -85,12 +89,12 @@ void ZResource::PreGenSourceFiles()
{
}
-string ZResource::GetName()
+const std::string& ZResource::GetName() const
{
return name;
}
-std::string ZResource::GetOutName()
+const std::string& ZResource::GetOutName() const
{
return outName;
}
@@ -120,16 +124,21 @@ std::string ZResource::GetExternalExtension()
return "";
}
-vector<uint8_t> ZResource::GetRawData()
+const std::vector<uint8_t>& ZResource::GetRawData() const
{
return rawData;
}
-void ZResource::SetRawData(std::vector<uint8_t> nData)
+void ZResource::SetRawData(const std::vector<uint8_t>& nData)
{
rawData = nData;
}
+bool ZResource::WasDeclaredInXml() const
+{
+ return declaredInXml;
+}
+
uint32_t ZResource::GetRawDataIndex()
{
return rawDataIndex;
@@ -159,6 +168,10 @@ void ZResource::ParseRawData()
{
}
+void ZResource::DeclareReferences(const std::string& prefix)
+{
+}
+
void ZResource::GenerateHLIntermediette(HLFileIntermediette& hlFile)
{
}
diff --git a/ZAPD/ZResource.h b/ZAPD/ZResource.h
index 5b411d2..984974b 100644
--- a/ZAPD/ZResource.h
+++ b/ZAPD/ZResource.h
@@ -7,6 +7,8 @@
#include <vector>
#include "tinyxml2.h"
+#include "Directory.h"
+
#define SEGMENT_SCENE 2
#define SEGMENT_ROOM 3
#define SEGMENT_KEEP 4
@@ -50,26 +52,28 @@ class ZResource
{
public:
ZFile* parent;
- bool outputDeclaration;
- uint32_t hash;
+ bool outputDeclaration = true;
+ uint32_t hash = 0;
ZResource(ZFile* nParent);
virtual ~ZResource();
// Parsing from File
virtual void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
- const uint32_t nRawDataIndex); // Extract Mode
+ const uint32_t nRawDataIndex);
+ // Extract Mode
virtual void ExtractFromFile(const std::vector<uint8_t>& nRawData, uint32_t nRawDataIndex);
// Misc
virtual void ParseXML(tinyxml2::XMLElement* reader);
virtual void ParseRawData();
+ virtual void DeclareReferences(const std::string& prefix);
virtual std::string GetSourceOutputCode(const std::string& prefix);
virtual std::string GetSourceOutputHeader(const std::string& prefix);
virtual void PreGenSourceFiles();
virtual void GenerateHLIntermediette(HLFileIntermediette& hlFile);
virtual void CalcHash();
- virtual void Save(const std::string& outFolder);
+ virtual void Save(const fs::path& outFolder);
// Properties
virtual bool IsExternalResource();
@@ -79,15 +83,16 @@ public:
virtual std::string GetExternalExtension();
// Getters/Setters
- std::string GetName();
+ const std::string& GetName() const;
void SetName(std::string nName);
- std::string GetOutName();
+ const std::string& GetOutName() const;
void SetOutName(std::string nName);
virtual uint32_t GetRawDataIndex();
virtual void SetRawDataIndex(uint32_t value);
virtual size_t GetRawDataSize();
- virtual std::vector<uint8_t> GetRawData();
- virtual void SetRawData(std::vector<uint8_t> nData);
+ virtual const std::vector<uint8_t>& GetRawData() const;
+ virtual void SetRawData(const std::vector<uint8_t>& nData);
+ bool WasDeclaredInXml() const;
protected:
std::string name;
@@ -98,6 +103,7 @@ protected:
bool canHaveInner = false; // Can this type have an inner node?
bool isCustomAsset; // If set to true, create a reference for the asset in the file, but don't
// actually try to extract it from the file
+ bool declaredInXml = false;
};
enum class DeclarationAlignment
@@ -178,4 +184,4 @@ typedef ZResource*(ZResourceFactoryFunc)();
ZFile::RegisterNode(#nodeName, &ZResourceFactory_##zResClass_##nodeName); \
} \
}; \
- static ZRes_##nodeName inst_ZRes_##nodeName;
+ static ZRes_##nodeName inst_ZRes_##nodeName
diff --git a/ZAPD/ZRoom/Commands/SetCutscenes.cpp b/ZAPD/ZRoom/Commands/SetCutscenes.cpp
index 345dca1..02b59bc 100644
--- a/ZAPD/ZRoom/Commands/SetCutscenes.cpp
+++ b/ZAPD/ZRoom/Commands/SetCutscenes.cpp
@@ -47,8 +47,9 @@ SetCutscenes::SetCutscenes(ZRoom* nZRoom, std::vector<uint8_t> rawData, uint32_t
declaration += "\n";
ZCutsceneMM* cutscene = new ZCutsceneMM(nZRoom->parent);
- cutscene->ExtractFromXML(
- nullptr, rawData, entry->segmentOffset); // TODO: Use ExtractFromFile() here when that gets implemented
+
+ // TODO: Use ExtractFromFile() here when that gets implemented
+ cutscene->ExtractFromXML(nullptr, rawData, entry->segmentOffset);
cutscenes.push_back(cutscene);
}
diff --git a/ZAPD/ZRoom/Commands/SetMesh.cpp b/ZAPD/ZRoom/Commands/SetMesh.cpp
index 62e1b1b..d875529 100644
--- a/ZAPD/ZRoom/Commands/SetMesh.cpp
+++ b/ZAPD/ZRoom/Commands/SetMesh.cpp
@@ -256,11 +256,6 @@ void SetMesh::GenDListDeclarations(std::vector<uint8_t> rawData, ZDisplayList* d
StringHelper::Sprintf("%sVtx_%06X", zRoom->GetName().c_str(), vtxEntry.first),
dList->vertices[vtxEntry.first].size(), vtxEntry.second);
}
-
- for (pair<uint32_t, string> texEntry : dList->texDeclarations)
- {
- zRoom->textures[texEntry.first] = dList->textures[texEntry.first];
- }
}
std::string SetMesh::GenDListExterns(ZDisplayList* dList)
@@ -276,10 +271,6 @@ std::string SetMesh::GenDListExterns(ZDisplayList* dList)
for (ZDisplayList* otherDList : dList->otherDLists)
sourceOutput += GenDListExterns(otherDList);
- for (pair<uint32_t, string> texEntry : dList->texDeclarations)
- sourceOutput += StringHelper::Sprintf("extern u64 %sTex_%06X[];\n",
- zRoom->GetName().c_str(), texEntry.first);
-
sourceOutput += dList->defines;
return sourceOutput;
diff --git a/ZAPD/ZRoom/ZRoom.cpp b/ZAPD/ZRoom/ZRoom.cpp
index de73b97..09cda02 100644
--- a/ZAPD/ZRoom/ZRoom.cpp
+++ b/ZAPD/ZRoom/ZRoom.cpp
@@ -50,9 +50,6 @@ REGISTER_ZFILENODE(Scene, ZRoom);
ZRoom::ZRoom(ZFile* nParent) : ZResource(nParent)
{
- textures = map<int32_t, ZTexture*>();
- commands = vector<ZRoomCommand*>();
- commandSets = vector<CommandSet>();
extDefines = "";
scene = nullptr;
roomCount = -1;
@@ -63,9 +60,6 @@ ZRoom::~ZRoom()
{
for (ZRoomCommand* cmd : commands)
delete cmd;
-
- for (auto t : textures)
- delete t.second;
}
void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
@@ -82,9 +76,6 @@ void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8
Globals::Instance->lastScene = this;
}
- Globals::Instance->AddSegment(SEGMENT_ROOM);
- Globals::Instance->AddSegment(SEGMENT_SCENE);
-
uint32_t cmdCount = UINT32_MAX;
if (name == "syotes_room_0")
@@ -158,12 +149,14 @@ void ZRoom::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8
delete pathway;
}
+#ifndef DEPRECATION_OFF
fprintf(stderr,
"ZRoom::ExtractFromXML: Deprecation warning in '%s'.\n"
"\t The resource '%s' is currently deprecated, and will be removed in a future "
"version.\n"
"\t Use the non-hint version instead.\n",
name.c_str(), child->Name());
+#endif
}
// ParseCommands(rawDataIndex);
@@ -487,65 +480,6 @@ string ZRoom::GetSourceOutputCode(const std::string& prefix)
ProcessCommandSets();
- // Check for texture intersections
- {
- string defines = "";
- if (textures.size() != 0)
- {
- vector<pair<uint32_t, ZTexture*>> texturesSorted(textures.begin(), textures.end());
-
- sort(texturesSorted.begin(), texturesSorted.end(),
- [](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; });
-
- for (size_t i = 0; i < texturesSorted.size() - 1; i++)
- {
- int32_t texSize = textures[texturesSorted[i].first]->GetRawDataSize();
-
- if ((texturesSorted[i].first + texSize) > texturesSorted[i + 1].first)
- {
- // int32_t intersectAmt = (texturesSorted[i].first + texSize) - texturesSorted[i
- // + 1].first;
-
- defines += StringHelper::Sprintf(
- "#define %sTex_%06X ((u32)%sTex_%06X + 0x%06X)\n", prefix.c_str(),
- texturesSorted[i + 1].first, prefix.c_str(), texturesSorted[i].first,
- texturesSorted[i + 1].first - texturesSorted[i].first);
-
- parent->declarations.erase(texturesSorted[i + 1].first);
- textures.erase(texturesSorted[i + 1].first);
- texturesSorted.erase(texturesSorted.begin() + i + 1);
-
- i--;
- }
- }
- }
-
- parent->defines += defines;
- }
-
- for (pair<int32_t, ZTexture*> item : textures)
- {
- string declaration = "";
-
- declaration += item.second->GetSourceOutputCode(prefix);
-
- std::string outPath = item.second->GetPoolOutPath(Globals::Instance->outputPath.string());
-
- if (Globals::Instance->verbosity >= VERBOSITY_DEBUG)
- printf("SAVING IMAGE TO %s\n", outPath.c_str());
-
- item.second->Save(outPath);
-
- auto filepath = Globals::Instance->outputPath /
- Path::GetFileNameWithoutExtension(item.second->GetName());
- parent->AddDeclarationIncludeArray(
- item.first,
- StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(),
- item.second->GetExternalExtension().c_str()),
- item.second->GetRawDataSize(), "u64",
- StringHelper::Sprintf("%sTex_%06X", prefix.c_str(), item.first), 0);
- }
-
return sourceOutput;
}
@@ -564,7 +498,7 @@ ZResourceType ZRoom::GetResourceType()
return ZResourceType::Room;
}
-void ZRoom::Save(const std::string& outFolder)
+void ZRoom::Save(const fs::path& outFolder)
{
for (ZRoomCommand* cmd : commands)
cmd->Save();
diff --git a/ZAPD/ZRoom/ZRoom.h b/ZAPD/ZRoom/ZRoom.h
index 1068ee2..7bb1241 100644
--- a/ZAPD/ZRoom/ZRoom.h
+++ b/ZAPD/ZRoom/ZRoom.h
@@ -21,7 +21,6 @@ protected:
public:
ZRoom* scene;
- std::map<int32_t, ZTexture*> textures;
std::vector<CommandSet> commandSets;
int32_t roomCount; // Only valid for scenes
@@ -38,7 +37,7 @@ public:
ZRoomCommand* FindCommandOfType(RoomCommand cmdType);
size_t GetRawDataSize() override;
virtual ZResourceType GetResourceType() override;
- virtual void Save(const std::string& outFolder) override;
+ virtual void Save(const fs::path& outFolder) override;
virtual void PreGenSourceFiles() override;
};
diff --git a/ZAPD/ZSkeleton.cpp b/ZAPD/ZSkeleton.cpp
index 3838450..f610ca5 100644
--- a/ZAPD/ZSkeleton.cpp
+++ b/ZAPD/ZSkeleton.cpp
@@ -150,10 +150,6 @@ void ZSkeleton::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<u
}
}
-void ZSkeleton::Save(const std::string& outFolder)
-{
-}
-
void ZSkeleton::GenerateHLIntermediette(HLFileIntermediette& hlFile)
{
HLModelIntermediette* mdl = (HLModelIntermediette*)&hlFile;
diff --git a/ZAPD/ZSkeleton.h b/ZAPD/ZSkeleton.h
index 400d6c1..9ca6b4e 100644
--- a/ZAPD/ZSkeleton.h
+++ b/ZAPD/ZSkeleton.h
@@ -32,7 +32,6 @@ public:
void ParseRawData() override;
void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex) override;
- void Save(const std::string& outFolder) override;
void GenerateHLIntermediette(HLFileIntermediette& hlFile) override;
size_t GetRawDataSize() override;
diff --git a/ZAPD/ZTexture.cpp b/ZAPD/ZTexture.cpp
index ebd7c55..cb3eaaa 100644
--- a/ZAPD/ZTexture.cpp
+++ b/ZAPD/ZTexture.cpp
@@ -1,164 +1,67 @@
-#define STB_IMAGE_IMPLEMENTATION
-#define STB_IMAGE_WRITE_IMPLEMENTATION
-#define TINYGLTF_IMPLEMENTATION
-
#include "ZTexture.h"
+
+#include <cassert>
#include "BitConverter.h"
#include "CRC32.h"
+#include "Directory.h"
#include "File.h"
#include "Globals.h"
#include "Path.h"
-#include <Directory.h>
-#include "stb_image.h"
-#include "stb_image_write.h"
-
-using namespace std;
-using namespace tinyxml2;
-
REGISTER_ZFILENODE(Texture, ZTexture);
ZTexture::ZTexture(ZFile* nParent) : ZResource(nParent)
{
- bmpRgb = nullptr;
- bmpRgba = nullptr;
width = 0;
height = 0;
- type = TextureType::Error;
- isPalette = false;
- isRawDataFixed = false;
-}
-
-ZTexture::~ZTexture()
-{
- if (bmpRgb != nullptr)
- {
- stbi_image_free(bmpRgb);
- bmpRgb = nullptr;
- }
-
- if (bmpRgba != nullptr)
- {
- stbi_image_free(bmpRgba);
- bmpRgba = nullptr;
- }
-
- width = 0;
- height = 0;
- type = TextureType::Error;
}
void ZTexture::ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
const uint32_t nRawDataIndex)
{
- ParseXML(reader);
- rawDataIndex = nRawDataIndex;
- rawData = vector<uint8_t>(nRawData.data() + rawDataIndex,
- nRawData.data() + rawDataIndex + GetRawDataSize());
-
- FixRawData();
- PrepareBitmap();
-}
-
-ZTexture* ZTexture::FromBinary(TextureType nType, std::vector<uint8_t> nRawData,
- uint32_t nRawDataIndex, std::string nName, int32_t nWidth,
- int32_t nHeight, ZFile* nParent)
-{
- ZTexture* tex = new ZTexture(nParent);
+ ZResource::ExtractFromXML(reader, nRawData, nRawDataIndex);
- tex->width = nWidth;
- tex->height = nHeight;
- tex->type = nType;
- tex->name = nName;
- tex->outName = nName;
- tex->rawDataIndex = nRawDataIndex;
+ auto filepath = Globals::Instance->outputPath / fs::path(name).stem();
- size_t dataEnd = tex->rawDataIndex + tex->GetRawDataSize();
- tex->rawData = vector<uint8_t>(nRawData.data() + tex->rawDataIndex, nRawData.data() + dataEnd);
+ std::string incStr =
+ StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(), GetExternalExtension().c_str());
- tex->FixRawData();
- tex->CalcHash();
- tex->PrepareBitmap();
-
- return tex;
+ parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(),
+ name, 0);
}
-// Build Source File Mode
-ZTexture* ZTexture::BuildFromXML(XMLElement* reader, string inFolder, bool readFile)
+void ZTexture::FromBinary(const std::vector<uint8_t>& nRawData, uint32_t nRawDataIndex,
+ int32_t nWidth, int32_t nHeight, TextureType nType, bool nIsPalette)
{
- ZTexture* tex = new ZTexture(nullptr);
-
- tex->ParseXML(reader);
+ width = nWidth;
+ height = nHeight;
+ format = nType;
+ rawDataIndex = nRawDataIndex;
+ isPalette = nIsPalette;
+ name = GetDefaultName(parent->GetName());
+ outName = name;
- if (readFile)
- tex->PrepareRawData(inFolder);
+ rawData.assign(nRawData.begin(), nRawData.end());
- return tex;
+ ParseRawData();
+ CalcHash();
}
-ZTexture* ZTexture::FromPNG(string pngFilePath, TextureType texType)
+void ZTexture::FromPNG(const fs::path& pngFilePath, TextureType texType)
{
- int32_t comp;
- ZTexture* tex = new ZTexture(nullptr);
- tex->type = texType;
- tex->name = StringHelper::Split(Path::GetFileNameWithoutExtension(pngFilePath), ".")[0];
-
- tex->bmpRgb = (uint8_t*)stbi_load((pngFilePath).c_str(), (int*)&tex->width, (int*)&tex->height,
- &comp, STBI_rgb);
- stbi_image_free(tex->bmpRgb);
- tex->bmpRgb = nullptr;
- tex->rawData = vector<uint8_t>(tex->GetRawDataSize());
-
- switch (texType)
- {
- case TextureType::RGBA16bpp:
- tex->PrepareRawDataRGBA16(pngFilePath);
- break;
- case TextureType::RGBA32bpp:
- tex->PrepareRawDataRGBA32(pngFilePath);
- break;
- case TextureType::Grayscale4bpp:
- tex->PrepareRawDataGrayscale4(pngFilePath);
- break;
- case TextureType::Grayscale8bpp:
- tex->PrepareRawDataGrayscale8(pngFilePath);
- break;
- case TextureType::GrayscaleAlpha4bpp:
- tex->PrepareRawDataGrayscaleAlpha4(pngFilePath);
- break;
- case TextureType::GrayscaleAlpha8bpp:
- tex->PrepareRawDataGrayscaleAlpha8(pngFilePath);
- break;
- case TextureType::GrayscaleAlpha16bpp:
- tex->PrepareRawDataGrayscaleAlpha16(pngFilePath);
- break;
- case TextureType::Palette4bpp:
- tex->PrepareRawDataPalette4(pngFilePath);
- break;
- case TextureType::Palette8bpp:
- tex->PrepareRawDataPalette8(pngFilePath);
- break;
- default:
- throw std::runtime_error("Format is not supported!");
- }
-
- tex->FixRawData();
-
- return tex;
+ format = texType;
+ name = StringHelper::Split(Path::GetFileNameWithoutExtension(pngFilePath), ".")[0];
+ PrepareRawDataFromFile(pngFilePath);
}
-ZTexture* ZTexture::FromHLTexture(HLTexture* hlTex)
+void ZTexture::FromHLTexture(HLTexture* hlTex)
{
- ZTexture* tex = new ZTexture(nullptr);
-
- tex->width = hlTex->width;
- tex->height = hlTex->height;
- tex->type = (TextureType)hlTex->type;
-
- return tex;
+ width = hlTex->width;
+ height = hlTex->height;
+ format = static_cast<TextureType>(hlTex->type);
}
-void ZTexture::ParseXML(XMLElement* reader)
+void ZTexture::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
@@ -168,7 +71,8 @@ void ZTexture::ParseXML(XMLElement* reader)
}
else
{
- throw std::runtime_error("Width == nullptr for asset " + (string)reader->Attribute("Name"));
+ throw std::runtime_error("Width == nullptr for asset " +
+ std::string(reader->Attribute("Name")));
}
if (reader->Attribute("Height") != nullptr)
@@ -178,58 +82,39 @@ void ZTexture::ParseXML(XMLElement* reader)
else
{
throw std::runtime_error("Height == nullptr for asset " +
- (string)reader->Attribute("Name"));
+ std::string(reader->Attribute("Name")));
}
- string formatStr = reader->Attribute("Format");
+ std::string formatStr = reader->Attribute("Format");
- type = GetTextureTypeFromString(formatStr);
+ format = GetTextureTypeFromString(formatStr);
- if (type == TextureType::Error)
+ if (format == TextureType::Error)
throw std::runtime_error("Format " + formatStr + " is not supported!");
-}
-void ZTexture::FixRawData()
-{
- if (type == TextureType::RGBA32bpp)
+ auto tlutOffsetXml = reader->Attribute("TlutOffset");
+ if (tlutOffsetXml != nullptr)
{
- for (size_t i = 0; i < rawData.size(); i += 4)
+ switch (format)
{
- uint8_t tmp = rawData[i];
- rawData[i] = rawData[i + 2];
- rawData[i + 2] = tmp;
+ case TextureType::Palette4bpp:
+ case TextureType::Palette8bpp:
+ tlutOffset = StringHelper::StrToL(std::string(tlutOffsetXml), 16);
+ break;
+
+ default:
+ throw std::runtime_error(StringHelper::Sprintf(
+ "ZTexture::ParseXML: Error in %s\n"
+ "\t 'TlutOffset' declared in non color-indexed (ci4 or ci8) texture.\n",
+ name.c_str()));
+ break;
}
}
- else if (type == TextureType::RGBA16bpp) // || type == TextureType::GrayscaleAlpha16bpp)
- {
- for (size_t i = 0; i < rawData.size(); i += 2)
- {
- uint8_t tmp = rawData[i];
- rawData[i] = rawData[i + 1];
- rawData[i + 1] = tmp;
- }
- }
-
- isRawDataFixed = !isRawDataFixed;
}
-void ZTexture::PrepareBitmap()
+void ZTexture::ParseRawData()
{
- switch (type)
- {
- case TextureType::RGBA16bpp:
- case TextureType::RGBA32bpp:
- case TextureType::GrayscaleAlpha4bpp:
- case TextureType::GrayscaleAlpha8bpp:
- case TextureType::GrayscaleAlpha16bpp:
- bmpRgba = new uint8_t[width * height * 4];
- break;
- default:
- bmpRgb = new uint8_t[width * height * 3];
- break;
- }
-
- switch (type)
+ switch (format)
{
case TextureType::RGBA16bpp:
PrepareBitmapRGBA16();
@@ -265,60 +150,62 @@ void ZTexture::PrepareBitmap()
void ZTexture::PrepareBitmapRGBA16()
{
- for (int32_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (int32_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- int32_t pos = ((y * width) + x) * 2;
- short data = (short)((rawData[pos + 1] << 8) + rawData[pos]);
- uint8_t r = (uint8_t)((data & 0xF800) >> 11);
- uint8_t g = (uint8_t)((data & 0x07C0) >> 6);
- uint8_t b = (uint8_t)((data & 0x003E) >> 1);
- uint8_t alpha = (uint8_t)(data & 0x01);
-
- bmpRgba[(((y * width) + x) * 4) + 0] = r * 8;
- bmpRgba[(((y * width) + x) * 4) + 1] = g * 8;
- bmpRgba[(((y * width) + x) * 4) + 2] = b * 8;
- bmpRgba[(((y * width) + x) * 4) + 3] = alpha * 255;
+ int32_t pos = rawDataIndex + ((y * width) + x) * 2;
+ uint16_t data = parentRawData.at(pos + 1) | (parentRawData.at(pos) << 8);
+ uint8_t r = (data & 0xF800) >> 11;
+ uint8_t g = (data & 0x07C0) >> 6;
+ uint8_t b = (data & 0x003E) >> 1;
+ uint8_t alpha = data & 0x01;
+
+ textureData.SetRGBPixel(y, x, r * 8, g * 8, b * 8, alpha * 255);
}
}
}
void ZTexture::PrepareBitmapRGBA32()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 4;
+ size_t pos = rawDataIndex + ((y * width) + x) * 4;
+ uint8_t r = parentRawData.at(pos + 0);
+ uint8_t g = parentRawData.at(pos + 1);
+ uint8_t b = parentRawData.at(pos + 2);
+ uint8_t alpha = parentRawData.at(pos + 3);
- bmpRgba[(((y * width) + x) * 4) + 0] = rawData[pos + 2];
- bmpRgba[(((y * width) + x) * 4) + 1] = rawData[pos + 1];
- bmpRgba[(((y * width) + x) * 4) + 2] = rawData[pos + 0];
- bmpRgba[(((y * width) + x) * 4) + 3] = rawData[pos + 3];
+ textureData.SetRGBPixel(y, x, r, g, b, alpha);
}
}
}
void ZTexture::PrepareBitmapGrayscale4()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, false);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x += 2)
+ for (size_t x = 0; x < width; x += 2)
{
for (uint8_t i = 0; i < 2; i++)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = rawDataIndex + ((y * width) + x) / 2;
uint8_t grayscale = 0;
if (i == 0)
- grayscale = rawData[pos] & 0xF0;
+ grayscale = parentRawData.at(pos) & 0xF0;
else
- grayscale = (rawData[pos] & 0x0F) << 4;
+ grayscale = (parentRawData.at(pos) & 0x0F) << 4;
- bmpRgb[(((y * width) + x + i) * 3) + 0] = grayscale;
- bmpRgb[(((y * width) + x + i) * 3) + 1] = grayscale;
- bmpRgb[(((y * width) + x + i) * 3) + 2] = grayscale;
+ textureData.SetGrayscalePixel(y, x + i, grayscale);
}
}
}
@@ -326,42 +213,41 @@ void ZTexture::PrepareBitmapGrayscale4()
void ZTexture::PrepareBitmapGrayscale8()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, false);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
+ size_t pos = rawDataIndex + ((y * width) + x) * 1;
- bmpRgb[(((y * width) + x) * 3) + 0] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 1] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 2] = rawData[pos];
+ textureData.SetGrayscalePixel(y, x, parentRawData.at(pos));
}
}
}
void ZTexture::PrepareBitmapGrayscaleAlpha4()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x += 2)
+ for (size_t x = 0; x < width; x += 2)
{
for (uint16_t i = 0; i < 2; i++)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = rawDataIndex + ((y * width) + x) / 2;
uint8_t data = 0;
if (i == 0)
- data = (rawData[pos] & 0xF0) >> 4;
+ data = (parentRawData.at(pos) & 0xF0) >> 4;
else
- data = rawData[pos] & 0x0F;
+ data = parentRawData.at(pos) & 0x0F;
uint8_t grayscale = ((data & 0x0E) >> 1) * 32;
uint8_t alpha = (data & 0x01) * 255;
- bmpRgba[(((y * width) + x + i) * 4) + 0] = grayscale;
- bmpRgba[(((y * width) + x + i) * 4) + 1] = grayscale;
- bmpRgba[(((y * width) + x + i) * 4) + 2] = grayscale;
- bmpRgba[(((y * width) + x + i) * 4) + 3] = alpha;
+ textureData.SetGrayscalePixel(y, x + i, grayscale, alpha);
}
}
}
@@ -369,59 +255,57 @@ void ZTexture::PrepareBitmapGrayscaleAlpha4()
void ZTexture::PrepareBitmapGrayscaleAlpha8()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
- uint8_t grayscale = rawData[pos] & 0xF0;
- uint8_t alpha = (rawData[pos] & 0x0F) << 4;
-
- bmpRgba[(((y * width) + x) * 4) + 0] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 1] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 2] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 3] = alpha;
+ size_t pos = rawDataIndex + ((y * width) + x) * 1;
+ uint8_t grayscale = parentRawData.at(pos) & 0xF0;
+ uint8_t alpha = (parentRawData.at(pos) & 0x0F) << 4;
+
+ textureData.SetGrayscalePixel(y, x, grayscale, alpha);
}
}
}
void ZTexture::PrepareBitmapGrayscaleAlpha16()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyRGBImage(width, height, true);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 2;
- uint8_t grayscale = rawData[pos + 0];
- uint8_t alpha = rawData[pos + 1];
-
- bmpRgba[(((y * width) + x) * 4) + 0] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 1] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 2] = grayscale;
- bmpRgba[(((y * width) + x) * 4) + 3] = alpha;
+ size_t pos = rawDataIndex + ((y * width) + x) * 2;
+ uint8_t grayscale = parentRawData.at(pos + 0);
+ uint8_t alpha = parentRawData.at(pos + 1);
+
+ textureData.SetGrayscalePixel(y, x, grayscale, alpha);
}
}
}
void ZTexture::PrepareBitmapPalette4()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyPaletteImage(width, height);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x += 2)
+ for (size_t x = 0; x < width; x += 2)
{
for (uint16_t i = 0; i < 2; i++)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = rawDataIndex + ((y * width) + x) / 2;
uint8_t paletteIndex = 0;
if (i == 0)
- paletteIndex = (rawData[pos] & 0xF0) >> 4;
+ paletteIndex = (parentRawData.at(pos) & 0xF0) >> 4;
else
- paletteIndex = (rawData[pos] & 0x0F);
+ paletteIndex = (parentRawData.at(pos) & 0x0F);
- bmpRgb[(((y * width) + x + i) * 3) + 0] = paletteIndex * 16;
- bmpRgb[(((y * width) + x + i) * 3) + 1] = paletteIndex * 16;
- bmpRgb[(((y * width) + x + i) * 3) + 2] = paletteIndex * 16;
+ textureData.SetIndexedPixel(y, x + i, paletteIndex, paletteIndex * 16);
}
}
}
@@ -429,267 +313,310 @@ void ZTexture::PrepareBitmapPalette4()
void ZTexture::PrepareBitmapPalette8()
{
- for (uint16_t y = 0; y < height; y++)
+ textureData.InitEmptyPaletteImage(width, height);
+ auto parentRawData = parent->GetRawData();
+ for (size_t y = 0; y < height; y++)
{
- for (uint16_t x = 0; x < width; x++)
+ for (size_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
+ size_t pos = rawDataIndex + ((y * width) + x) * 1;
+ uint8_t grayscale = parentRawData.at(pos);
- bmpRgb[(((y * width) + x) * 3) + 0] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 1] = rawData[pos];
- bmpRgb[(((y * width) + x) * 3) + 2] = rawData[pos];
+ textureData.SetIndexedPixel(y, x, grayscale, grayscale);
}
}
}
-void ZTexture::PrepareRawData(string inFolder)
+void ZTexture::DeclareReferences(const std::string& prefix)
{
- rawData = vector<uint8_t>(GetRawDataSize());
+ if (tlutOffset != static_cast<uint32_t>(-1))
+ {
+ tlut = parent->GetTextureResource(tlutOffset);
+ if (tlut == nullptr)
+ {
+ int32_t tlutDim = 16;
+ if (format == TextureType::Palette4bpp)
+ tlutDim = 4;
+
+ auto filepath = Globals::Instance->outputPath / fs::path(name).stem();
+ std::string incStr = StringHelper::Sprintf("%s.%s.inc.c", filepath.c_str(),
+ GetExternalExtension().c_str());
+
+ tlut = new ZTexture(parent);
+ tlut->FromBinary(rawData, tlutOffset, tlutDim, tlutDim, TextureType::RGBA16bpp, true);
+ parent->AddTextureResource(tlutOffset, tlut);
+ parent->AddDeclarationIncludeArray(tlutOffset, incStr, tlut->GetRawDataSize(),
+ tlut->GetSourceTypeName(), tlut->GetName(), 0);
+ }
+ else
+ {
+ tlut->isPalette = true;
+ }
+ SetTlut(tlut);
+ }
+}
- switch (type)
+void ZTexture::PrepareRawDataFromFile(const fs::path& pngFilePath)
+{
+ switch (format)
{
case TextureType::RGBA16bpp:
- PrepareRawDataRGBA16(inFolder + "/" + outName + ".rgba5a1.png");
+ PrepareRawDataRGBA16(pngFilePath);
break;
case TextureType::RGBA32bpp:
- PrepareRawDataRGBA32(inFolder + "/" + outName + ".rgba32.png");
+ PrepareRawDataRGBA32(pngFilePath);
break;
case TextureType::Grayscale4bpp:
- PrepareRawDataGrayscale4(inFolder + "/" + outName + ".i4.png");
+ PrepareRawDataGrayscale4(pngFilePath);
break;
case TextureType::Grayscale8bpp:
- PrepareRawDataGrayscale8(inFolder + "/" + outName + ".i8.png");
+ PrepareRawDataGrayscale8(pngFilePath);
break;
case TextureType::GrayscaleAlpha4bpp:
- PrepareRawDataGrayscaleAlpha4(inFolder + "/" + outName + ".ia4.png");
+ PrepareRawDataGrayscaleAlpha4(pngFilePath);
break;
case TextureType::GrayscaleAlpha8bpp:
- PrepareRawDataGrayscaleAlpha8(inFolder + "/" + outName + ".ia8.png");
+ PrepareRawDataGrayscaleAlpha8(pngFilePath);
break;
case TextureType::GrayscaleAlpha16bpp:
- PrepareRawDataGrayscaleAlpha16(inFolder + "/" + outName + ".ia16.png");
+ PrepareRawDataGrayscaleAlpha16(pngFilePath);
break;
case TextureType::Palette4bpp:
- PrepareRawDataPalette4(inFolder + "/" + outName + ".ci4.png");
+ PrepareRawDataPalette4(pngFilePath);
break;
case TextureType::Palette8bpp:
- PrepareRawDataPalette8(inFolder + "/" + outName + ".ci8.png");
+ PrepareRawDataPalette8(pngFilePath);
break;
default:
- throw std::runtime_error("Build Mode: Format is not supported!");
+ throw std::runtime_error("Format is not supported!");
}
}
-void ZTexture::PrepareRawDataRGBA16(string rgbaPath)
+void ZTexture::PrepareRawDataRGBA16(const fs::path& rgbaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(rgbaPath);
- bmpRgba = (uint8_t*)stbi_load(rgbaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 2;
+ size_t pos = ((y * width) + x) * 2;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- uint8_t r = bmpRgba[(((y * width) + x) * 4) + 0] / 8;
- uint8_t g = bmpRgba[(((y * width) + x) * 4) + 1] / 8;
- uint8_t b = bmpRgba[(((y * width) + x) * 4) + 2] / 8;
+ uint8_t r = pixel.r / 8;
+ uint8_t g = pixel.g / 8;
+ uint8_t b = pixel.b / 8;
- uint8_t alphaBit = bmpRgba[(((y * width) + x) * 4) + 3] != 0;
+ uint8_t alphaBit = pixel.a != 0;
uint16_t data = (r << 11) + (g << 6) + (b << 1) + alphaBit;
- rawData[pos + 0] = (data & 0xFF00) >> 8;
- rawData[pos + 1] = (data & 0x00FF);
+ textureDataRaw[pos + 0] = (data & 0xFF00) >> 8;
+ textureDataRaw[pos + 1] = (data & 0x00FF);
}
}
}
-void ZTexture::PrepareRawDataRGBA32(string rgbaPath)
+void ZTexture::PrepareRawDataRGBA32(const fs::path& rgbaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(rgbaPath);
- bmpRgba = (uint8_t*)stbi_load(rgbaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 4;
+ size_t pos = ((y * width) + x) * 4;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- rawData[pos + 0] = bmpRgba[(((y * width) + x) * 4) + 0];
- rawData[pos + 1] = bmpRgba[(((y * width) + x) * 4) + 1];
- rawData[pos + 2] = bmpRgba[(((y * width) + x) * 4) + 2];
- rawData[pos + 3] = bmpRgba[(((y * width) + x) * 4) + 3];
+ textureDataRaw[pos + 0] = pixel.r;
+ textureDataRaw[pos + 1] = pixel.g;
+ textureDataRaw[pos + 2] = pixel.b;
+ textureDataRaw[pos + 3] = pixel.a;
}
}
}
-void ZTexture::PrepareRawDataGrayscale4(string grayPath)
+void ZTexture::PrepareRawDataGrayscale4(const fs::path& grayPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayPath);
- bmpRgb = (uint8_t*)stbi_load(grayPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x += 2)
{
- uint16_t pos = ((y * width) + x) / 2;
- uint8_t r1 = bmpRgb[(((y * width) + x) * 3) + 0];
- uint8_t r2 = bmpRgb[(((y * width) + x + 1) * 3) + 0];
+ size_t pos = ((y * width) + x) / 2;
+ uint8_t r1 = textureData.GetPixel(y, x).r;
+ uint8_t r2 = textureData.GetPixel(y, x + 1).r;
- rawData[pos] = (uint8_t)(((r1 / 16) << 4) + (r2 / 16));
+ textureDataRaw[pos] = (uint8_t)(((r1 / 16) << 4) + (r2 / 16));
}
}
}
-void ZTexture::PrepareRawDataGrayscale8(string grayPath)
+void ZTexture::PrepareRawDataGrayscale8(const fs::path& grayPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayPath);
- bmpRgb = (uint8_t*)stbi_load(grayPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = (y * width) + x;
- rawData[pos] = bmpRgb[(((y * width) + x) * 3) + 0];
+ size_t pos = (y * width) + x;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
+ textureDataRaw[pos] = pixel.r;
}
}
}
-void ZTexture::PrepareRawDataGrayscaleAlpha4(string grayAlphaPath)
+void ZTexture::PrepareRawDataGrayscaleAlpha4(const fs::path& grayAlphaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayAlphaPath);
- bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x += 2)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = ((y * width) + x) / 2;
uint8_t data = 0;
for (uint16_t i = 0; i < 2; i++)
{
- uint8_t cR = bmpRgba[(((y * width) + x + i) * 4) + 0];
- uint8_t alphaBit = bmpRgba[(((y * width) + x + i) * 4) + 3] != 0;
+ RGBAPixel pixel = textureData.GetPixel(y, x + i);
+ uint8_t cR = pixel.r;
+ uint8_t alphaBit = pixel.a != 0;
if (i == 0)
- data += (((cR / 32) << 1) + alphaBit) << 4;
+ data |= (((cR / 32) << 1) + alphaBit) << 4;
else
- data += ((cR / 32) << 1) + alphaBit;
+ data |= ((cR / 32) << 1) + alphaBit;
}
- rawData[pos] = data;
+ textureDataRaw[pos] = data;
}
}
}
-void ZTexture::PrepareRawDataGrayscaleAlpha8(string grayAlphaPath)
+void ZTexture::PrepareRawDataGrayscaleAlpha8(const fs::path& grayAlphaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayAlphaPath);
- bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 1;
+ size_t pos = ((y * width) + x) * 1;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- uint8_t r = bmpRgba[(((y * width) + x) * 4) + 0];
- uint8_t a = bmpRgba[(((y * width) + x) * 4) + 3];
+ uint8_t r = pixel.r;
+ uint8_t a = pixel.a;
- rawData[pos] = ((r / 16) << 4) + (a / 16);
+ textureDataRaw[pos] = ((r / 16) << 4) + (a / 16);
}
}
}
-void ZTexture::PrepareRawDataGrayscaleAlpha16(string grayAlphaPath)
+void ZTexture::PrepareRawDataGrayscaleAlpha16(const fs::path& grayAlphaPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(grayAlphaPath);
- bmpRgba = (uint8_t*)stbi_load(grayAlphaPath.c_str(), &width, &height, &comp, STBI_rgb_alpha);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x) * 2;
+ size_t pos = ((y * width) + x) * 2;
+ RGBAPixel pixel = textureData.GetPixel(y, x);
- uint8_t cR = bmpRgba[(((y * width) + x) * 4) + 0];
- uint8_t aR = bmpRgba[(((y * width) + x) * 4) + 3];
+ uint8_t cR = pixel.r;
+ uint8_t aR = pixel.a;
- rawData[pos + 0] = cR;
- rawData[pos + 1] = aR;
+ textureDataRaw[pos + 0] = cR;
+ textureDataRaw[pos + 1] = aR;
}
}
}
-void ZTexture::PrepareRawDataPalette4(string palPath)
+void ZTexture::PrepareRawDataPalette4(const fs::path& palPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(palPath);
- bmpRgb = (uint8_t*)stbi_load(palPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x += 2)
{
- uint16_t pos = ((y * width) + x) / 2;
+ size_t pos = ((y * width) + x) / 2;
- uint8_t cR1 = bmpRgb[(((y * width) + x) * 3) + 0];
- uint8_t cR2 = bmpRgb[(((y * width) + x + 1) * 3) + 0];
+ uint8_t cR1 = textureData.GetIndexedPixel(y, x);
+ uint8_t cR2 = textureData.GetIndexedPixel(y, x + 1);
- rawData[pos] = ((cR1 / 16) << 4) + (cR2 / 16);
+ textureDataRaw[pos] = (cR1 << 4) | (cR2);
}
}
}
-void ZTexture::PrepareRawDataPalette8(string palPath)
+void ZTexture::PrepareRawDataPalette8(const fs::path& palPath)
{
- int32_t width;
- int32_t height;
- int32_t comp;
+ textureData.ReadPng(palPath);
- bmpRgb = (uint8_t*)stbi_load(palPath.c_str(), &width, &height, &comp, STBI_rgb);
+ width = textureData.GetWidth();
+ height = textureData.GetHeight();
+ textureDataRaw.clear();
+ textureDataRaw.resize(GetRawDataSize());
for (uint16_t y = 0; y < height; y++)
{
for (uint16_t x = 0; x < width; x++)
{
- uint16_t pos = ((y * width) + x);
+ size_t pos = ((y * width) + x);
+ uint8_t cR = textureData.GetIndexedPixel(y, x);
- uint8_t cR = bmpRgb[(((y * width) + x) * 3) + 0];
- rawData[pos] = cR;
+ textureDataRaw[pos] = cR;
}
}
}
-float ZTexture::GetPixelMultiplyer()
+float ZTexture::GetPixelMultiplyer() const
{
- switch (type)
+ switch (format)
{
case TextureType::Grayscale4bpp:
case TextureType::GrayscaleAlpha4bpp:
@@ -716,7 +643,7 @@ size_t ZTexture::GetRawDataSize()
std::string ZTexture::GetIMFmtFromType()
{
- switch (type)
+ switch (format)
{
case TextureType::RGBA32bpp:
case TextureType::RGBA16bpp:
@@ -738,7 +665,7 @@ std::string ZTexture::GetIMFmtFromType()
std::string ZTexture::GetIMSizFromType()
{
- switch (type)
+ switch (format)
{
case TextureType::Grayscale4bpp:
case TextureType::Palette4bpp:
@@ -757,99 +684,78 @@ std::string ZTexture::GetIMSizFromType()
}
}
-uint16_t ZTexture::GetWidth()
+std::string ZTexture::GetDefaultName(const std::string& prefix)
{
- return width;
+ const char* suffix = "Tex";
+ if (isPalette)
+ suffix = "TLUT";
+ return StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), suffix, rawDataIndex);
}
-uint16_t ZTexture::GetHeight()
+uint32_t ZTexture::GetWidth() const
{
- return height;
+ return width;
}
-void ZTexture::SetWidth(uint16_t nWidth)
+uint32_t ZTexture::GetHeight() const
{
- width = nWidth;
+ return height;
}
-void ZTexture::SetHeight(uint16_t nHeight)
+void ZTexture::SetDimensions(uint32_t nWidth, uint32_t nHeight)
{
+ width = nWidth;
height = nHeight;
+ ParseRawData();
}
TextureType ZTexture::GetTextureType()
{
- return type;
+ return format;
}
-void ZTexture::Save(const std::string& outFolder)
+void ZTexture::Save(const fs::path& outFolder)
{
// Optionally generate text file containing CRC information. This is going to be a one time
// process for generating the Texture Pool XML.
- if (Globals::Instance->testMode)
+ if (Globals::Instance->outputCrc)
{
- if (hash != 0)
- {
- File::WriteAllText(StringHelper::Sprintf("%s/%s.txt",
- Globals::Instance->outputPath.c_str(),
- outName.c_str()),
- StringHelper::Sprintf("%08lX", hash));
- hash = 0;
- }
+ File::WriteAllText(Globals::Instance->outputPath / (outName + ".txt"),
+ StringHelper::Sprintf("%08lX", hash));
}
- std::string outPath = GetPoolOutPath(outFolder);
+ auto outPath = GetPoolOutPath(outFolder);
if (!Directory::Exists(outPath))
Directory::CreateDirectory(outPath);
- if (type == TextureType::RGBA32bpp)
- stbi_write_png((outPath + "/" + outName + ".rgba32.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::RGBA16bpp)
- stbi_write_png((outPath + "/" + outName + ".rgb5a1.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::Grayscale8bpp)
- stbi_write_png((outPath + "/" + outName + ".i8.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
- else if (type == TextureType::Grayscale4bpp)
- stbi_write_png((outPath + "/" + outName + ".i4.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
- else if (type == TextureType::GrayscaleAlpha16bpp)
- stbi_write_png((outPath + "/" + outName + ".ia16.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::GrayscaleAlpha8bpp)
- stbi_write_png((outPath + "/" + outName + ".ia8.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::GrayscaleAlpha4bpp)
- stbi_write_png((outPath + "/" + outName + ".ia4.png").c_str(), width, height, 4, bmpRgba,
- width * 4);
- else if (type == TextureType::Palette4bpp)
- stbi_write_png((outPath + "/" + outName + ".ci4.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
- else if (type == TextureType::Palette8bpp)
- stbi_write_png((outPath + "/" + outName + ".ci8.png").c_str(), width, height, 3, bmpRgb,
- width * 3);
-
- // if (outName != name && outName != "")
- // File::WriteAllText(outFolder + "/" + outName + ".cfg", name.c_str());
-}
-
-string ZTexture::GetSourceOutputCode(const std::string& prefix)
-{
- sourceOutput = "";
-
- FixRawData();
-
- uint8_t* rawDataArr = rawData.data();
-
- for (size_t i = 0; i < rawData.size(); i += 8)
+ auto outFileName = outPath / (outName + "." + GetExternalExtension() + ".png");
+
+#ifdef TEXTURE_DEBUG
+ printf("Saving PNG: %s\n", outFileName.c_str());
+ printf("\t Var name: %s\n", name.c_str());
+ if (tlut != nullptr)
+ printf("\t TLUT name: %s\n", tlut->name.c_str());
+#endif
+
+ textureData.WritePng(outFileName);
+
+#ifdef TEXTURE_DEBUG
+ printf("\n");
+#endif
+}
+
+std::string ZTexture::GetBodySourceCode() const
+{
+ std::string sourceOutput = "";
+
+ for (size_t i = 0; i < textureDataRaw.size(); i += 8)
{
if (i % 32 == 0)
sourceOutput += " ";
sourceOutput +=
- StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(rawDataArr, i));
+ StringHelper::Sprintf("0x%016llX, ", BitConverter::ToUInt64BE(textureDataRaw, i));
if (i % 32 == 24)
sourceOutput += StringHelper::Sprintf(" // 0x%06X \n", rawDataIndex + ((i / 32) * 32));
@@ -880,21 +786,13 @@ std::string ZTexture::GetSourceTypeName()
void ZTexture::CalcHash()
{
- // Make sure raw data is fixed before we calc the hash...
- bool fixFlag = !isRawDataFixed;
-
- if (fixFlag)
- FixRawData();
-
- hash = CRC32B(rawData.data(), GetRawDataSize());
-
- if (fixFlag)
- FixRawData();
+ auto parentRawData = parent->GetRawData();
+ hash = CRC32B(parentRawData.data() + rawDataIndex, GetRawDataSize());
}
std::string ZTexture::GetExternalExtension()
{
- switch (type)
+ switch (format)
{
case TextureType::RGBA32bpp:
return "rgba32";
@@ -919,7 +817,7 @@ std::string ZTexture::GetExternalExtension()
}
}
-std::string ZTexture::GetPoolOutPath(std::string defaultValue)
+fs::path ZTexture::GetPoolOutPath(const fs::path& defaultValue)
{
if (Globals::Instance->cfg.texturePool.find(hash) != Globals::Instance->cfg.texturePool.end())
return Path::GetDirectoryName(Globals::Instance->cfg.texturePool[hash].path.string());
@@ -927,12 +825,7 @@ std::string ZTexture::GetPoolOutPath(std::string defaultValue)
return defaultValue;
}
-string ZTexture::GetSourceOutputHeader(const std::string& prefix)
-{
- return "";
-}
-
-TextureType ZTexture::GetTextureTypeFromString(string str)
+TextureType ZTexture::GetTextureTypeFromString(std::string str)
{
TextureType texType = TextureType::Error;
@@ -955,6 +848,33 @@ TextureType ZTexture::GetTextureTypeFromString(string str)
else if (str == "ci8")
texType = TextureType::Palette8bpp;
else
- fprintf(stderr, "Encountered Unknown Texture Type %s \n", str.c_str());
+ fprintf(stderr, "Encountered Unknown Texture format %s \n", str.c_str());
return texType;
}
+
+bool ZTexture::IsColorIndexed() const
+{
+ switch (format)
+ {
+ case TextureType::Palette4bpp:
+ case TextureType::Palette8bpp:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+void ZTexture::SetTlut(ZTexture* nTlut)
+{
+ assert(IsColorIndexed());
+ assert(nTlut->isPalette);
+ tlut = nTlut;
+
+ textureData.SetPalette(tlut->textureData);
+}
+
+bool ZTexture::HasTlut() const
+{
+ return tlut != nullptr;
+}
diff --git a/ZAPD/ZTexture.h b/ZAPD/ZTexture.h
index ef87441..aea2cd3 100644
--- a/ZAPD/ZTexture.h
+++ b/ZAPD/ZTexture.h
@@ -1,13 +1,15 @@
#pragma once
+#include <vector>
+
#include "HighLevel/HLTexture.h"
+#include "ImageBackend.h"
#include "ZResource.h"
#include "tinyxml2.h"
-#include <vector>
-
enum class TextureType
{
+ Error,
RGBA32bpp,
RGBA16bpp,
Palette4bpp,
@@ -17,25 +19,19 @@ enum class TextureType
GrayscaleAlpha4bpp,
GrayscaleAlpha8bpp,
GrayscaleAlpha16bpp,
- Error
};
class ZTexture : public ZResource
{
protected:
- TextureType type;
- uint16_t width, height;
+ TextureType format = TextureType::Error;
+ uint32_t width, height;
- uint8_t* bmpRgb;
- uint8_t* bmpRgba;
- bool isRawDataFixed;
+ ImageBackend textureData;
+ std::vector<uint8_t> textureDataRaw; // When reading from a PNG file.
+ uint32_t tlutOffset = static_cast<uint32_t>(-1);
+ ZTexture* tlut = nullptr;
- void ParseXML(tinyxml2::XMLElement* reader) override;
- void FixRawData();
- void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
- const uint32_t nRawDataIndex) override; // Extract Mode
-
- void PrepareBitmap();
void PrepareBitmapRGBA16();
void PrepareBitmapRGBA32();
void PrepareBitmapGrayscale8();
@@ -45,52 +41,54 @@ protected:
void PrepareBitmapGrayscaleAlpha16();
void PrepareBitmapPalette4();
void PrepareBitmapPalette8();
- void PrepareRawData(std::string inFolder);
- void PrepareRawDataRGBA16(std::string rgbaPath);
- void PrepareRawDataRGBA32(std::string rgbaPath);
- void PrepareRawDataGrayscale4(std::string grayPath);
- void PrepareRawDataGrayscale8(std::string grayPath);
- void PrepareRawDataGrayscaleAlpha4(std::string grayAlphaPath);
- void PrepareRawDataGrayscaleAlpha8(std::string grayAlphaPath);
- void PrepareRawDataGrayscaleAlpha16(std::string grayAlphaPath);
- void PrepareRawDataPalette4(std::string palPath);
- void PrepareRawDataPalette8(std::string palPath);
- float GetPixelMultiplyer();
+
+ void PrepareRawDataFromFile(const fs::path& inFolder);
+ void PrepareRawDataRGBA16(const fs::path& rgbaPath);
+ void PrepareRawDataRGBA32(const fs::path& rgbaPath);
+ void PrepareRawDataGrayscale4(const fs::path& grayPath);
+ void PrepareRawDataGrayscale8(const fs::path& grayPath);
+ void PrepareRawDataGrayscaleAlpha4(const fs::path& grayAlphaPath);
+ void PrepareRawDataGrayscaleAlpha8(const fs::path& grayAlphaPath);
+ void PrepareRawDataGrayscaleAlpha16(const fs::path& grayAlphaPath);
+ void PrepareRawDataPalette4(const fs::path& palPath);
+ void PrepareRawDataPalette8(const fs::path& palPath);
public:
ZTexture(ZFile* nParent);
- ~ZTexture();
- bool isPalette;
+ bool isPalette = false;
- static ZTexture* BuildFromXML(tinyxml2::XMLElement* reader, std::string inFolder,
- bool readFile);
- // static ZTexture* ExtractFromXML(tinyxml2::XMLElement* reader, std::vector<uint8_t> nRawData,
- // uint32_t rawDataIndex, std::string nRelPath, ZFile* nParent);
- static ZTexture* FromBinary(TextureType nType, std::vector<uint8_t> nRawData,
- uint32_t rawDataIndex, std::string nName, int32_t nWidth,
- int32_t nHeight, ZFile* nParent);
- static ZTexture* FromPNG(std::string pngFilePath, TextureType texType);
- static ZTexture* FromHLTexture(HLTexture* hlTex);
+ void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
+ const uint32_t nRawDataIndex) override;
+ void FromBinary(const std::vector<uint8_t>& nRawData, uint32_t nRawDataIndex, int32_t nWidth,
+ int32_t nHeight, TextureType nType, bool nIsPalette);
+ void FromPNG(const fs::path& pngFilePath, TextureType texType);
+ void FromHLTexture(HLTexture* hlTex);
static TextureType GetTextureTypeFromString(std::string str);
- std::string GetSourceOutputCode(const std::string& prefix) override;
- std::string GetSourceOutputHeader(const std::string& prefix) override;
-
- size_t GetRawDataSize() override;
- std::string GetIMFmtFromType();
- std::string GetIMSizFromType();
- uint16_t GetWidth();
- uint16_t GetHeight();
- void SetWidth(uint16_t nWidth);
- void SetHeight(uint16_t nHeight);
- TextureType GetTextureType();
- void Save(const std::string& outFolder) override;
- std::string GetExternalExtension() override;
- std::string GetPoolOutPath(std::string defaultValue);
+ void ParseXML(tinyxml2::XMLElement* reader) override;
+ void ParseRawData() override;
+ void DeclareReferences(const std::string& prefix) override;
+ std::string GetBodySourceCode() const;
void CalcHash() override;
+ void Save(const fs::path& outFolder) override;
bool IsExternalResource() override;
std::string GetSourceTypeName() override;
ZResourceType GetResourceType() override;
+ std::string GetExternalExtension() override;
+
+ size_t GetRawDataSize() override;
+ std::string GetIMFmtFromType();
+ std::string GetIMSizFromType();
+ std::string GetDefaultName(const std::string& prefix);
+ uint32_t GetWidth() const;
+ uint32_t GetHeight() const;
+ void SetDimensions(uint32_t nWidth, uint32_t nHeight);
+ float GetPixelMultiplyer() const;
+ TextureType GetTextureType();
+ fs::path GetPoolOutPath(const fs::path& defaultValue);
+ bool IsColorIndexed() const;
+ void SetTlut(ZTexture* nTlut);
+ bool HasTlut() const;
};
diff --git a/ZAPD/ZVtx.cpp b/ZAPD/ZVtx.cpp
index 4c80895..eacf563 100644
--- a/ZAPD/ZVtx.cpp
+++ b/ZAPD/ZVtx.cpp
@@ -19,8 +19,24 @@ ZVtx::ZVtx(ZFile* nParent) : ZResource(nParent)
a = 0;
}
-void ZVtx::ParseXML(tinyxml2::XMLElement* reader)
+void ZVtx::ParseRawData()
{
+ x = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
+ y = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
+ z = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
+ flag = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
+ s = BitConverter::ToInt16BE(rawData, rawDataIndex + 8);
+ t = BitConverter::ToInt16BE(rawData, rawDataIndex + 10);
+ r = rawData[rawDataIndex + 12];
+ g = rawData[rawDataIndex + 13];
+ b = rawData[rawDataIndex + 14];
+ a = rawData[rawDataIndex + 15];
+}
+
+std::string ZVtx::GetBodySourceCode() const
+{
+ return StringHelper::Sprintf("VTX(%i, %i, %i, %i, %i, %i, %i, %i, %i)", x, y, z, s, t, r, g, b,
+ a);
}
std::string ZVtx::GetSourceTypeName()
@@ -30,8 +46,7 @@ std::string ZVtx::GetSourceTypeName()
std::string ZVtx::GetSourceOutputCode(const std::string& prefix)
{
- std::string output =
- StringHelper::Sprintf("VTX(%i, %i, %i, %i, %i, %i, %i, %i, %i)", x, y, z, s, t, r, g, b, a);
+ std::string output = GetBodySourceCode();
if (parent != nullptr)
{
@@ -44,22 +59,6 @@ std::string ZVtx::GetSourceOutputCode(const std::string& prefix)
return "";
}
-void ZVtx::ParseRawData()
-{
- const uint8_t* data = rawData.data();
-
- x = BitConverter::ToInt16BE(data, rawDataIndex + 0);
- y = BitConverter::ToInt16BE(data, rawDataIndex + 2);
- z = BitConverter::ToInt16BE(data, rawDataIndex + 4);
- flag = BitConverter::ToInt16BE(data, rawDataIndex + 6);
- s = BitConverter::ToInt16BE(data, rawDataIndex + 8);
- t = BitConverter::ToInt16BE(data, rawDataIndex + 10);
- r = data[rawDataIndex + 12];
- g = data[rawDataIndex + 13];
- b = data[rawDataIndex + 14];
- a = data[rawDataIndex + 15];
-}
-
size_t ZVtx::GetRawDataSize()
{
return 16;
diff --git a/ZAPD/ZVtx.h b/ZAPD/ZVtx.h
index d400d44..0caed82 100644
--- a/ZAPD/ZVtx.h
+++ b/ZAPD/ZVtx.h
@@ -17,18 +17,20 @@ public:
ZVtx(ZFile* nParent);
- void ParseXML(tinyxml2::XMLElement* reader) override;
- std::string GetSourceTypeName() override;
- std::string GetSourceOutputCode(const std::string& prefix) override;
+ void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
+ const uint32_t nRawDataIndex) override;
+
void ParseRawData() override;
- size_t GetRawDataSize() override;
+ std::string GetBodySourceCode() const;
+ std::string GetSourceOutputCode(const std::string& prefix) override;
+
+ bool IsExternalResource() override;
bool DoesSupportArray() override;
+ std::string GetSourceTypeName() override;
ZResourceType GetResourceType() override;
- bool IsExternalResource() override;
virtual std::string GetExternalExtension() override;
- void ExtractFromXML(tinyxml2::XMLElement* reader, const std::vector<uint8_t>& nRawData,
- const uint32_t nRawDataIndex) override;
+ size_t GetRawDataSize() override;
protected:
}; \ No newline at end of file