Skip to content

Port: keep a texture set's animation inside the set's own blocks - #151

Merged
Adubbz merged 1 commit into
TheMoonPeople:masterfrom
drkm9743:fix/tex-anime-own-blocks
Oct 24, 2026
Merged

Adubbz merged 1 commit into
TheMoonPeople:masterfrom
drkm9743:fix/tex-anime-own-blocks

Conversation

@drkm9743

Copy link
Copy Markdown
Contributor

Before: in Zelmite Mine (chapter 8), after defeating Metal Flotsam, going into the last room, back out to the dungeon map and into "Dead End 4", the game crashed (SIGSEGV in RestoreAnimatedTextures, from mgCTextureManager::ReloadTexture in CScene::DrawEffect(0x4B)). It reproduces on iOS with the same steps; loading a save near the crash did not, because the bad state comes from the boss fight.

After: the same steps with the same save no longer crash.

Cause: block 0x4B holds the dungeon's fire set (fire_wrk, fire_scr, fire_anm, lightling from dungeon/articles/tex01_N), whose animation has three groups. In the crash, that animation had a fourth group whose list pointed into reused memory. ApplyAnimation (port/src/mg_texture.cpp) resolves a script's SRC_TEX/DEST_TEX by name across every block, which returns the earliest registration of that name, and puts the record in the block of its source picture. In the retail data, the last group (newgrp3) of several jet and fire effects names the bare fire_anm/fire_wrk, which those effects don't define: dungeon/eff_script/e808_mp_jet (Metal Flotsam's "ポルJET"), event/e800/e808/e808_mp_jet, e540_jet, e640_jet1, e616_ozu_moe, e736_nobori_new and the e206 fire effects. Those frames resolve to the dungeon's pictures in block 0x4B, so the group is added to block 0x4B's animation but allocated from the effect's memory. When the effect is released and its memory reused (here, by the dead end's image), the next restore of block 0x4B follows a garbage node. polm (Halloween boss) has the related problem: it defines its own fire_scr/fire_wrk, but the name lookup finds the dungeon's copies first.

How: when a set has pictures of its own, ApplyAnimation looks a script's names up in the set's blocks first, and skips a record whose source or destination picture lies outside them. Retail TexAnime only draws a record whose pictures are in the animated block, so these records never drew anything. A set without pictures (a script for pictures entered earlier) keeps the lookup across every block. ps2/ is unchanged.

Tests: MgTexture.NativeSetScriptsAnimateTheirOwnPicturesOverEarlierPicturesOfTheSameName covers both cases (a set redefining the names, and a set naming pictures it doesn't define, entered from short-lived memory). The other MgTexture.* tests pass except KeysLiveInTex0, which fails the same way on unpatched master depending on test order.

Tested the changes and the crash seems to be gone.

Texture animation scripts named their pictures across every block, so a
retail jet or fire effect naming the dungeon's bare fire_anm/fire_wrk
(Metal Flotsam's e808_mp_jet, the e540/e640/e616/e736/e206 effects), or
polm redefining fire_scr/fire_wrk, added a group allocated from the
effect's memory to the dungeon fire set in block 0x4B. Once that memory
was reused, restoring the block's animation followed a garbage node and
crashed (Zelmite Mine, Dead End 4 after Metal Flotsam).

Look a set's names up in its own blocks first, and skip a record whose
pictures lie outside them. Retail TexAnime never draws such a record.
@Adubbz
Adubbz merged commit 5cf5b61 into TheMoonPeople:master Oct 24, 2026
4 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants