Repository navigation
Port: keep a texture set's animation inside the set's own blocks - #151
Merged
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.