CONTROL Resonant

Hides the window-interior shader D3DMetal draws as flat colours.

GPL-3.0-or-laterThis fix in MacGameFix

What you see

Faces and hair render as black boxes; the lit rooms behind windows show as flat violet, cyan and yellow, spreading to neighbouring windows as the camera moves

Why it happens

Faces: Metal 4 on. Windows: one pixel shader, interiorPS, whose non-uniform texture read D3DMetal runs as uniform, plus a second fault, outside the shaders, that shows up after about a minute of play

What the fix changes

Metal 4 off for this title; the pipelines built with interiorPS are created writing nothing

The code

The pipeline whose pixel shader draws the lit rooms behind windows is created with its colour writes muted, from a copy of the game's description.

fixes/ctl-window-fix.c · my_gfx, lines 138–154
c
static HRESULT WINAPI my_gfx(void *dev, const void *desc, REFIID iid, void **out)
{
    unsigned long long h;
    if (desc && is_hidden(*(void *const *)((const char *)desc + 24), *(const SIZE_T *)((const char *)desc + 32), &h))
    {
        /* sizeof(D3D12_GRAPHICS_PIPELINE_STATE_DESC) on x64: no more is read. */
        char copy[656];
        HRESULT hr;
        memcpy(copy, desc, sizeof(copy));
        mute(copy + 120);
        hr = real_gfx(dev, copy, iid, out);
        InterlockedIncrement(&muted);
        logline("interiorPS %016llx hidden (graphics) -> %08lx", h, (unsigned long)hr);
        return hr;
    }
    return real_gfx(dev, desc, iid, out);
}

Zeroes the write mask of each of the eight render targets in the blend description.

fixes/ctl-window-fix.c · mute, lines 102–106
c
static void mute(char *blend)
{
    int i;
    for (i = 0; i < 8; i++) ((unsigned char *)blend)[8 + i * 40 + 36] = 0;
}

Details

Needs
D3DMetal, D3D12
Installer
install-ctl-fix.sh
Executable
CONTROLResonant.exe
Built from
ctl-window-fix.c
Verified on
Stable 26.3 with Game Porting Toolkit 4.0b2 (2026-09-26)

The full story, with the measurements and the wrong turns