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

StackOverflow https://stackoverflow.com/questions/1054365

  •  20-08-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

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) :Имя файла вашей программы.Никакого пути, только имя исполняемого файла.
  • "ИДЕНТИФИКАТОР" (REG_BINARY) :Идентификатор DirectDraw приложения.

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

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectDraw\MostRecentApplication

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

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

Другие советы

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

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

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

R

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top