Практикум

От редакции. Автор статьи, которую нам доставила почта из Тамбовской области, не просто играл в компьютерные игры, как все остальные люди, но и серьезно анализировал используемые в играх видеорежимы. Основываясь на результатах этого исследования, он предложил свой, нетрадиционный, подход к разрешению противоречия между качеством изображения и требованиями к аппаратному обеспечению. И хотя при тестировании предложенной автором программы были выявлены некоторые проблемы совместимости с различными видеоадаптерами, мы решили опубликовать этот материал как пример творческого подхода к использованию возможностей видеоплат. А вдруг сама идея этого метода окажется для кого-нибудь полезной?

Итак, вы все-таки решились создать свою собственную игру и тем самым покорить всю игровую общественность мира (страны/города/отдельно взятой квартиры), а заодно и заработать несколько миллионов долларов (десятков тысяч/сотен/на бутылку "Пепси"). Что ж, давно пора потеснить всякие там Id. Apogee, Electronics Arts, Broderbund, Sierra и пр. Но прежде чем этим заняться, давайте рассмотрим режим видеоадаптера, в котором будет работать ваша программа.

Ни для кого не секрет, что подавляющее большинство игр, вышедших после 1990 г., поддерживают графику с 256 оттенками цветов. Причем до 1994 г. производители за редким исключением использовали режимы низкого разрешения 320x200 и 320x240 точек (Low Resolution, далее LowRes), которые характеризуются недостаточной детализацией изображения. И только с 1994 года началось массовое использование режимов высокого разрешения (High Resolution, далее - HiRes), в основном 640x480, обеспечивающих отличную детализацию изображения.1

Использование режима HiRes можно только приветствовать: качество изображения при этом резко улучшается, сравните хотя бы WarCraft и WarCraft 2. Но, как оказалось, для некоторых классов игр переход в HiRes сопровождается резким увеличением требований к аппаратуре, что пагубно отражается на объемах продаж. Я имею в виду следующие игры: Doom, Rise of the Triad, Dark Forces, Descent, Terminal Velocity, Magic Carpet, Alone in the Dark, Ecstatica, BioForge, Mortal Kombat, Rise of the Robots.

В играх этих классов постоянно перерисовывается либо весь экран (Doom, Descent), либо большая его часть (Ecstatica). Это значит, что аппаратные требования возрастают практически пропорционально увеличению количества элементов обрабатываемого изображения. Для вышеперечисленных игр объем страницы видеопамяти в LowRes-режиме составляет 62,5 Кбайт, в HiRes-режиме - 300 Кбайт - почти в пять раз больше! Это значит, что для запуска HiRes-версий этих игр нужна система, возможности которой существенно превышают рекомендуемые минимальные требования, т. е. нужна машина с процессором Pentium-100 и 16-Мбайт ОЗУ, а не с процессором 486-ЗЗ и ОЗУ 4 Мбайт. Такая конфигурация для игрового компьютера станет обычной не раньше конца 1996 года, а то и позже. При этом следует помнить, что во всем мире есть десятки миллионов машин типа 486-50 - 486-100 с 8-Мбайт ОЗУ, владельцы которых составляют и еще долго будут составлять большую часть покупателей игр. Выходит, что популярными HiRes-версии подобных игр еще долго не станут - слишком велики аппаратные требования. Значит ли это, что придется с их выпуском повременить? Возможно, нет. И вот почему.

Мне кажется удивительным, что производители игр обходят своим вниманием режим среднего разрешения (Medium Resolution, далее MedRes) 320x400 точек, характеризующийся вдвое более высокой детализацией, нежели LowRes-режим. К тому же качество изображения в этом режиме весьма близко к качеству в HiRes-режиме. А вот объем страницы видеопамяти в MedRes-режиме больше, чем в LowRes-режиме, всего лишь в два раза, а не в пять, как в случае с HiRes. Характеристики некоторых видеорежимов, пригодных для игр, приведены в таблице.

Для переключения в тот или иной нужный вам видеорежим можно использовать приведенный ниже фрагмент текста программы на Ассемблере с соответствующими модификациями. Данный текст включает MedRes-режим (см. листинг 1).

Последние две команды, собственно, и включают разрешение по вертикали 400 точек. Все дело в том, что LowRes-режима на самом деле не существует: это модификация MedRes-режима 320x400 точек. Переделку осуществляет видео BIOS, включая двойное сканирование каждой строки. Это делается очень просто: в младшие пять битов регистра высоты символа (порт 3D4h, индекс 9) заносится значение на единицу меньше нужного, т. е. для 400 линий заносим О (один раз сканировать линию), для 200 линий заносим 1 (два раза сканировать линию). Разумеется, можно включить и троекратное, и четырехкратное и даже 32- кратное сканирование - все зависит от значения этих младших пяти битов, и только! Кстати, если последние две команды в листинге убрать, то разрешение по вертикали все равно будет составлять 200, просто включится режим адресации "4 плоскости", в котором работают Doom, Heretic, Rise of the Triad, Ecstatica и многие другие игры.

