Repository navigation
lib: preserve MxDSSelectAction list extension through Read/Write - #48
Merged
Merged
Conversation
MxDSSelectAction child lists ('Act_'/'RAND') replace the regular list
count with a null-terminated selector string (e.g. "RANDOM_3"), the
actual count, and one null-terminated value string per child. Read
previously consumed this extension only for the description stream
(assuming single-character values) and Write always emitted a bare
child count, corrupting select actions in rewritten files.
Retain the raw extension bytes on the object and re-emit them verbatim
on write. Verified byte-exact roundtrip of the extension on the four
retail SI files that use it (COPTER.SI, DUNECAR.SI, JETSKI.SI,
RACECAR.SI).
Three defects conspired to corrupt rewritten SI files once object sizes changed from the source file (any replacement shifts every downstream chunk): - Object::CalculateMaximumDiskSize did not account for RIFF odd-size padding of nested chunks, so the pre-MxSt padding projection could undershoot the actual object tree by one byte per odd-sized chunk. - The projection did not include the MxDa LIST header that follows the object tree, so that header could land within the last bytes of a buffer, where both the game and Interleaf::Read skip it (chunks must not straddle buffer boundaries), desyncing the entire parse. - WritePadding silently no-ops for gaps smaller than a pad_ chunk; WritePaddingIfNecessary now fills such gaps with zeroes instead. Also preserve the MxOf object count field through Read/Write instead of rewriting it with the top-level slot count (retail files store the total object count there; e.g. ISLE.SI says 3708 while having 1186 slots).
The runner image's newer CMake resolves the relative root against the app/ subdirectory when find_package(FFMPEG) runs, so configuration fails with the include paths reported under app/. Resolve the path in the workflow instead of relying on version-specific behavior.
Member
Author
|
Regression verification done against retail 1.1 English data and the isle-portable asset pipeline:
One caveat worth knowing: if an object is added to or removed from a file, the preserved MxOf count becomes stale by that delta (previously it was rewritten with the top-level slot count, which was also not the retail semantic). Fresh files with no count read still fall back to the child count. |
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.
MxDSSelectAction child lists ('Act_'/'RAND') replace the regular list count with a null-terminated selector string (e.g. "RANDOM_3"), the actual count, and one null-terminated value string per child. Read previously consumed this extension only for the description stream (assuming single-character values) and Write always emitted a bare child count, corrupting select actions in rewritten files.
This retains the raw extension bytes on the object (
Object::list_extension_) and re-emits them verbatim on write.CalculateMaximumDiskSizeaccounts for the extra bytes.Verified byte-exact roundtrip of the extension on the four retail SI files that use it (COPTER.SI, DUNECAR.SI, JETSKI.SI, RACECAR.SI), and full Read→Write→Read object-tree equality on all 26 retail 1.1 English SI files.