Persona 5 Strikers

Cutscene runs with sound and no picture. Its video is VC-1 with WMA Pro audio, which the fix decodes itself where the engine cannot. Runs on DXMT only.

GPL-3.0-or-laterThis fix in MacGameFix

What you see

Sound plays, the picture never appears

Why it happens

No CrossOver ships a VC-1 decoder, and with one staged the reader still never reads a sample, because the shared D3D9 render target it is given has a null handle.

What the fix changes

The fix's own VC-1 and WMA Pro reader (or a staged VC-1 decoder), then bridge D3D9 to D3D11

The code

Wine's d3d9 answers a shared render target with S_OK and a null handle; where it leaves that hole, the bridge hands the game a real shared handle.

fixes/p5s-video-bridge.c ยท my_CreateRenderTarget, lines 1437โ€“1466
c
static HRESULT WINAPI my_CreateRenderTarget(void *self, UINT w, UINT h, DWORD fmt,
                                            DWORD ms, DWORD msq, BOOL lockable,
                                            void **surface, HANDLE *shared)
{
    HRESULT hr = real_CreateRenderTarget(self, w, h, fmt, ms, msq, lockable, surface, shared);
    note_shared("CreateRenderTarget", w, h, fmt, hr, shared);
    /* Only where Wine left a hole: it succeeded and shared nothing. */
    if (SUCCEEDED(hr) && shared && !*shared && make_sidecar(w, h))
    {
        static LONG said;
        *shared = sidecar_handle;
        sidecar_w = w; sidecar_h = h;
        if (surface && *surface)
        {
            static void *su;
            void **vt;
            shared_surface = *surface;
            vt = *(void ***)shared_surface;
            real_SurfUnlock = (HRESULT (WINAPI *)(void *))vt[SLOT_SURF_UNLOCKRECT];
            if (!watch_write_path || !patch_slot("surface UnlockRect", shared_surface,
                    SLOT_SURF_UNLOCKRECT, (void *)my_SurfUnlock, &su))
                real_SurfUnlock = NULL;
        }
        if (InterlockedIncrement(&said) == 1)
            logf_("  handed the game a real shared handle %p instead of null -- "
                  "nothing copies into it yet; this only asks whether the game "
                  "then carries on", sidecar_handle);
    }
    return hr;
}

Thanks to

  • winevideoIndependent confirmation of the shared-texture cutscene path, which winevideo repairs inside a patched Wine d3d9.dll.

Details

Needs
DXMT only. D3DMetal cannot produce a shared handle at all
Installer
install-p5s-bridge.sh
Executable
game.exe
Built from
p5s-video-bridge.c, asf-reader.c, wmv-dmo.c, wm-reader.c, dshow-graph.c
Verified on
Plays on stable 26.3 with the codec staged, and on CrossOver Preview 27 through NotProton with nothing staged (2026-10-14)

The full story, with the measurements and the wrong turns