babalae/better-genshin-impact · warning · Exception

BitBlt not supported

Error message

BitBlt not supported

What it means

Intended to throw when the window device context lacks the RC_BITBLT raster capability, meaning the device cannot perform BitBlt operations. CRITICAL BUG: the guard uses bitwise OR `(hdcRasterCaps | 1) == 0` — since `x | 1` always sets bit 0, it can never equal 0, so this condition is unreachable and the exception will never actually fire. The operator should be bitwise AND (`&`).

Source

Thrown at Fischless.GameCapture/BitBlt/BitBltSession.cs:72

        _hWnd = hWnd;

        if (w <= 0 || h <= 0) throw new Exception("Invalid width or height");

        // 这俩仅做标记
        Width = w;
        Height = h;

        lock (_lockObject)
        {
            try
            {
                _hdcSrc = User32.GetDC(_hWnd);
                if (_hdcSrc.IsInvalid) throw new Exception($"Failed to get DC for {_hWnd}");

                var hdcRasterCaps = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.RASTERCAPS);
                if ((hdcRasterCaps | 1) == 0) // RC_BITBLT
                    // 设备不支持 BitBlt
                    throw new Exception("BitBlt not supported");

                var hdcSrcPixel = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.BITSPIXEL);
                // 颜色位数
                if (hdcSrcPixel != 32 && hdcSrcPixel != 24)
                    // 目前只考虑支持24/32位像素格式
                    throw new Exception("BitBlt only support 24 or 32 bit pixel color");

                var hdcSrcPlanes = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.PLANES);
                // 颜色平面数
                if (hdcSrcPlanes > 1)
                    // 意味着色深不是标准色深
                    throw new Exception("BitBlt only support 1 plane");

                var hdcClip = Gdi32.GetDeviceCaps(_hdcSrc, Gdi32.DeviceCap.CLIPCAPS);
                if (hdcClip == 0)
                    // 设备不支持剪切出单一窗口
                    throw new Exception("Device does not support clipping");

View on GitHub (pinned to a7cb36712d)

Solutions

  1. Fix the operator: change `(hdcRasterCaps | 1) == 0` to `(hdcRasterCaps & 1) == 0` so RC_BITBLT is actually tested.
  2. If a device genuinely lacks BitBlt after the fix, fall back to GraphicsCapture or DXGI capture mode.
  3. Validate device caps during capture-mode selection and pick a backend the hardware supports.

Example fix

// before
if ((hdcRasterCaps | 1) == 0) // RC_BITBLT
    throw new Exception("BitBlt not supported");

// after
if ((hdcRasterCaps & 1) == 0) // RC_BITBLT
    throw new Exception("BitBlt not supported");
Defensive patterns

Strategy: validation

Validate before calling

// After fixing the operator to '&':
var caps = Gdi32.GetDeviceCaps(hdc, Gdi32.DeviceCap.RASTERCAPS);
if ((caps & 1) == 0) // RC_BITBLT not supported
    return CaptureMode.BitBltUnsupported; // pick another backend

Prevention

When it happens

Trigger: Only theoretically: a device context reporting no RC_BITBLT capability (some virtual/remote display drivers). In practice unreachable due to the `|` vs `&` bug.

Common situations: Headless or virtual display adapters, certain RDP modes, or software renderers with limited raster caps — but the bug prevents the guard from ever triggering.

Related errors


AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13). Data as JSON: /api/errors/0c8c98472b9dbf66. Report an issue: GitHub.