mirror of
https://github.com/HarbourMasters/Shipwright
synced 2026-04-23 08:14:31 +00:00
Alt Toggle for Custom animation (#6433)
Add explicit alt prefix checking to animation loading Makes ResourceMgr_LoadAnimByName alt-toggleable this will work for Link and any other animations files
This commit is contained in:
parent
e86e0ff693
commit
262958a2eb
|
|
@ -517,7 +517,47 @@ extern "C" int ResourceMgr_OTRSigCheck(char* imgData) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load animation with explicit alt asset path checking.
|
||||||
|
// When Alt Assets is OFF: use original path directly (O2R or vanilla)
|
||||||
|
// When Alt Assets is ON: try alt/ prefix first, fall back to regular path if not found or invalid
|
||||||
extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) {
|
extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) {
|
||||||
|
bool isAlt = ResourceMgr_IsAltAssetsEnabled();
|
||||||
|
|
||||||
|
if (isAlt) {
|
||||||
|
std::string pathStr = std::string(path);
|
||||||
|
static const std::string sOtr = "__OTR__";
|
||||||
|
|
||||||
|
if (pathStr.starts_with(sOtr)) {
|
||||||
|
pathStr = pathStr.substr(sOtr.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try alt/ first
|
||||||
|
pathStr = Ship::IResource::gAltAssetPrefix + pathStr;
|
||||||
|
AnimationHeaderCommon* animHeader = (AnimationHeaderCommon*)ResourceGetDataByName(pathStr.c_str());
|
||||||
|
|
||||||
|
// If alt loaded successfully, verify it has valid data
|
||||||
|
if (animHeader != NULL) {
|
||||||
|
// Check for valid frame count (> 0)
|
||||||
|
if (animHeader->frameCount > 0) {
|
||||||
|
// For Normal animations: check frameData (comes after frameCount in AnimationHeader)
|
||||||
|
// For Link animations: check segment (comes after frameCount in LinkAnimationHeader)
|
||||||
|
// We check both to be safe - if either is valid, the animation is usable
|
||||||
|
AnimationHeader* normalAnim = (AnimationHeader*)animHeader;
|
||||||
|
LinkAnimationHeader* linkAnim = (LinkAnimationHeader*)animHeader;
|
||||||
|
|
||||||
|
// Valid if Normal animation has frameData OR Link animation has segment
|
||||||
|
if (normalAnim->frameData != NULL || linkAnim->segment != NULL) {
|
||||||
|
return animHeader;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Alt loaded but is invalid (broken), fall through to original path
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fall back to original path
|
||||||
|
return (AnimationHeaderCommon*)ResourceGetDataByName(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alt OFF: use original path directly
|
||||||
return (AnimationHeaderCommon*)ResourceGetDataByName(path);
|
return (AnimationHeaderCommon*)ResourceGetDataByName(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,15 +78,33 @@ ResourceFactoryBinaryAnimationV0::ReadResource(std::shared_ptr<Ship::File> file,
|
||||||
}
|
}
|
||||||
animation->animationData.transformUpdateIndex.copyValues = animation->copyValuesArr.data();
|
animation->animationData.transformUpdateIndex.copyValues = animation->copyValuesArr.data();
|
||||||
} else if (animType == AnimationType::Link) {
|
} else if (animType == AnimationType::Link) {
|
||||||
|
// Initialize segment to nullptr (important for alt asset fallback)
|
||||||
|
animation->animationData.linkAnimationHeader.segment = nullptr;
|
||||||
|
|
||||||
// Read the frame count
|
// Read the frame count
|
||||||
animation->animationData.linkAnimationHeader.common.frameCount = reader->ReadInt16();
|
animation->animationData.linkAnimationHeader.common.frameCount = reader->ReadInt16();
|
||||||
|
|
||||||
// Read the segment pointer (always 32 bit, doesn't adjust for system pointer size)
|
// Read the segment pointer (always 32 bit, doesn't adjust for system pointer size)
|
||||||
std::string path = reader->ReadString();
|
std::string path = reader->ReadString();
|
||||||
const auto animData = std::static_pointer_cast<Animation>(
|
auto animData = std::static_pointer_cast<Animation>(
|
||||||
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(path.c_str()));
|
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(path.c_str()));
|
||||||
|
|
||||||
animation->animationData.linkAnimationHeader.segment = animData->GetPointer();
|
// If direct load failed and alt assets are enabled, try with alt/ prefix
|
||||||
|
if (animData == nullptr && Ship::Context::GetInstance()->GetResourceManager()->IsAltAssetsEnabled()) {
|
||||||
|
std::string altPath = path;
|
||||||
|
if (altPath.find("__OTR__") == 0) {
|
||||||
|
altPath = altPath.substr(7); // Strip __OTR__
|
||||||
|
}
|
||||||
|
altPath = "alt/" + altPath;
|
||||||
|
animData = std::static_pointer_cast<Animation>(
|
||||||
|
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(altPath.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animData != nullptr) {
|
||||||
|
animation->animationData.linkAnimationHeader.segment = animData->GetPointer();
|
||||||
|
} else {
|
||||||
|
SPDLOG_WARN("Animation data segment not found: {}", path);
|
||||||
|
}
|
||||||
} else if (animType == AnimationType::Legacy) {
|
} else if (animType == AnimationType::Legacy) {
|
||||||
SPDLOG_DEBUG("BEYTAH ANIMATION?!");
|
SPDLOG_DEBUG("BEYTAH ANIMATION?!");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -902,6 +902,10 @@ void AnimationContext_SetLoadFrame(PlayState* play, LinkAnimationHeader* animati
|
||||||
if (frame < 0) {
|
if (frame < 0) {
|
||||||
frame = 0;
|
frame = 0;
|
||||||
}
|
}
|
||||||
|
// SOH [Alt Assets] Check if animData is null (can happen if animation data segment failed to load)
|
||||||
|
if (animData == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
memcpy(ram, (uintptr_t)animData + (((sizeof(Vec3s) * limbCount + 2) * frame)), sizeof(Vec3s) * limbCount + 2);
|
memcpy(ram, (uintptr_t)animData + (((sizeof(Vec3s) * limbCount + 2) * frame)), sizeof(Vec3s) * limbCount + 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue