Skip to content

FSC: Sort merged directory listings by name (fixes ZombiU black screen with update v32) - #2048

Open
LuismaSP89 wants to merge 1 commit into
cemu-project:mainfrom
LuismaSP89:fix/fsc-merged-dir-order
Open

FSC: Sort merged directory listings by name (fixes ZombiU black screen with update v32)#2048
LuismaSP89 wants to merge 1 commit into
cemu-project:mainfrom
LuismaSP89:fix/fsc-merged-dir-order

Conversation

@LuismaSP89

@LuismaSP89 LuismaSP89 commented Sep 2, 2026

Copy link
Copy Markdown

Fixes the long-standing "ZombiU doesn't boot with update v32 installed" problem documented on the wiki (and reported in #1823): the game stays on a black screen after the Ubisoft logo, at 30 FPS, forever.

What the game does

At boot ZombiU enumerates /vol/content/lynfsatest/BinCafe with FSReadDir and registers its .lin.bfz archives in the order they are returned. Its boot sequence then loads the intro video by resource id. That resource exists in two archives (Video_Common_1 and a duplicate in Gen_Common), and which copy gets used depends on the archive order.

What goes wrong in Cemu

FSCVirtualFileDirectoryIterator::PopulateIterationList builds the listing of a directory that exists in several mounted layers by iterating the layers in priority order and appending each layer's entries. With an update installed, every file from the update is therefore listed before any file from the base title. The v32 update adds BinCafe/Patch.lin.bfz, which becomes the first archive the game registers and shifts all the others. The boot sequence resolves the intro video to the wrong archive (and starts streaming it from the wrong block), waits out its timeouts and the game never leaves the boot screen. On hardware the directory is returned in FST order, i.e. sorted by name, so Patch.lin.bfz lands between Mip0_Common_1 and SndStream_Common_0 and everything works.

Two experiments showed it is purely the order: removing Patch.lin.bfz from the update makes v32 boot, and so does moving the very same file into the base title's BinCafe folder, where the host filesystem lists it alphabetically.

The fix

Sort the merged listing by name (case-insensitively, like the FSA name comparison) whenever more than one folder contributes to a directory. Listings that come from a single layer are not touched, so games without an update or DLC see exactly what they saw before.

Testing

Confirmed with a build of this branch: ZombiU (EUR) with update v32 installed in its normal location now plays the intro video and reaches the main menu, and the game runs normally from there. Base v0 behaves as before.

When a directory exists in more than one mounted layer (base title plus
update, for example), the virtual directory iterator concatenated the
listings layer by layer, so all of the update's files were returned before
any of the base title's files. On hardware FSReadDir returns entries in FST
order, which is sorted by name.

ZombiU indexes its .bfz archives in the order returned by FSReadDir. With the
v32 update installed, its Patch.lin.bfz was enumerated before Gen_Common and
the other base archives, the boot sequence resolved the intro video to the
wrong archive and the game never got past the black screen after the Ubisoft
logo (see the ZombiU wiki page and cemu-project#1823). Moving Patch.lin.bfz into the base
content folder, where it gets listed alphabetically, makes the game boot, so
the order alone is what breaks it.

Sort the merged listing case-insensitively by name whenever more than one
folder contributes to it. Single-layer listings are left untouched.
@LuismaSP89
LuismaSP89 marked this pull request as draft September 2, 2026 21:25
@LuismaSP89
LuismaSP89 marked this pull request as ready for review September 2, 2026 22:09
@LuismaSP89

Copy link
Copy Markdown
Author

PS: Same as the previous PR, I did this using AI help. And again... In case the devs doesn't want to merge this commit because they don't like AI things, I totally understand. But this fixes a long-standing issue with just 16 lines of code (Not including the comments). So, in case any other person wants to develop a better fix, at least he/she can take this as an example or reference.

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.

1 participant