mirror of
https://github.com/zeldaret/botw
synced 2026-06-02 01:59:59 -04:00
ksys/res: Start adding AnimInfo
not going to do parse() for now, it's a major pain
This commit is contained in:
@@ -1 +1,128 @@
|
||||
#include "KingSystem/Resource/resResourceAnimInfo.h"
|
||||
#include "KingSystem/Utils/Byaml/Byaml.h"
|
||||
#include "KingSystem/Utils/SafeDelete.h"
|
||||
|
||||
namespace ksys::res {
|
||||
|
||||
AnimInfo::AnimInfo() : ParamIO("animinfo", 0) {}
|
||||
|
||||
AnimInfo::~AnimInfo() {
|
||||
mAnims.freeBuffer();
|
||||
|
||||
if (mSwordBlurInfo) {
|
||||
mSwordBlurInfo->finalize();
|
||||
util::safeDelete(mSwordBlurInfo);
|
||||
}
|
||||
}
|
||||
|
||||
void AnimInfo::SwordBlurInfo::finalize() {
|
||||
if (!entries)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < num_entries; ++i) {
|
||||
SwordBlur& entry = entries[i];
|
||||
auto* h = heap;
|
||||
if (entry.frames) {
|
||||
h->free(entry.frames);
|
||||
entry.frames = nullptr;
|
||||
}
|
||||
if (entry._18) {
|
||||
h->free(entry._18);
|
||||
entry._18 = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
heap->free(entries);
|
||||
entries = nullptr;
|
||||
}
|
||||
|
||||
void AnimInfo::doCreate_(u8* buffer, u32 buffer_size, sead::Heap* heap) {}
|
||||
|
||||
bool AnimInfo::parse_(u8* data, size_t size, sead::Heap* heap) {
|
||||
al::ByamlIter root_iter{data};
|
||||
|
||||
const int num_entries = root_iter.getSize();
|
||||
int num_anims = num_entries - 1;
|
||||
if (num_entries < 1)
|
||||
return true;
|
||||
|
||||
al::ByamlIter iter;
|
||||
int double_attack_anm_num = 0;
|
||||
int num = 0;
|
||||
bool allocate_anims = false;
|
||||
if (root_iter.isExistKey("_sword_blur")) {
|
||||
iter = root_iter.getIterByKey("_sword_blur");
|
||||
const int num_sword_blurs = iter.getSize();
|
||||
iter.tryGetIntByKey(&double_attack_anm_num, "double_attack_anm_num");
|
||||
num = num_sword_blurs - 1;
|
||||
if (num_entries > 1)
|
||||
allocate_anims = true;
|
||||
} else {
|
||||
num = 0;
|
||||
num_anims = num_entries;
|
||||
allocate_anims = true;
|
||||
}
|
||||
|
||||
if (allocate_anims) {
|
||||
if (!mAnims.tryAllocBuffer(num_anims, heap))
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < num_anims; ++i) {
|
||||
auto& anim = mAnims[i];
|
||||
anim.scale.e.fill(0.0);
|
||||
|
||||
al::ByamlIter entry_iter;
|
||||
if (root_iter.tryGetIterByIndex(&entry_iter, i)) {
|
||||
const char* name_c;
|
||||
if (root_iter.getKeyName(&name_c, i)) {
|
||||
if (std::strcmp(name_c, "_sword_blur") == 0)
|
||||
continue;
|
||||
anim.name = name_c;
|
||||
} else {
|
||||
anim.name = "";
|
||||
}
|
||||
entry_iter.tryGetFloatByKey(&anim.scale.x, "scaleX");
|
||||
entry_iter.tryGetFloatByKey(&anim.scale.y, "scaleY");
|
||||
entry_iter.tryGetFloatByKey(&anim.scale.z, "scaleZ");
|
||||
} else {
|
||||
anim.name = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num >= 1) {
|
||||
if (!mSwordBlurInfo) {
|
||||
auto* info = new (heap) SwordBlurInfo;
|
||||
info->entries = nullptr;
|
||||
mSwordBlurInfo = info;
|
||||
info->heap = heap;
|
||||
info->num_entries = double_attack_anm_num;
|
||||
/// @bug SwordBlur is not trivially constructible and not trivially copyable.
|
||||
/// The only reason using SwordBlur::name doesn't crash is that Clang and GHS
|
||||
/// are smart enough to devirtualize sead::SafeString virtual function calls,
|
||||
/// which removes the need to go through the vtable.
|
||||
info->entries = static_cast<SwordBlur*>(
|
||||
heap->tryAlloc(sizeof(SwordBlur) * info->num_entries, alignof(SwordBlur)));
|
||||
std::memset(info->entries, 0, sizeof(SwordBlur) * info->num_entries);
|
||||
}
|
||||
|
||||
// TODO / FIXME: finish this
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const AnimInfo::Anim* AnimInfo::getAnim(const sead::SafeString& name) const {
|
||||
const auto idx = findAnimIndex(name);
|
||||
if (idx < 0)
|
||||
return nullptr;
|
||||
return &mAnims[idx];
|
||||
}
|
||||
|
||||
int AnimInfo::findAnimIndex(const sead::SafeString& name) const {
|
||||
return mAnims.binarySearch(
|
||||
name,
|
||||
+[](const Anim& anim, const sead::SafeString& key) { return anim.name.compare(key); });
|
||||
}
|
||||
|
||||
} // namespace ksys::res
|
||||
|
||||
Reference in New Issue
Block a user