alexbatalov / fallout1-ce

Fallout for modern operating systems
Other
2.1k stars 146 forks source link

Fix pre-rendered cutscene corruption #188

Open dje4321 opened 1 month ago

dje4321 commented 1 month ago

Fixes movie corruption due to a bad return type in getOffset().

Dword_51F018 is a 256 element arry with 16 bit values ranging from 65535 - -65535. Elements 0-127 are all positive 16bit values where as elements 128-255 are all negative 16bit values. getOffset() takes in an unsigned 16bit value, gets the signed representation of the lower 8 bits and adds it to the result of the Dword_51F018[] array after indexing the upper 8 bits of the value

Return type is capped at 16bits incase of an intentional overflow so the offset calculation does not exceed dest ptr of the memcpy() call during the decompression stage of the video.

Not 100% on this fix as I have not fully reversed the decompression function to ensure the behavior of getOffset() and the decompression function are proper in tune with each other. However I have verified that this fixes both the intro cinematic and the vat explosion cutscene near the end of the game.

Credit goes to @Northfear for their vita fork for pointing me in the right direction on where to start with this issue. See commit 00c1269db7d69ae86ee6211a9e8c77548d002b09 on their fallout1-ce-vita fork for their fix. Due to the inconsistancy of the C STD library, I performed further verification of the fix because the bit width of int has no guarntees. This can lead to platform->platform issues as each compiler and triple target could assign int to be whatever bit width most suits it.

dje4321 commented 1 month ago

Attached is a graph of the Dword_51F018 array mapping that gets generated at runtime graph

dje4321 commented 1 month ago

One issue remains that the border surrounding the FMV cutscene is still remains corrupted at times. However, it appears to be an issue with SDL not refreshing the border surrounding the FMV with a new blank background

giuliano-macedo commented 1 month ago

Fixes #194 even if using int16_t, int32_t or int64_t as a return type for getOffset