Skip to content

Commit e802bd0

Browse files
committed
Support for "always on" mods when no alt/
1 parent 0491c21 commit e802bd0

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed

soh/soh/ResourceManagerHelpers.cpp

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -518,33 +518,39 @@ extern "C" int ResourceMgr_OTRSigCheck(char* imgData) {
518518
}
519519

520520
// Load animation with explicit alt asset path checking.
521-
// This ensures animations are loaded with the correct alt/ prefix when alt assets are enabled,
522-
// matching the behavior of skeleton loading and preventing cached vanilla animations from
523-
// overriding alternate animations when toggling.
521+
// When Alt Assets is OFF: use original path directly (O2R or vanilla)
522+
// When Alt Assets is ON: try alt/ prefix first, fall back to regular path if not found
524523
extern "C" AnimationHeaderCommon* ResourceMgr_LoadAnimByName(const char* path) {
525-
std::string pathStr = std::string(path);
526-
static const std::string sOtr = "__OTR__";
527-
528-
// Strip the OTR signature prefix if present
529-
if (pathStr.starts_with(sOtr)) {
530-
pathStr = pathStr.substr(sOtr.length());
531-
}
532-
533524
bool isAlt = ResourceMgr_IsAltAssetsEnabled();
534525

535-
// Explicitly add alt prefix when alternate assets are enabled
536526
if (isAlt) {
537-
pathStr = Ship::IResource::gAltAssetPrefix + pathStr;
538-
}
527+
std::string pathStr = std::string(path);
528+
static const std::string sOtr = "__OTR__";
529+
530+
if (pathStr.starts_with(sOtr)) {
531+
pathStr = pathStr.substr(sOtr.length());
532+
}
539533

540-
AnimationHeaderCommon* animHeader = (AnimationHeaderCommon*)ResourceGetDataByName(pathStr.c_str());
534+
// Try alt/ first
535+
pathStr = Ship::IResource::gAltAssetPrefix + pathStr;
536+
AnimationHeaderCommon* animHeader = (AnimationHeaderCommon*)ResourceGetDataByName(pathStr.c_str());
537+
538+
// If alt loaded successfully and has valid frame data, return it
539+
if (animHeader != NULL) {
540+
// Check if it's a Link animation and has valid segment data
541+
LinkAnimationHeader* linkAnim = (LinkAnimationHeader*)animHeader;
542+
if (linkAnim->segment != NULL) {
543+
return animHeader;
544+
}
545+
// Alt loaded but segment is null (broken), fall through to original path
546+
}
541547

542-
// If there isn't an alternate animation, fall back to the regular one
543-
if (isAlt && animHeader == NULL) {
544-
animHeader = (AnimationHeaderCommon*)ResourceGetDataByName(path);
548+
// Fall back to original path
549+
return (AnimationHeaderCommon*)ResourceGetDataByName(path);
545550
}
546551

547-
return animHeader;
552+
// Alt OFF: use original path directly
553+
return (AnimationHeaderCommon*)ResourceGetDataByName(path);
548554
}
549555

550556
extern "C" SkeletonHeader* ResourceMgr_LoadSkeletonByName(const char* path, SkelAnime* skelAnime) {

soh/soh/resource/importer/AnimationFactory.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,15 +78,33 @@ ResourceFactoryBinaryAnimationV0::ReadResource(std::shared_ptr<Ship::File> file,
7878
}
7979
animation->animationData.transformUpdateIndex.copyValues = animation->copyValuesArr.data();
8080
} else if (animType == AnimationType::Link) {
81+
// Initialize segment to nullptr (important for alt asset fallback)
82+
animation->animationData.linkAnimationHeader.segment = nullptr;
83+
8184
// Read the frame count
8285
animation->animationData.linkAnimationHeader.common.frameCount = reader->ReadInt16();
8386

8487
// Read the segment pointer (always 32 bit, doesn't adjust for system pointer size)
8588
std::string path = reader->ReadString();
86-
const auto animData = std::static_pointer_cast<Animation>(
89+
auto animData = std::static_pointer_cast<Animation>(
8790
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(path.c_str()));
8891

89-
animation->animationData.linkAnimationHeader.segment = animData->GetPointer();
92+
// If direct load failed and alt assets are enabled, try with alt/ prefix
93+
if (animData == nullptr && Ship::Context::GetInstance()->GetResourceManager()->IsAltAssetsEnabled()) {
94+
std::string altPath = path;
95+
if (altPath.find("__OTR__") == 0) {
96+
altPath = altPath.substr(7); // Strip __OTR__
97+
}
98+
altPath = "alt/" + altPath;
99+
animData = std::static_pointer_cast<Animation>(
100+
Ship::Context::GetInstance()->GetResourceManager()->LoadResourceProcess(altPath.c_str()));
101+
}
102+
103+
if (animData != nullptr) {
104+
animation->animationData.linkAnimationHeader.segment = animData->GetPointer();
105+
} else {
106+
SPDLOG_WARN("Animation data segment not found: {}", path);
107+
}
90108
} else if (animType == AnimationType::Legacy) {
91109
SPDLOG_DEBUG("BEYTAH ANIMATION?!");
92110
}

soh/src/code/z_skelanime.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,10 @@ void AnimationContext_SetLoadFrame(PlayState* play, LinkAnimationHeader* animati
902902
if (frame < 0) {
903903
frame = 0;
904904
}
905+
// SOH [Alt Assets] Check if animData is null (can happen if animation data segment failed to load)
906+
if (animData == NULL) {
907+
return;
908+
}
905909
memcpy(ram, (uintptr_t)animData + (((sizeof(Vec3s) * limbCount + 2) * frame)), sizeof(Vec3s) * limbCount + 2);
906910
}
907911
}

0 commit comments

Comments
 (0)