summaryrefslogtreecommitdiff
path: root/ZAPD/ZTextureAnimation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ZAPD/ZTextureAnimation.cpp')
-rw-r--r--ZAPD/ZTextureAnimation.cpp729
1 files changed, 729 insertions, 0 deletions
diff --git a/ZAPD/ZTextureAnimation.cpp b/ZAPD/ZTextureAnimation.cpp
new file mode 100644
index 0000000..e8236f1
--- /dev/null
+++ b/ZAPD/ZTextureAnimation.cpp
@@ -0,0 +1,729 @@
+/**
+ * File: ZTextureAnimation.cpp
+ * ZResources defined: ZTextureAnimation, ZTextureAnimationParams (XML declaration not supported for
+ * the latter)
+ * Purpose: extracting texture animating structures from asset files Note: data type is exclusive to
+ * Majora's Mask
+ *
+ * Structure of data:
+ * A texture animation consists of a main array of data of the form
+ * `SS 00 00 0T PPPPPPPP`,
+ * where `S` is the segment that the functionality is sent to (and read by DLists), `T` is the
+ * "type" (see below), and `P` is a pointer to the type's subsidiary information, which is
+ * invariably just above this main array. Details of this subsidiary data are given below.
+ *
+ * Segment
+ * ===
+ * The segment starts at 1 and is incremented in each entry; the final one is negated, which is used
+ * as the indication to stop reading. The actual segment the game will use to draw is S + 7.
+ *
+ * Types
+ * ===
+ * There are 7 values that `T` can take:
+ * `0`: A single texture scroll (Implemented by Gfx_TexScroll): subsidiary params are given as
+ * an array with one entry, a struct `XX YY WW HH` containing xStep, yStep, width, height
+ * (all u8).
+ *
+ * `1`: A dual texture scroll (Implementated by Gfx_TwoTexScroll): same as type `0`, but with
+ * two entries in the params array.
+ *
+ * `2`: Color changing: Changes the primColor (with a LOD factor) and envColor
+ * `KKKK LLLL PPPPPPPP QQQQQQQQ RRRRRRRR`
+ * - `K` (u16) is the total length of the animation (and in this case, the total number of
+ * colors)
+ * - `L` (u16) is seemingly always 0 for this type, and not used in the code
+ * - `P` segmented pointer to array of augmented primColors
+ * - `Q` segmented pointer to array of envColors, and can be NULL
+ * - `R` segmented pointer to array of frameData (u8), which is also seemingly always NULL
+ * for this type.
+ *
+ * envColors take the form `RR GG BB AA` as usual, while primColors have an extra LODFrac
+ * element: RR GG BB AA LL
+ *
+ * `3`: Color changing (LERP): similar to type `2`, but uses linear interpolation. The structure
+ * is similar to `2`, but
+ * - `K` is now just the animation length, while
+ * - `L` is the total number of colors, and
+ * - the frameData is used to determine which colors to interpolate.
+ *
+ * `4`: Color changing (Lagrange interpolation): For extraction purposes identical to type 3.
+ * Uses a nonlinear interpolation formula to change the colours more smoothly.
+ *
+ * `5`: Texture cycle: functions like a gif. Subsidiary params:
+ * `FFFF 0000 PPPPPPPP QQQQQQQQ`
+ * where
+ * - `F` (u16) time between changes in frames
+ * - `P` pointer to array of segmented pointers to textures to cycle through
+ * - `Q` array of indices, indicating which texture to use next when a change frame is
+ * reached. The maximum indicates the number of textures in the texture array.
+ *
+ * `6`: This is used to indicate an empty/unimplemented params set. It is ignored by the game's
+ * function provided that the segment is 0. A generic empty one takes the form
+ * `00 00 00 06 00000000`,
+ * and has no extra data.
+ *
+ * Implementation
+ * ===
+ * - ZTextureAnimation requires a declaration in the XML to extract anything. It handles the main
+ * array. It uses a POD struct for each entry, and declares references to the params structs.
+ *
+ * - ZTextureAnimationParams is not (currently) declarable in an XML. It is a parent class for the
+ * three classes that handle the various cases:
+ * - TextureScrollingParams for types `0` and `1`
+ * - TextureColorChangingParams for types `2`,`3`,`4`
+ * - TextureCyclingParams for type `5`
+ * Each of these will declare all its subsidiary arrays, using POD structs.
+ */
+#include "ZTextureAnimation.h"
+#include <cassert>
+#include <memory>
+#include <vector>
+#include "Globals.h"
+#include "Utils/BitConverter.h"
+#include "ZFile.h"
+#include "ZResource.h"
+#include "tinyxml2.h"
+
+REGISTER_ZFILENODE(TextureAnimation, ZTextureAnimation);
+
+/* Constructors */
+ZTextureAnimationParams::ZTextureAnimationParams(ZFile* parent) : ZResource::ZResource(parent)
+{
+}
+TextureScrollingParams::TextureScrollingParams(ZFile* parent)
+ : ZTextureAnimationParams::ZTextureAnimationParams(parent)
+{
+}
+TextureColorChangingParams::TextureColorChangingParams(ZFile* parent)
+ : ZTextureAnimationParams::ZTextureAnimationParams(parent)
+{
+}
+TextureCyclingParams::TextureCyclingParams(ZFile* parent)
+ : ZTextureAnimationParams::ZTextureAnimationParams(parent)
+{
+}
+
+/* TextureAnimationParams */
+/* This class only implements the functions common to all or most its inheritors */
+
+void ZTextureAnimationParams::ExtractFromBinary(uint32_t nRawDataIndex)
+{
+ rawDataIndex = nRawDataIndex;
+
+ ParseRawData();
+}
+
+// Implemented by TextureScrollingParams only[
+void ZTextureAnimationParams::ExtractFromBinary([[maybe_unused]] uint32_t nRawDataIndex,
+ [[maybe_unused]] int count)
+{
+}
+
+std::string
+ZTextureAnimationParams::GetDefaultName([[maybe_unused]] const std::string& prefix) const
+{
+ return "ShouldNotBeVIsible";
+}
+
+void ZTextureAnimationParams::DeclareVar(const std::string& prefix,
+ const std::string& bodyStr) const
+{
+ std::string auxName = name;
+
+ if (name == "")
+ auxName = GetDefaultName(prefix);
+
+ parent->AddDeclaration(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(),
+ GetSourceTypeName(), auxName, bodyStr);
+}
+
+std::string ZTextureAnimationParams::GetSourceOutputCode(const std::string& prefix)
+{
+ std::string bodyStr = GetBodySourceCode();
+
+ Declaration* decl = parent->GetDeclaration(rawDataIndex);
+
+ if (decl == nullptr)
+ DeclareVar(prefix, bodyStr);
+ else
+ decl->text = bodyStr;
+
+ return "";
+}
+
+ZResourceType ZTextureAnimationParams::GetResourceType() const
+{
+ return ZResourceType::TextureAnimationParams;
+}
+
+/* TextureScrollingParams */
+
+void TextureScrollingParams::ParseRawData()
+{
+ const auto& rawData = parent->GetRawData();
+
+ for (int i = 0; i < count; i++)
+ {
+ rows[i].xStep = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4 * i);
+ rows[i].yStep = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4 * i + 1);
+ rows[i].width = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4 * i + 2);
+ rows[i].height = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4 * i + 3);
+ }
+}
+
+void TextureScrollingParams::ExtractFromBinary(uint32_t nRawDataIndex, int nCount)
+{
+ rawDataIndex = nRawDataIndex;
+ count = nCount;
+
+ ParseRawData();
+}
+
+std::string TextureScrollingParams::GetSourceTypeName() const
+{
+ return "AnimatedMatTexScrollParams"; // TODO: Better name
+}
+
+std::string TextureScrollingParams::GetDefaultName(const std::string& prefix) const
+{
+ return StringHelper::Sprintf("%sTexScrollParams_%06X", prefix.c_str(), rawDataIndex);
+}
+
+size_t TextureScrollingParams::GetRawDataSize() const
+{
+ return 4 * count;
+}
+
+/**
+ * Overrides the parent version to declare an array of the params rather than just one entry.
+ */
+void TextureScrollingParams::DeclareVar(const std::string& prefix, const std::string& bodyStr) const
+{
+ std::string auxName = name;
+
+ if (name == "")
+ auxName = GetDefaultName(prefix);
+
+ parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(),
+ GetSourceTypeName(), auxName, count, bodyStr);
+}
+
+std::string TextureScrollingParams::GetBodySourceCode() const
+{
+ std::string bodyStr = "";
+
+ for (int i = 0; i < count; i++)
+ {
+ bodyStr += StringHelper::Sprintf(" { %d, %d, 0x%02X, 0x%02X },\n", rows[i].xStep,
+ rows[i].yStep, rows[i].width, rows[i].height);
+ }
+
+ bodyStr.pop_back();
+
+ return bodyStr;
+}
+
+/* TextureColorChangingParams */
+
+/**
+ * Also parses the color and frameData arrays
+ */
+void TextureColorChangingParams::ParseRawData()
+{
+ const auto& rawData = parent->GetRawData();
+
+ animLength = BitConverter::ToUInt16BE(rawData, rawDataIndex);
+ colorListCount = BitConverter::ToUInt16BE(rawData, rawDataIndex + 2);
+
+ // Handle type 2 separately
+ uint16_t listLength =
+ ((type == TextureAnimationParamsType::ColorChange) ? animLength : colorListCount);
+
+ if (listLength == 0)
+ throw std::runtime_error(StringHelper::Sprintf(
+ "When processing file %s: in input binary file %s, offset 0x%06X:"
+ "\n\t"
+ "\033[97m"
+ "TextureColorChangingParams::ParseRawData:"
+ "\033[0m"
+ "\033[91m"
+ " error: "
+ "\033[0m"
+ "\033[97m"
+ "color list length cannot be 0\n"
+ "\033[0m",
+ Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex));
+
+ primColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
+ envColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
+ frameDataListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0xC);
+
+ uint32_t primColorListOffset = Seg2Filespace(primColorListAddress, parent->baseAddress);
+ uint32_t envColorListOffset = Seg2Filespace(envColorListAddress, parent->baseAddress);
+ uint32_t frameDataListOffset = Seg2Filespace(frameDataListAddress, parent->baseAddress);
+
+ uint32_t currentPtr;
+
+ F3DPrimColor currentPrimColor;
+
+ for (currentPtr = primColorListOffset; currentPtr < primColorListOffset + 5 * listLength;
+ currentPtr += 5)
+ {
+ currentPrimColor = {BitConverter::ToUInt8BE(rawData, currentPtr),
+ BitConverter::ToUInt8BE(rawData, currentPtr + 1),
+ BitConverter::ToUInt8BE(rawData, currentPtr + 2),
+ BitConverter::ToUInt8BE(rawData, currentPtr + 3),
+ BitConverter::ToUInt8BE(rawData, currentPtr + 4)};
+ primColorList.push_back(currentPrimColor);
+ }
+
+ F3DEnvColor currentEnvColor;
+
+ for (currentPtr = envColorListOffset; currentPtr < envColorListOffset + 4 * listLength;
+ currentPtr += 4)
+ {
+ currentEnvColor = {BitConverter::ToUInt8BE(rawData, currentPtr),
+ BitConverter::ToUInt8BE(rawData, currentPtr + 1),
+ BitConverter::ToUInt8BE(rawData, currentPtr + 2),
+ BitConverter::ToUInt8BE(rawData, currentPtr + 3)};
+ envColorList.push_back(currentEnvColor);
+ }
+
+ uint16_t currentFrameData;
+
+ for (currentPtr = frameDataListOffset; currentPtr < frameDataListOffset + 2 * listLength;
+ currentPtr += 2)
+ {
+ currentFrameData = BitConverter::ToUInt16BE(rawData, currentPtr);
+ frameDataList.push_back(currentFrameData);
+ }
+}
+
+std::string TextureColorChangingParams::GetSourceTypeName() const
+{
+ return "AnimatedMatColorParams"; // TODO: Better name
+}
+
+std::string TextureColorChangingParams::GetDefaultName(const std::string& prefix) const
+{
+ return StringHelper::Sprintf("%sColorParams_%06X", prefix.c_str(), rawDataIndex);
+}
+
+size_t TextureColorChangingParams::GetRawDataSize() const
+{
+ return 0x10;
+}
+
+void TextureColorChangingParams::DeclareReferences([[maybe_unused]] const std::string& prefix)
+{
+ if (primColorListAddress != 0) // NULL
+ {
+ std::string primColorBodyStr = "";
+
+ for (const auto& color : primColorList)
+ {
+ primColorBodyStr += StringHelper::Sprintf(" { %d, %d, %d, %d, %d },\n", color.r,
+ color.g, color.b, color.a, color.lodFrac);
+ }
+
+ primColorBodyStr.pop_back();
+
+ parent->AddDeclarationArray(
+ Seg2Filespace(primColorListAddress, parent->baseAddress), DeclarationAlignment::Align4,
+ primColorList.size() * 5, "F3DPrimColor",
+ StringHelper::Sprintf("%sTexColorChangingPrimColors_%06X", parent->GetName().c_str(),
+ Seg2Filespace(primColorListAddress, parent->baseAddress)),
+ primColorList.size(), primColorBodyStr);
+ }
+
+ if (envColorListAddress != 0) // NULL
+ {
+ std::string envColorBodyStr = "";
+
+ for (const auto& color : envColorList)
+ {
+ envColorBodyStr += StringHelper::Sprintf(" { %d, %d, %d, %d },\n", color.r, color.g,
+ color.b, color.a);
+ }
+
+ envColorBodyStr.pop_back();
+
+ parent->AddDeclarationArray(
+ Seg2Filespace(envColorListAddress, parent->baseAddress), DeclarationAlignment::Align4,
+ envColorList.size() * 4, "F3DEnvColor",
+ StringHelper::Sprintf("%sTexColorChangingEnvColors_%06X", parent->GetName().c_str(),
+ Seg2Filespace(envColorListAddress, parent->baseAddress)),
+ envColorList.size(), envColorBodyStr);
+ }
+
+ if (frameDataListAddress != 0) // NULL
+ {
+ std::string frameDataBodyStr = " ";
+
+ for (const auto& frame : frameDataList)
+ {
+ frameDataBodyStr += StringHelper::Sprintf("%d, ", frame);
+ }
+
+ frameDataBodyStr.pop_back();
+
+ parent->AddDeclarationArray(
+ Seg2Filespace(frameDataListAddress, parent->baseAddress), DeclarationAlignment::Align4,
+ frameDataList.size() * 2, "u16",
+ StringHelper::Sprintf("%sTexColorChangingFrameData_%06X", parent->GetName().c_str(),
+ Seg2Filespace(frameDataListAddress, parent->baseAddress)),
+ frameDataList.size(), frameDataBodyStr);
+ }
+}
+
+std::string TextureColorChangingParams::GetBodySourceCode() const
+{
+ std::string bodyStr =
+ StringHelper::Sprintf("\n %d, %d, %s, %s, %s,\n", animLength, colorListCount,
+ parent->GetDeclarationPtrName(primColorListAddress).c_str(),
+ parent->GetDeclarationPtrName(envColorListAddress).c_str(),
+ parent->GetDeclarationPtrName(frameDataListAddress).c_str());
+
+ return bodyStr;
+}
+
+/* TextureCyclingParams */
+
+void TextureCyclingParams::ParseRawData()
+{
+ const auto& rawData = parent->GetRawData();
+
+ cycleLength = BitConverter::ToUInt16BE(rawData, rawDataIndex);
+ if (cycleLength == 0)
+ throw std::runtime_error(
+ StringHelper::Sprintf("When processing file %s: in input binary file %s, offset 0x%06X:"
+ "\n\t"
+ "\033[97m"
+ "TextureCyclingParams::ParseRawData:"
+ "\033[0m"
+ "\033[91m"
+ " error: "
+ "\033[0m"
+ "\033[97m"
+ "cycleLength cannot be 0\n"
+ "\033[0m",
+ Globals::Instance->inputPath.c_str(), parent->GetName().c_str(),
+ Seg2Filespace(rawDataIndex, 0)));
+
+ textureListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4);
+ textureIndexListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8);
+
+ uint32_t textureListOffset = Seg2Filespace(textureListAddress, parent->baseAddress);
+ uint32_t textureIndexListOffset = Seg2Filespace(textureIndexListAddress, parent->baseAddress);
+
+ uint32_t currentPtr;
+
+ uint8_t currentIndex;
+ uint8_t maxIndex = 0; // To find the length of the texture list
+
+ for (currentPtr = textureIndexListOffset; currentPtr < textureIndexListOffset + cycleLength;
+ currentPtr++)
+ {
+ currentIndex = BitConverter::ToUInt8BE(rawData, currentPtr);
+ textureIndexList.push_back(currentIndex);
+ if (currentIndex > maxIndex)
+ maxIndex = currentIndex;
+ }
+
+ for (currentPtr = textureListOffset; currentPtr <= textureListOffset + 4 * maxIndex;
+ currentPtr += 4)
+ {
+ textureList.push_back(BitConverter::ToUInt32BE(rawData, currentPtr));
+ }
+}
+
+std::string TextureCyclingParams::GetSourceTypeName() const
+{
+ return "AnimatedMatTexCycleParams"; // TODO: Better name
+}
+
+std::string TextureCyclingParams::GetDefaultName(const std::string& prefix) const
+{
+ return StringHelper::Sprintf("%sTexCycleParams_%06X", prefix.c_str(), rawDataIndex);
+}
+
+size_t TextureCyclingParams::GetRawDataSize() const
+{
+ return 0xC;
+}
+
+void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& prefix)
+{
+ if (textureListAddress != 0) // NULL
+ {
+ std::string texturesBodyStr = "";
+ std::string texName;
+ std::string comment = "";
+
+ for (const auto& tex : textureList)
+ {
+ texName = parent->GetDeclarationPtrName(tex);
+
+ // texName is a raw segmented pointer. This occurs if the texture is not declared
+ // separately since we cannot read the format. In theory we could scan DLists for the
+ // format on the appropriate segments.
+ if (texName.length() == 10 && texName.substr(0, 2) == "0x")
+ {
+ comment = " // Raw pointer, declare texture in XML to use proper symbol";
+
+ fprintf(stderr,
+ "When processing file %s: in input binary file %s, offset 0x%06X:"
+ "\n\t"
+ "\033[97m"
+ "TextureCyclingParams::DeclareReferences:"
+ "\033[0m"
+ "\033[95m"
+ " warning: "
+ "\033[0m"
+ "\033[97m"
+ "TexCycle declared here points to unknown texture at address %s. "
+ "Please declare the texture in the XML to use the proper symbol.\n"
+ "\033[0m",
+ Globals::Instance->inputPath.c_str(), parent->GetName().c_str(),
+ Seg2Filespace(textureListAddress, parent->baseAddress), texName.c_str());
+ }
+ texturesBodyStr +=
+ StringHelper::Sprintf(" %s,%s\n", texName.c_str(), comment.c_str());
+ }
+
+ texturesBodyStr.pop_back();
+
+ parent->AddDeclarationArray(
+ Seg2Filespace(textureListAddress, parent->baseAddress), DeclarationAlignment::Align4,
+ textureList.size() * 4, "TexturePtr",
+ StringHelper::Sprintf("%sTexCycleTexPtrs_%06X", parent->GetName().c_str(),
+ Seg2Filespace(textureListAddress, parent->baseAddress)),
+ textureList.size(), texturesBodyStr);
+ }
+
+ if (textureIndexListAddress != 0) // NULL
+ {
+ std::string indicesBodyStr = " ";
+
+ for (uint8_t index : textureIndexList)
+ {
+ indicesBodyStr += StringHelper::Sprintf("%d, ", index);
+ }
+
+ indicesBodyStr.pop_back();
+
+ parent->AddDeclarationArray(
+ Seg2Filespace(textureIndexListAddress, parent->baseAddress),
+ DeclarationAlignment::Align4, textureIndexList.size(), "u8",
+ StringHelper::Sprintf("%sTexCycleTexIndices_%06X", parent->GetName().c_str(),
+ Seg2Filespace(textureIndexListAddress, parent->baseAddress)),
+ textureIndexList.size(), indicesBodyStr);
+ }
+}
+
+std::string TextureCyclingParams::GetBodySourceCode() const
+{
+ std::string bodyStr =
+ StringHelper::Sprintf("\n %d, %s, %s,\n", cycleLength,
+ parent->GetDeclarationPtrName(textureListAddress).c_str(),
+ parent->GetDeclarationPtrName(textureIndexListAddress).c_str());
+
+ return bodyStr;
+}
+
+/* ZTextureAnimation */
+
+ZTextureAnimation::ZTextureAnimation(ZFile* nParent) : ZResource(nParent)
+{
+}
+
+void ZTextureAnimation::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDataIndex)
+{
+ ZResource::ExtractFromXML(reader, nRawDataIndex);
+ DeclareVar("", "");
+}
+
+/**
+ * Builds the array of params
+ */
+void ZTextureAnimation::ParseRawData()
+{
+ ZResource::ParseRawData();
+
+ TextureAnimationEntry currentEntry;
+ auto rawData = parent->GetRawData();
+ int16_t type;
+
+ for (uint32_t currentPtr = rawDataIndex;; currentPtr += 8)
+ {
+ type = BitConverter::ToInt16BE(rawData, currentPtr + 2);
+
+ currentEntry.segment = BitConverter::ToInt8BE(rawData, currentPtr);
+ currentEntry.type = (TextureAnimationParamsType)type;
+ currentEntry.paramsPtr = BitConverter::ToUInt32BE(rawData, currentPtr + 4);
+ entries.push_back(currentEntry);
+
+ if ((type < 0) || (type > 6))
+ {
+ throw std::runtime_error(StringHelper::Sprintf(
+ "When processing file %s: in input binary file %s, offset 0x%06X:"
+ "\n\t"
+ "\033[97m"
+ "ZTextureAnimation::ParseRawData:"
+ "\033[0m"
+ "\033[91m"
+ " error: "
+ "\033[0m"
+ "\033[97m"
+ "unknown TextureAnimationParams type 0x%02X in TextureAnimation: entry reads\n\t{ "
+ "0x%02X, 0x%02X, 0x%08X }\n(type should be between "
+ "0x00 and 0x06)\n"
+ "\033[0m",
+ Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex, type,
+ currentEntry.segment, type, currentEntry.paramsPtr));
+ }
+
+ if (currentEntry.segment <= 0)
+ break;
+ }
+}
+
+#include <optional>
+/**
+ * For each params entry,
+ */
+void ZTextureAnimation::DeclareReferences(const std::string& prefix)
+{
+ std::string varPrefix = name;
+ if (varPrefix == "")
+ varPrefix = prefix;
+
+ ZResource::DeclareReferences(varPrefix);
+
+ for (const auto& entry : entries)
+ {
+ if (entry.paramsPtr != 0 && GETSEGNUM(entry.paramsPtr) == parent->segment)
+ {
+ uint32_t paramsOffset = Seg2Filespace(entry.paramsPtr, parent->baseAddress);
+ if (!parent->HasDeclaration(paramsOffset))
+ {
+ ZTextureAnimationParams* params;
+ int count = 2;
+ switch (entry.type)
+ {
+ case TextureAnimationParamsType::SingleScroll:
+ count = 1;
+ [[fallthrough]];
+ case TextureAnimationParamsType::DualScroll:
+ params = new TextureScrollingParams(parent);
+ params->ExtractFromBinary(paramsOffset, count);
+ break;
+
+ case TextureAnimationParamsType::ColorChange:
+ case TextureAnimationParamsType::ColorChangeLERP:
+ case TextureAnimationParamsType::ColorChangeLagrange:
+ params = new TextureColorChangingParams(parent);
+ params->type = entry.type;
+ params->ExtractFromBinary(paramsOffset);
+ break;
+
+ case TextureAnimationParamsType::TextureCycle:
+ params = new TextureCyclingParams(parent);
+ params->ExtractFromBinary(paramsOffset);
+ break;
+
+ case TextureAnimationParamsType::Empty:
+ fprintf(stderr,
+ "When processing file %s: in input binary file %s: offset 0x%06X:"
+ "\n\t"
+ "\033[97m"
+ "ZTextureAnimation::DeclareReferences:"
+ "\033[0m"
+ "\033[95m"
+ " warning: "
+ "\033[0m"
+ "\033[97m"
+ "TextureAnimationParams entry has empty type (6), but params pointer "
+ "is not NULL. Params read\n\t\t"
+ "{ 0x%02X, 0x%02X, 0x%08X }\n"
+ "\033[0m",
+ Globals::Instance->inputPath.c_str(), parent->GetName().c_str(),
+ rawDataIndex, entry.segment, (int)entry.type, entry.paramsPtr);
+ return;
+ default:
+ // Because GCC is worried this could happen
+ assert(entry.type < TextureAnimationParamsType::SingleScroll ||
+ entry.type > TextureAnimationParamsType::Empty);
+ return;
+ }
+
+ params->SetName(params->GetDefaultName(varPrefix));
+ params->DeclareVar(varPrefix, "");
+ parent->AddResource(params);
+ }
+ }
+ }
+}
+
+std::string ZTextureAnimation::GetSourceTypeName() const
+{
+ return "AnimatedMaterial"; // TODO: Better name
+}
+
+ZResourceType ZTextureAnimation::GetResourceType() const
+{
+ return ZResourceType::TextureAnimation;
+}
+
+/**
+ * The size of the main array
+ */
+size_t ZTextureAnimation::GetRawDataSize() const
+{
+ return entries.size() * 8;
+}
+
+std::string ZTextureAnimation::GetDefaultName(const std::string& prefix) const
+{
+ return StringHelper::Sprintf("%sTexAnim_%06X", prefix.c_str(), rawDataIndex);
+}
+
+void ZTextureAnimation::DeclareVar(const std::string& prefix, const std::string& bodyStr) const
+{
+ std::string auxName = name;
+
+ if (name == "")
+ auxName = GetDefaultName(prefix);
+
+ parent->AddDeclarationArray(rawDataIndex, DeclarationAlignment::Align4, GetRawDataSize(),
+ GetSourceTypeName(), auxName, entries.size(), bodyStr);
+}
+
+std::string ZTextureAnimation::GetBodySourceCode() const
+{
+ std::string bodyStr = "";
+
+ for (const auto& entry : entries)
+ {
+ bodyStr += StringHelper::Sprintf(" { %d, %d, %s },\n", entry.segment, entry.type,
+ parent->GetDeclarationPtrName(entry.paramsPtr).c_str());
+ }
+
+ bodyStr.pop_back();
+
+ return bodyStr;
+}
+
+std::string ZTextureAnimation::GetSourceOutputCode(const std::string& prefix)
+{
+ std::string bodyStr = GetBodySourceCode();
+
+ Declaration* decl = parent->GetDeclaration(rawDataIndex);
+
+ if (decl == nullptr)
+ DeclareVar(prefix, bodyStr);
+ else
+ decl->text = bodyStr;
+
+ return "";
+}