Таким образом, для запуска MedRes-версий упомянутых игр будет достаточно машины с процессором 486-66 и 8-Мбайт ОЗУ. Согласитесь, это терпимо. Зато разница в качестве изображения будет очень заметна, можете проверить это, оттранслировав и запустив программу SLIM, приведенную в листинге 2. При использовании Турбо-Ассемблера фирмы Borland не забудьте указать параметр /m (многопроходность компиляции). После запуска программа SLIM остается резидентной, и если какая-нибудь другая программа попытается включить видеорежим 320Ё200 точек с 256 оттенками цветов, то она заменит его на 320x400. Изображение при этом сплющится и будет занимать верхнюю половину экрана.

Думаю, что единственным препятствием для использования такого режима является некоторая необычность пропорций, быть может, затрудняющая обработку изображений в графическом редакторе. Действительно, в режиме 320x400 точка изображения вдвое меньше по вертикали, чем в режиме 320x200, но именно за счет этого и достигается улучшение качества изображения. Двух страниц видеопамяти, доступных в MedRes-режиме, достаточно для применения механизма чередования, используемого в подавляющем большинстве игр. При этом во время показа одной страницы в другой рисуется изображение, затем страницы меняются ролями, и т. д. Таким образом, процесс перерисовки не виден и изменения на экране происходят без миганий и прочих дефектов.

Возможно, приведенные аргументы в пользу MedRes-режима, не убедят вас, - что ж, сколько людей, столько и мнений. Если же эта информация будет вам полезна, значит, автор трудился не напрасно.

Режим
Разрешение,
точки
Объем страницы
(Кбайт)
Число
страниц
Параметры
видеоплаты
LowRes
LowRes
MedRes
MedRes
HiRes
HiRes
320x200
320x240
320x400
360x480
640x480
800x600
62,5
75
125
169
300
469
4
3
2
1
1
1
VGA 256 Кбайт
VGA 256 Кбайт
VGA 256 Кбайт
VGA 256 Кбайт
SVGA 512 Кбайт
SVGA 512 Кбайт

Алексей Хошенко - программист Уваровского химического колледжа, адрес в редакции.

Практикум

Листинг 1. Фрагмент программы, включающей MidRes-режим

mov ax,0013h
; Включаем режим 320x200
int 10h
mov dx,03C4h
mov ax,0604h
; Адресация "4 плоскости"
out dx,ax
; A000h - сегментный адрес видеобуфера
push 0A000h
pop es
xor di,di
xor ax,ax
mov cx,B000h
; Очищаем видеопамять от "мусора"
rep stosm
mov dx,03D4h
mov ax,OE317h
out dx,ax
mov ax,0014h
; Байтовый режим сканирования
out dx,ax
mov ax,4009h
; Отключаем двойное сканирование строк 
out dx,ax 







Листинг 2. Резидентная программа SLIM, включающая разрешение 320x400 вместо 320x200. Компилировать в СОМ-Файл.

.286
assume cs:code,ds:nothing
code segment
org 02Ch
envir dw ?
org 0B0h
old_10 dd ?
org 100h
start: jmp short inst
int_10: cmp ax,0013h; Попытка включить режим 320x200?
je ok; Да, идем на "подмену"
jmp dword ptr old_10; Нет, передаем управление дальше
ok:
pushf
call dword ptr old_10; Включаем режим 320x200
pusha; Сохраняем регистры процессора
cld; Очистка флага направления
mov si,offset array; Адрес массива с параметрами
mov cx,5; Количество параметров
mov dx,03D4h; Порт видеоплаты
;
db 2Eh
rep outsw; Загрузка параметров в видеоплату
popa; Восстанавливаем регистры процессора
iret; Возврат в программу
array dw 0E11h, 0C712h, 1D07h, 4009h, 8E11h
inst: assume ds:code
mov ax,3510h
int 21h; Считываем вектор 10h.
mov word ptr old_10,bx; и сохраняем 
mov word ptr old_10+2,es; его для 
будущих целей
mov ax,2510h
mov dx,offset int_10
int 21h; Берем вектор 10h на себя
mov es,envir
mov ah,49h
int 21h; Отказываемся от окружения
mov dx,offset inst
int 27h; Остаемся резидентом
code ends
end start


1 Информация об используемых в играх видеорежимах была получена с помощью программы - перехватчика картинок Smart Grab 3.11 (автор Евгений Шутров).