«Эксклюзивная» палитра DirectDraw на самом деле не является эксклюзивной

Мы поддерживаем старую видеоигру, которая использует полноэкранный 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)

16 bit цвета в панели управления и игра идет правильно, работает наOriginal Command and Conquer для меня: D

 Ray Koopa27 июл. 2013 г., 12:04
Также в Windows 8 и более поздних версиях вы не можете установить 16-битную глубину цвета.
 Vladimir Panteleev20 июл. 2013 г., 00:06
Это не решение, которое может быть применено в видеоигре. Кроме того, это не будет работать для версий Windows, начиная с Windows 8, которые больше не поддерживают цветовые режимы ниже, чем True Color.
 Nyerguds19 дек. 2013 г., 10:27
Просто к твоему сведению, есть переопределение дроу создан специально для Command & Conquer, который работает на всех ОС. Я бы посоветовал просто скачать полный неофициальный патч к игре, хотя; CnC-DDraw все равно был оптимизирован для этого: p

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

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

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

R

 Nyerguds05 окт. 2012 г., 13:26
У не очень современных ПК нет бизнеса, использующего разрешения HD: p
 Vladimir Panteleev20 сент. 2012 г., 12:19
Это то, с чем мы В конечном счете прошли, но это не получилось дешево. Некоторые пользователи сообщили о Тройной Использование процессора из-за преобразования программной палитры.
 Toad21 сент. 2012 г., 16:16
@ CyberShadow Тогда вы, возможно, делаете это неправильно. Преобразование может быть выполнено с использованием действительно тесного цикла, используя только поиск. Если хочешь, я могу проверить твой код.
 Vladimir Panteleev22 сент. 2012 г., 03:20
Я уверен, что код в порядке - вот цикл:for ( int i=0; i < iSize; i++ ) *(pDst++) = pPalette[ *(pSrc++) ]; Проблема заключается в том, чтобы делать это при 60 FPS на HD-разрешениях и не очень современных ПК.
 Nyerguds13 нояб. 2010 г., 14:37
Кто-то делает это в первых двух играх Command & Conquer (C & C1 и Red Alert 1), делая переопределение ddraw.dll. Работал довольно хорошо, и добавил оконный режим (после некоторых попыток адаптировать функции смещения мыши, чтобы компенсировать переменное смещение 0,0). Информация о проекте на Hifi.iki.fi / чпу-ddraw
Решение Вопроса

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

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

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

Создайте новый ключ в разделе «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.

 Vladimir Panteleev04 авг. 2010 г., 22:26
Да, похоже на работу :) Спасибо!
 Vladimir Panteleev03 авг. 2010 г., 17:30
Спасибо, выложили скрипт для тестирования наших пользователей, посмотрим, как он будет работать для нашей игры на практике.
 Adrian McCarthy20 июл. 2013 г., 01:00
Это похоже на совместимость, которую Microsoft вставила для приложений, которые неправильно обрабатывали палитру.

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

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

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

 Vladimir Panteleev01 июл. 2009 г., 03:50
Когда палитра будет украдена, обычно это будет полная (или большая часть видимой) палитры, поэтому, вероятно, это не было параметром приложения SetSystemPaletteUse. Мы добавили вызов SetSystemPaletteUse (dc, SYSPAL_NOSTATIC256), и это помогло в некоторых ситуациях, но не решило основную проблему. Пространство палитры ограничено, так что мы бы предпочли, чтобы мы время от времени мерцали, а не переписывали игру или пользовательский контент.

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

Ваш ответ на вопрос