diff options
| author | EllipticEllipsis <73679967+EllipticEllipsis@users.noreply.github.com> | 2021-09-13 18:19:34 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-09-13 13:19:34 -0400 |
| commit | 3c00dcb30f33b763e215aebfa8ebdf96a8c3ee4d (patch) | |
| tree | c397a7442330e580a827854f1421e8ce97a8dbdb /ZAPD/ZTextureAnimation.cpp | |
| parent | 4d051c0fa036d245027a211bc7fd6a4afdce207f (diff) | |
Texture Animation extraction from objects (#180)
* Initial files
* Add resource header, first go at ExtractFromXML
* Now prints plenty to terminal, but not to file
* Main array now declared in file
* Erroring, but need to checkout master to test
* Not erroring any more, hooray
* TextureScrollingParams working, missing pointer
* Scrolling works
* Cycling params should work completely now
* Type 2 works, type 4 crashes
* Fixed iterator bound, works for Type 4 too now
* Correct a couple more EnvColor things
* Add null checks to declarations
* Switch to Seg2Offset, make TextureAnimationEntry an ordinary struct, delete some obsolete functions
* Remove Unknown (throws exception at construction instead)
* Move GetResourceType down
* Begin rewrite of SetAnimatedMaterialList
* Remove old structs in SetAnimatedMaterialList
* Fix infinite loop
* Tested and working for MM, objects and scenes
* Add warnings for undeclared textures (MM OK)
* Make `__PRETTY_FUNCTION__` work on GCC/Clang, at least
* Remove address from GetDefault name, add fancy errors
* Format (also added some extensive documentation last time)
* More formatting
* Fiddle with errors a bit more
* Fix pointer offsets and alignment
* Format, add comment to SetAnimatedMaterialList
* Add to docs
* Review
* Add [[maybe_unused]]
* uint to get rid of warnings
* makefile
* Fix most warnings
* Add default to shut GCC up
* Format
Diffstat (limited to 'ZAPD/ZTextureAnimation.cpp')
| -rw-r--r-- | ZAPD/ZTextureAnimation.cpp | 729 |
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 ""; +} |
