Repository navigation
NANCY: Fix chroma-keyed Bink videos not being keyed - #7823
Conversation
|
Thanks for your work! Interesting issue... that video definitely worked, and after checking the game files, this video exists as both an AVF and a Bink file. Given the above, I think that the issue has been caused by a recent commit, where we prefer Bink videos over AVF ones, if both exist. This was done in commit a72a80d , so could you try swapping the two if branches for AVF and Bink, to check if that fixes the issue? Unfortunately, I can't verify the above right now, as I'm on vacation. |
BinkDecoder decodes YUV into Codec::getDefaultYUVFormat(), which is the screen format, while nancy's surfaces and the transparent colour taken from the BSUM chunk use the engine's input format. Those differ before Nancy13 - screen RGB565 against input RGB555 - and frames are copied with copyToManaged(), which does not convert, so full green was stored as 0x07E0 while the engine keyed on 0x03E0 and the key never matched. From Nancy13 both formats are BGRA32, so nothing changes there. Ask the decoder for the engine's input format instead, after loadFile() since setOutputPixelFormat() only reaches tracks that already exist. This became visible in Nancy11 after a72a80d started preferring Bink over AVF, since the AVF decoder already decodes into the input format. Fixes Nigel_Fidget.bik rendering as a green rectangle in the library, and BLU_FoodCU_OVL, a keyed overlay used in 14 scenes that has no AVF version at all.
ae52dfc to
c6e3566
Compare
|
Thanks for the pointer, that was really helpful. I tried swapping the two branches and it does fix Two things left me unsure whether the swap is the right fix, though I may be missing context. For now I've left the pixel format change in since it covers both, but I'd be glad to switch to the No rush at all, this can easily wait until you're back. Enjoy the rest of your holiday! |
|
After reviewing this, the changes here are definitely a cleaner way of what I've done in 3fe1886, so this PR can be merged. I'll probably revert my changes above, after testing a bit more. Thanks for your work! |
|
Thanks for sorting this out. Two things I got wrong. The I rebuilt master and checked the library scene. Nigel looks fine, no green rectangle. |



Chroma-keyed Bink videos in the nancy engine are never keyed: their key colour is
drawn fully opaque. In Nancy Drew 11: Curse of Blackmoor Manor, Nigel's ambient loop
in the library (
CDVideo/Nigel_Fidget.bik) renders as a solid green rectangle withthe character composited on top.
The cause is a pixel format mismatch.
Video::BinkDecoderdecodes to RGB565, whilenancy's surfaces and the transparent colour derived from the BSUM chunk use the
engine's input pixel format, which is RGB555 (
_inputPixelFormat16) for games beforeNancy13. Frames reach the surface through
GraphicsManager::copyToManaged(), which isa
memcpyand performs no conversion, so full green is stored as0x07E0while theengine keys on
0x03E0.ManagedSurfacekeys on an exact match, so nothing is keyed.BinkDecoderalready implementssetOutputPixelFormat(), butMoviePlayer::loadFile()never called it. This asks the decoder for the engine's own input format instead.
Verified with temporary instrumentation in
PlaySecondaryVideo::init():Tested on nancy11 (English Windows retail,
ciftree.datmd53c406d4f391b6536982c6081f2dd1f4e, 55960641 bytes) in a--disable-all-engines --enable-engine=nancybuild on macOS/arm64. The greenbackground is gone and the video composites correctly.
Scanning the first-frame corner pixel of all 907
.bikfiles inCDVideo/andHDVideo/found exactly one chroma-keyed video in this game, which is probably whythis went unnoticed. Other game types are unaffected in practice: the call is a no-op
whenever the requested format already matches what the decoder produces.
One follow-up that this patch deliberately does not address: because Bink is lossy,
pixels along the subject's silhouette are blends of the key colour and the subject and
do not exactly equal the key, so a thin green fringe remains once the background is
correctly keyed. That needs tolerance somewhere in the keying path rather than a
format fix, and the right design is your call. I have a local workaround that snaps a
greenish pixel to the key colour only when it directly touches an already-keyed pixel,
confining erosion to the boundary; happy to submit it separately if that approach is
wanted.