«Эксклюзивная» палитра DirectDraw на самом деле не является эксклюзивной - PullRequest
5 голосов
/ 28 июня 2009

Мы поддерживаем старую видеоигру, которая использует полноэкранный 256-цветный графический режим с DirectDraw. Проблема в том, что некоторые приложения, работающие в фоновом режиме, иногда пытаются изменить системную палитру во время игры, что приводит к повреждению графики.

Мы можем (иногда) определить, когда это происходит, обработав сообщение WM_PALETTECHANGED. Несколько версий обновлений назад мы добавили ведение журнала (просто введите заголовок окна / класс / имя процесса), что помогло пользователям идентифицировать вредоносные приложения и закрыть их. MSN Live Messenger был распространенным преступником.

Проблема усугубилась, когда мы узнали, что Windows Vista (и 7) делает это «сама по себе». Параметры WM_PALETTECHANGED указывают на CSRSS и окно рабочего стола. В Vista часто применялся обходной путь - открыть любую папку (компьютер, документы и т. Д.) И оставить ее открытой во время игры. Звучит смешно, но это сработало - в большинстве случаев. В Windows 7 даже этот обходной путь больше не работал. Пользователи обнаружили, что остановка некоторых служб (Центра обновления Windows и службы индексирования) также решила проблему в некоторых конфигурациях.

Некоторое время назад я просто начал пробовать случайные вещи в надежде найти решение. Я обнаружил, что установка палитры GDI (с помощью Create / SelectPalette) перед настройкой палитры DirectDraw (с использованием IDirectDrawPalette :: SetEntries) будет восстанавливать палитру после ее повреждения (обработчик WM_PALETTECHANGED). SetSystemPaletteUse и вызов SetPalette на первичной поверхности помогли еще немного. Однако при попытке кражи палитры приложение все еще ощущает мерцание, которое особенно заметно во время затухания.

Вопрос: есть ли способ получить «настоящую» эксклюзивную палитру, которая полностью запрещает другим приложениям изменять палитру Windows, пока наша игра сохраняет фокус?

Ответы [ 5 ]

3 голосов
/ 11 августа 2009

То, что вы можете сделать, это «простой» обходной путь. Поскольку ваша игра - старая игра, она, вероятно, не соответствует текущему оборудованию, поэтому этот прием будет работать:

  • Сбросить все в буфер за пределами экрана (память)
  • преобразовать 8-битный буфер в 16-битный (или 32-битный), используя текущую палитру (так же сделано в памяти)
  • скопировать содержимое 16-битного (или 32-битного) буфера в буферный буфер экрана
  • перевернуть экранный буфер.

Это потребует минимальных изменений в вашей игре и полностью избавит от проблем палитры, хотя ваша игра все еще может использовать все свои хитрости палитры

R

1 голос
/ 03 августа 2010

Кто-то действительно нашел исправление записи реестра для этого, здесь:

http://answers.ea.com/t5/Command-Conquer-The-Ultimate/Common-Problems-Read-This-Before-Posting/m-p/222052

Найдите на этой странице "зашифрованные цвета", и вы попадете в нужное вам исправление.


Так как онлайн-ресурсы мимолетны, вот полное объяснение:

Создайте новый ключ в разделе «HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ DirectDraw \ Compatibility \» для программы.

Если программа, для которой вы применяете совместимость, является 32-битной программой, и вы работаете в 64-битной системе (применяя ее вручную или через 64-битную программу), не забудьте добавить "Wow6432Node" между "Software" и "DirectDraw", чтобы компенсировать это.

В этом ключе установите следующие значения:

  • "Флаги" (REG_BINARY): [00,08,00,00]
  • «Имя» (REG_SW): имя файла вашей программы. Нет пути, только имя исполняемого файла.
  • «ID» (REG_BINARY): DirectDraw ID приложения.

Чтобы получить требуемый идентификатор DirectDraw, запустите программу и проверьте этот раздел реестра:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectDraw\MostRecentApplication

Опять же, если вы работаете в 64-битной системе, и программа, для которой вы это делаете, является 32-битной, добавьте "Wow6432Node" после "Software".

Идентификатор в этом ключе составляет четыре байта. Измените их порядок, чтобы получить байты для ввода значения идентификатора. 32dd83d5 становится d5,83, дд, 32.

0 голосов
/ 19 июля 2013

Все, что вам нужно сделать, это установить ваш ПК на 16 bit цветов на панели управления, и игра подходит, работает на Original Command and Conquer для меня: D

0 голосов
/ 27 мая 2010

Я совсем не знаю DirectX, но я бы посоветовал попробовать сделать рендеринг вне экрана, а затем преобразовать в глубину экрана ... Я думаю, вы можете заставить Direct2D сделать все это за вас ...

0 голосов
/ 30 июня 2009

Очевидно "приложение не должно вызывать SetSystemPaletteUse, если оно не имеет развернутое окно и фокус ввода" . Возможно, какая-то другая программа плохо себя ведет. Это описание звучит очень похоже на то, что Microsoft надеется, что все программы будут сотрудничать, и не предложит способа заставить их сделать это. Это как вернуться на Windows 3.1. :)

Случайное предложение: пробовали ли вы SetSystemPaletteUse с параметром SYSPAL_NOSTATIC256?

Вы также можете увидеть, содержит ли ваша палитра 20 зарезервированных цветов Windows; если это так, это означает, что любой другой палитрированной программе, которая просто использует цвета Windows, не нужно будет менять палитру для того, чтобы визуализировать себя, насколько я понимаю.

...