1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-02-04 02:44:24 +00:00
oot/tools/ZAPD/ZAPD/ZCKeyFrameAnim.cpp
Dragorn421 bdee3d33b4
No longer use asm-processor (#1824)
* git subrepo pull --force tools/ZAPD

subrepo:
  subdir:   "tools/ZAPD"
  merged:   "b3bfa14cf"
upstream:
  origin:   "https://github.com/zeldaret/ZAPD.git"
  branch:   "master"
  commit:   "b3bfa14cf"
git-subrepo:
  version:  "0.4.6"
  origin:   "https://github.com/ingydotnet/git-subrepo"
  commit:   "110b9eb"

* use CS_FLOAT

* update csdis

* update committed csdata

* finish updating csdis.py

* add script to reextract committed csdata

* dont use asm-processor, use iconv for reencoding utf8 to eucjp

* remove asm-processor csdata usage remnants

* --cs-float hex

* delete tempfile at end of reencode.sh (may want to rm even if compilation fails though?)

* comment reencode.sh

* comment CMD_F

* do not break permuter guessing compile command, by not reencode.sh-wrapping compilation under PERMUTER (thanks anghelo)

* fix the permuter fix

* pad -> sBssDummyNeg1

* reencode.sh: rm tempfile on script exit (including on error)

* renumber sBssDummy vars in zcolchk from 0

* Revert "--cs-float hex"

This reverts commit 85267dc348.

* Revert BSS changes

* Add linemarker to reencoded files for better error message

* fix audio/general.c bss

* make reencode.sh work on macOS

* touch up csdis, csdis_re

---------

Co-authored-by: cadmic <cadmic24@gmail.com>
2024-03-01 16:12:22 -05:00

219 lines
No EOL
6.3 KiB
C++

#include "ZCkeyFrameAnim.h"
#include "ZCKeyFrame.h"
#include "Globals.h"
#include "Utils/BitConverter.h"
REGISTER_ZFILENODE(KeyFrameAnimation, ZKeyFrameAnim);
ZKeyFrameAnim::ZKeyFrameAnim(ZFile* nParent) : ZResource(nParent)
{
RegisterRequiredAttribute("Skel");
}
ZKeyFrameAnim::~ZKeyFrameAnim()
{
}
void ZKeyFrameAnim::ParseXML(tinyxml2::XMLElement* reader)
{
ZResource::ParseXML(reader);
std::string skelAddrStr = registeredAttributes.at("Skel").value;
skelOffset = (offset_t)StringHelper::StrToL(skelAddrStr, 16);
}
void ZKeyFrameAnim::DeclareReferencesLate(const std::string& prefix)
{
std::string defaultPrefix = name;
std::string declaration;
if (defaultPrefix == "")
defaultPrefix = prefix;
ZResource::DeclareReferences(defaultPrefix);
declaration += "\t";
if (skel->limbType == ZKeyframeSkelType::Normal)
{
for (const auto b : bitFlags)
{
declaration += StringHelper::Sprintf("0x%02X, ", b);
parent->AddDeclarationArray(
GETSEGOFFSET(bitFlagsAddr), DeclarationAlignment::Align4, bitFlags.size(), "u8",
StringHelper::Sprintf("%s_bitFlags_%06X", prefix.c_str(), rawDataIndex),
bitFlags.size(), declaration);
}
}
else
{
for (const auto b : bitFlagsFlex)
{
declaration += StringHelper::Sprintf("0x%04X, ", b);
parent->AddDeclarationArray(
GETSEGOFFSET(bitFlagsAddr), DeclarationAlignment::Align4, bitFlagsFlex.size() * 2,
"u16", StringHelper::Sprintf("%s_flexBitFlags_%06X", prefix.c_str(), rawDataIndex),
bitFlagsFlex.size(), declaration);
}
}
declaration.clear();
for (const auto kf : keyFrames)
{
declaration +=
StringHelper::Sprintf(" \t { %i, %i, %i, },\n", kf.frame, kf.value, kf.velocity);
}
// Remove last new line to prevent an extra line after the last element
declaration = declaration.substr(0, declaration.length() - 1);
parent->AddDeclarationArray(
GETSEGOFFSET(keyFramesAddr), DeclarationAlignment::Align4, keyFrames.size() * 6, "KeyFrame",
StringHelper::Sprintf("%s_KeyFrame_%06X", prefix.c_str(), rawDataIndex), keyFrames.size(),
declaration);
declaration.clear();
declaration += "\t";
for (const auto kfNum : kfNums)
{
declaration += StringHelper::Sprintf("0x%04X, ", kfNum);
}
parent->AddDeclarationArray(
GETSEGOFFSET(kfNumsAddr), DeclarationAlignment::Align4, kfNums.size() * 2, "s16",
StringHelper::Sprintf("%s_kfNums_%06X", prefix.c_str(), rawDataIndex), kfNums.size(),
declaration);
declaration += "\n";
declaration.clear();
declaration += "\t";
for (const auto pv : presetValues)
{
declaration += StringHelper::Sprintf("0x%04X, ", pv);
}
declaration += "\n";
parent->AddDeclarationArray(
GETSEGOFFSET(presentValuesAddr), DeclarationAlignment::Align4, presetValues.size() * 2,
"s16", StringHelper::Sprintf("%s_presetValues_%06X", prefix.c_str(), rawDataIndex),
presetValues.size(), declaration);
}
// ParseRawDataLate is used because we need to make sure the flex skel has been processed first.
void ZKeyFrameAnim::ParseRawDataLate()
{
const auto& rawData = parent->GetRawData();
skel = static_cast<ZKeyFrameSkel*>(parent->FindResource(skelOffset));
size_t numLimbs = skel->limbCount;
bitFlagsAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x0);
keyFramesAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x4);
kfNumsAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0x8);
presentValuesAddr = BitConverter::ToUInt32BE(rawData, rawDataIndex + 0xC);
uint32_t kfNumsSize = 0;
uint32_t presetValuesSize = 0;
uint32_t keyFramesCount = 0;
if (skel->limbType == ZKeyframeSkelType::Normal)
{
bitFlags.reserve(numLimbs);
for (size_t i = 0; i < numLimbs; i++)
{
uint8_t e = BitConverter::ToUInt8BE(rawData, GETSEGOFFSET(bitFlagsAddr) + i);
bitFlags.push_back(e);
kfNumsSize += GetSetBits((uint8_t)(e & 0b111111));
presetValuesSize += GetSetBits((uint8_t)((e ^ 0xFF) & 0b111111));
}
}
else
{
bitFlagsFlex.reserve(numLimbs);
for (size_t i = 0; i < numLimbs; i++)
{
uint16_t e = BitConverter::ToUInt16BE(rawData, GETSEGOFFSET(bitFlagsAddr) + (i * 2));
bitFlagsFlex.push_back(e);
kfNumsSize += GetSetBits((uint16_t)(e & 0b111111111));
presetValuesSize += GetSetBits((uint16_t)((e ^ 0xFFFF) & 0b111111111));
}
}
kfNums.reserve(kfNumsSize);
for (uint32_t i = 0; i < kfNumsSize; i++)
{
int16_t kfNum = BitConverter::ToUInt16BE(rawData, GETSEGOFFSET(kfNumsAddr) + (i * 2));
keyFramesCount += kfNum;
kfNums.push_back(kfNum);
}
keyFrames.reserve(keyFramesCount);
for (uint32_t i = 0; i < keyFramesCount; i++)
{
KeyFrame kf;
kf.frame = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 0) + (i * 6));
kf.value = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 2) + (i * 6));
kf.velocity = BitConverter::ToInt16BE(rawData, (GETSEGOFFSET(keyFramesAddr) + 4) + (i * 6));
keyFrames.push_back(kf);
}
presetValues.reserve(presetValuesSize);
for (uint32_t i = 0; i < presetValuesSize; i++)
{
presetValues.push_back(
BitConverter::ToInt16BE(rawData, GETSEGOFFSET(presentValuesAddr) + (i * 2)));
}
unk_10 = BitConverter::ToInt16BE(rawData, GETSEGOFFSET(rawDataIndex) + 0x10);
duration = BitConverter::ToInt16BE(rawData, GETSEGOFFSET(rawDataIndex) + 0x12);
}
std::string ZKeyFrameAnim::GetBodySourceCode() const
{
std::string declaration;
std::string bitFlagsStr;
std::string keyFrameStr;
std::string kfNumsStr;
std::string presetValuesStr;
Globals::Instance->GetSegmentedPtrName(bitFlagsAddr, parent, "", bitFlagsStr);
Globals::Instance->GetSegmentedPtrName(keyFramesAddr, parent, "", keyFrameStr);
Globals::Instance->GetSegmentedPtrName(kfNumsAddr, parent, "", kfNumsStr);
Globals::Instance->GetSegmentedPtrName(presentValuesAddr, parent, "", presetValuesStr);
return StringHelper::Sprintf("\n\t%s, %s, %s, %s, 0x%04X, 0x%04X\n", bitFlagsStr.c_str(),
keyFrameStr.c_str(), kfNumsStr.c_str(), presetValuesStr.c_str(),
unk_10, duration);
}
std::string ZKeyFrameAnim::GetSourceTypeName() const
{
return "KeyFrameAnimation";
}
ZResourceType ZKeyFrameAnim::GetResourceType() const
{
return ZResourceType::KeyFrameAnimation;
}
size_t ZKeyFrameAnim::GetRawDataSize() const
{
return 0x14;
}
template <typename T>
uint32_t ZKeyFrameAnim::GetSetBits(T data) const
{
uint32_t num = 0;
for (size_t i = 0; i < sizeof(T) * 8; i++)
{
if ((data >> i) & 1)
num++;
}
return num;
}