gdi - "Exclusive"DirectDraw 调色板实际上不是独占的

标签 gdi directdraw palette

我们正在维护一个使用 DirectDraw 的全屏 256 色图形模式的旧视频游戏。问题是,某些在后台运行的应用程序有时会在游戏运行时尝试更改系统调色板,从而导致图形损坏。

我们可以(有时)通过处理 WM_PALETTECHANGED 消息来检测何时发生这种情况。几个更新版本之前,我们添加了日志记录(只记录窗口标题/类/进程名称),这有助于用户识别有问题的应用程序并关闭它们。 MSN Live Messenger 是一个常见的罪魁祸首。

当我们发现 Windows Vista(和 7)“自行”完成时,问题变得更糟了。 WM_PALETTECHANGED 参数指向 CSRSS 和桌面窗口。在 Vista 中,一种通常有效的解决方法是打开任何文件夹(计算机、文档等)并在运行游戏时将其保持打开状态。听起来很荒谬,但它奏效了——在大多数情况下。在 Windows 7 中,即使是这种解决方法也不再有效。用户发现停止某些服务(Windows 更新和索引服务)也解决了某些配置上的问题。

前段时间我刚开始尝试随机的东西,希望能找到解决方案。我发现在设置 DirectDraw 调色板(使用 IDirectDrawPalette::SetEntries)之前设置 GDI 调色板(使用 Create/SelectPalette)会在调色板损坏后恢复它(WM_PALETTECHANGED 处理程序)。 SetSystemPaletteUse 和在主表面上调用 SetPalette 提供了更多帮助。但是,当应用程序试图窃取调色板时,仍然存在可察觉的闪烁,这在淡入淡出期间尤为突出。

问题:有没有办法获得一个“真正的”专属调色板,只要我们的游戏保持焦点,它就完全不允许其他应用程序更改 Windows 调色板?

最佳答案

您可以做的是一个“简单”的解决方法。由于您的游戏是旧游戏,因此可能无法与当前硬件匹配,这就是此技巧有效的原因:

  • 将所有内容 Blit 到屏幕外缓冲区(内存)
  • 使用当前调色板将 8 位缓冲区转换为 16 位(或 32 位)
    (在内存中也是如此)
  • 将 16 位(或 32 位)缓冲区的内容复制到屏幕的后缓冲区
  • 翻转屏幕缓冲区。

  • 这将需要对您的游戏进行最少的更改,并且将完全摆脱调色板问题,尽管您的游戏仍然可以使用它所有的调色板技巧

    R

    关于gdi - "Exclusive"DirectDraw 调色板实际上不是独占的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1054365/

    相关文章:

    c++ - 如何将一个窗口保持在另一个应用程序窗口的前面

    windows - 通用纯文本打印机驱动程序不起作用

    colors - GNUPLOT splot 调色板匹配 jetmap

    Javascript/ExtendScript/ScriptUI 临时窗口消息

    c - 在 GDI 中绘制文本并使其适合矩形?

    c++ - 如何使用 C++/WinAPI 绘制具有透明背景的文本?

    c++ - 在 DirectDrawCreate 上解析 'LNK2019 unresolved external symbol'

    directdraw - 如何在 DirectX 12 中绘制文本?

    c++ - DirectDraw Blt函数参数

    java - Android 上的 AnyChart 着色网格