С ограничением на объем памяти мы столкнулись, когда определяли максимально допустимое число спрайтов1, и связано это было с тем, что наша программа перемещения спрайтов работала в реальном режиме DOS, отличающемся следующими особенностями. Полный объем доступной памяти составляет 640 Кбайт, причем часть ее занимают сама ОС и ее драйверы. Исполняемая программа способна использовать лишь 400—550 Кбайт. И главное, этот объем не зависит от вместимости ОЗУ компьютера — неважно, составляет ли она 1 или 64 Мбайт. Кроме того, память сегментирована, и размер одного сегмента не превышает 64 Кбайт. Таким образом, работа с памятью, реализованная с помощью распространенного компилятора Borland Pascal, ограничивает максимальный размер любой структуры или массива величиной в 64 Кбайт. Эту же величину не должен превосходить суммарный объем всех статических переменных и констант. Так что разработчику зачастую приходится предусматривать, даже при использовании графического режима с разрешением 320x200 точек, возможность загрузки с диска новых изображений во время игры при переходе на следующий уровень, в другие локацию или игровой режим. Применять более высокое разрешение в реальном режиме становится почти невозможным.
Чтобы задействовать всю имеющуюся в компьютере память, программа должна работать в защищенном режиме процессора (PM — protected mode), впервые появившемся в 286-м процессоре. В Borland Pascal есть средства для создания программ, работающих в этом режиме. Максимально доступный объем памяти был увеличен с 640 Кбайт до 16 Мбайт, однако ограничение в 64 Кбайт на размер массива или статических данных не только сохранилось, но и стало более строгим2. Появление 386-го процессора с 32-разрядным защищенным режимом устранило сразу оба ограничения, и 16-разрядный защищенный режим отошел в прошлое. К сожалению, Borland Pascal новый режим не поддерживает. Однако существуют компиляторы языка Паскаль, допускающие такую поддержку [1], в частности свободно распространяемый ТМТ Pascal (www.tmt.com). В нем, в отличие от Borland Delphi, сохранена идеология Borland Pascal, поэтому мы и будем использовать именно его для дальнейшего усовершенствования нашей программы.
Тридцатидвухразрядные приложения DOS (далее — DOS32) могут работать в среде любой совместимой с DOS операционной системы, например, в DOS-сессии Windows 9х/Me. В текстовом режиме они практически не отличаются от консольных приложений многозадачной ОС, а в полноэкранном графическом — от приложений, написанных с помощью DirectDraw. Более того, программы DOS32 зачастую работают быстрее приложений Windows, особенно при выводе информации на экран. Но поскольку в среде DOS не применяются 3D-ускорители, а также возникают сложности с современными звуковыми платами, она практически вытеснена из игровой индустрии. А вот для вывода спрайтовой графики приложения DOS32 вполне подходят.
Переделаем нашу программу таким образом, чтобы можно было отображать движение анимированных спрайтов в графических режимах с высоким разрешением через сервис VESA [2, 3]. Стандартный модуль graph TMT Pascal содержит средства для работы в этих режимах3.
Многие программы, написанные в среде Borland Pascal, не требуется изменять, чтобы они могли функционировать и в ТМТ. Однако защищенный режим имеет свои особенности. Так, программы, созданные в реальном режиме Borland Pascal, не всегда работают в защищенном режиме этого же компилятора. Это же свойственно и программам, компилируемым с помощью TMT Pascal: если они работают в защищенном режиме Borland, то, скорее всего, будут функционировать и в ТМТ. Некоторую несовместимость реального режима с защищенным имеют операции с указателями, с прямой адресацией памяти, с прерываниями DOS и BIOS, а также с аппаратными прерываниями.
В нашей программе кроме основного блока накопились еще семь модулей. Из них bmpread, mouse и timer18 не нуждаются в какой-либо переделке — они без изменений могут «трудиться» и в защищенном режиме. Модуль sprites из-за изменения экранного режима в любом случае придется переделывать. Оставшиеся три модуля по тем или иным причинам оказались несовместимы с защищенным режимом: pal и text256 — по передаче адреса в прерывание BIOS, а keyboard — по обработчику аппаратного прерывания.
Внесем изменения в модули sprites и pal, а модули keyboard и text256 временно отключим. Кроме того, дополнительно подсоединим модуль graph, входящий в стандартные библиотеки.
Начнем с pal. Конечно, все сложности с вызовом прерывания реального режима из защищенного преодолимы, но все же будет лучше использовать альтернативный способ установки палитры — непосредственную запись в порты видеоплаты. Порты $3c7 и $3c8 предназначены для того, чтобы задавать номер цвета при чтении и установке палитры соответственно, а $3c9 — для записи составляющих RGB, которые пишутся в один и тот же порт по очереди: красный, зеленый, синий. Чтение происходит аналогично. Текст изменений приведен в листинге 1.
В модуле sprites изменений гораздо больше. Если среди стандартных видеорежимов VGA лишь в одном допускается использовать 256 цветов, то среди режимов SVGA таких будет довольно много, и потому неразумно привязываться к какому-либо одному из них. Так как при разработке программы неоднократно приходится указывать размеры экрана, то целесообразно установить четыре дополнительные константы, характеризующие пространственное разрешение.
const ScrSizeX = 800; ScrSizeX1 = ScrSizeX-1; ScrSizeY = 600; ScrSizeY1 = ScrSizeY-1;
Теперь в модуле sprites повсюду заменим 319 на ScrSizeX1, а 199 — на ScrSizeY1, а также поместим ссылку на модуль graph, в котором предусмотрены процедуры не только для установки режимов SVGA, но и для работы с экранным буфером и спрайтами (листинг 2). Кстати, объем экранного буфера, составлявший 64 тыс. байт, здесь явно не задается и даже не вычисляется исходя из размеров экрана, а возвращается функцией GetPageSize из модуля graph. Это связано с тем, что объем буфера должен быть равен объему используемой видеопамяти, а конструкция некоторых видеоплат такова, что памяти под экран выделяется больше, чем нужно. Естественно, функция GetPageSize должна вызываться только при установленном графическом режиме.
Окончание в следующем номере.
Полные тексты программ находятся по адресу www.pcworld.ru.
Литература
1. Андрианов С. Паскаль сегодня // Мир ПК. 2001. № 4. С. 68.
2. Андрианов С. А. VESA: стандарт новый, проблемы старые // Мир ПК. 1998. № 7. С. 62.
3. Андрианов С. А. VESA 2.0: программируем в защищенном режиме // Мир ПК. 1998. № 8. С. 22.
1 См. «Мир ПК» за 2001 г. — № 7, с. 87; № 10, с. 99; № 11, с. 100; № 12, с. 98; за 2002 г. — № 1, с.117; № 2, с. 107; № 3, с. 100; № 5, с. 108; № 6, с. 103; № 9, с. 96; № 10, с. 98; № 11, с. 112.
2 В реальном режиме с помощью вычисления сегментной части адреса можно было направлять более 64 Кбайт, а в защищенном вместо адресов используются селекторы, арифметические действия над которыми запрещены.
3 Включая режимы с большей глубиной цвета: 15, 16, 24 и 32 разряда на пиксел.