Разработка игр на Evo SDK
Переходим от абстрактных материй типа
геймплея к более приземлённым. На чём де─
лать игру? Могу предложить Evo SDK.Почему
именно его? Потому что я делаю игры в ос─
новном в этой среде и достаточно неплохо
её изучил.
Я перешел на неё со связкиC++, OpenGL
из-за того, что мне хотелось просто делать
свои игры, без долгой возни с оборудовани─
ем, разработки формата хранения моделей и
создания конвертера под него (OpenGL не
имеет какого-то стандартного формата хра─
нения моделей), хотелось чего-то более ин─
тересного,чем банальный PC. Готовые движки
меня не устраивали, т.к. игра,созданная на
чужом движке, не давала той радости, как
игра, написанная своими руками полностью с
нуля.Языком ассемблера я не владею,и выбор
сам собой пал на Evo SDK. Вот несколько
аргументов в его пользу (если, конечно,вам
не важна платформа и вы не хотите делать
трёхмерные игры):
*Лёгкий старт. Для того, чтобы просто
инициализировать видеокарту и создать пус─
тое окно, на OpenGLнужно написать около
экрана кода.В Evo SDK не нужно ничего ини─
циализировать,всё уже готово.Если есть ка─
ртинка спрайта,то её можно отобразить все─
го парой вызовов. Для начала работы нужно
всего лишь взять заготовкуempty_project,
открытьmain.cи начать писать свой код.
* Ресурсы.С одной стороны, ограниченные
ресурсы Спектрума - это огромный минус по
сравнению с обычным PC с его гигабайтами
и гигагерцами. Зато ограничения "железа"
сдерживают амбиции разработчика, тут уже
сложнее "увязнуть" в процессе подготовки
ресурсов. Ещё, в отличие от поиска готовых
текстур,рисование пиксельной графики - это
настоящее искусство. Программирование в
условиях ограниченного пространства с не
шибко быстрым процессором быстро оттачива─
ет навыки программиста. Приходится как-то
"ужиматься", оптимизировать код,выдумывать
более быстрые алгоритмы, что само по себе
уже довольно интересно.
* "Теплота и ламповость".Как ни крути,
а АТМ Turbo 2 является клоном ZX Spectrum
родом из 90-х, что навевает ностальгию.
Что,собственно,из себя представляет Evo
SDK? Это SDCC - кросс-компилятор языкаC,
плюс набор библиотек, позволяющих максима─
льно отдалиться от низкоуровневой работы с
железом, и набор утилит и скриптов, позво─
ляющих максимально просто и быстро из ис─
ходников и ресурсов собрать готовый образ
TR-DOS. Вся эта система позволяет без лиш─
них телодвижений на домашнем компьютере, в
любом удобном для вас редакторе на простом
и понятном языкеС написать игру, которая
будет использовать навороты ATM2 или Pent─
evo. Правда, за удобства придётся распла─
чиваться потерей быстродействия, увеличен─
ным объемом кода (компилятор несовершенен,
и там, где опытный программист на ассемб─
лере обойдётся десятью командами, компиля─
тор может использовать тридцать и более) и
ограниченными возможностями (это не такая
большая проблема - ассемблерные вставки
делать никто не запрещал).
Взять текущую версию можно вот здесь:
http://
alonecoder.nedopc.com/zx/evosdk_libs.rar
В рамках этой статьи я не буду подробно
описывать все возможности Evo SDK и давать
комментарии ко всем его функциям.Вся необ─
ходимая информация есть вreadme.txt, и
все функции подробно прокомментированы в
evo.h. Здесь я опишу новые "фишки" SDK,
такие как работа с памятью и диском,а так─
же несколько "подводных камней",с которыми
можно столкнуться в начале работы с SDK.
В архиве с SDK находится две версии
среды:
*Настроенная под SDCC версии2.9;
*Настроенная под SDCC версии3.4.0(на─
ходится в архивеevosdk_3_4_0_hippiman.7z)
Отличия этих версий минимальны, но их
стоит принять во внимание. SDCC версии
3.4.0 компилирует код на С намного более
компактно и правильно, чем SDCC2.9 версии
и, казалось бы, надобность в более старой
версии SDCC отпадает. Однако SDCC более
новой версии компилирует исходный код в
несколько раз дольше.На моём Core i5 время
компиляции SpaceMerc на SDCC3.4 занимает
порядка четырёх-пяти минут против 40-60
секунд в SDCC2.9. Отсюда следует следую─
щий совет. Для начальных стадий проекта,
когда исходный код не слишком большой и
тестовые компиляции проводятся часто,лучше
использовать SDK настроенный под SDCC вер─
сии 2.9, а на поздних стадиях разработки
перейти на более новую версию SDK.
Также в архиве со сборкой SDK под SDCC
3.4.0 находятся несколько дополнительных
библиотек:put_get_mem_atm.h (функции ра─
боты с страницами памяти), additions.h
(сборник дополнительных функций, которые
могут существенно упростить разработку иг─
ры). Если вы будете использовать старую
версию SDK, скопируйте туда эти хедеры.
Графика:
Руководство говорит: "Графика должна
быть подготовлена в форматеBMPбез сжа─
тия,с 16 или 256 цветами (используются пе─
рвые 16 цветов). Для этого могут использо─
ваться любые стандартные графические реда─
кторы". Включая стандартный Paint. Однако
Paint не умеет редактировать палитру, при
сохранении он подбирает цвета сам.Для под─
готовки графики наилучшим образом подходят
программы типа GIMP и Photoshop, которые
умеют создавать "палитровые" изображения.
Но здесь есть одна меленькая деталь. GIMP
(начиная с версии 2.8 ) и новые версии
Photoshop сохраняют "палитровые"BMP нес─
колько странно. Из картинок, сделанных в
этих редакторах, SDK не может получить па─
литру, причём вся информация о цветах сох─
раняется, и если подставить к изображению
уже готовую палитру,то оно будет отобража─
ться нормально. Я настоятельно рекомендую
использовать GIMP версии2.6.9. В версии
2.7.* есть небольшой глюк с рендером рабо─
чего пространства при сильном увеличении.
SDK умеет работать со спрайтами16x1бpx
(до 64 штук одновременно на экране) и име─
ет два режима: отображение спрайтов вклю─
чено или выключено. При включённом отобра─
жении спрайтов рисовка всех тайлов проис─
ходит на два экрана сразу, при выключенном
- только в теневой экран. Это нужно учиты─
вать при построении изображения.С включён─
ными спрайтами рисовка тайлов идёт сущест─
венно медленней.
При отображении спрайтов прозрачными
считаются цвета после 16-го, т.е. можно
использовать все цвета палитры плюс про─
зрачный, а при отображении тайлов прозрач─
ный цвет нужно указывать из палитры. Сле─
дует учитывать при разработке игры, что
прозрачные тайлы имеют на один цвет боль─
ше, и если вы хотите использовать все 16
цветов в прозрачных тайлах, то рисуйте их
в два слоя с разными прозрачными цветами.
Звук:
Со звуком не должно возникнуть каких-
либо затруднений, но стоит предостеречь от
чрезмерного использования Covox. Воспроиз─
ведениеwav через Covox хоть и звучит вну─
шительно, но приостанавливает выполнение
основной программы, что нарушает динамику
игры,а сами звуки занимают достаточно мно─
го места в памяти. Covox можно использо─
вать при переходах в меню,окончании уровня
и т.д.
Программирование:
Переменные внутри функций желательно
объявлять с использованием ключевого слова
static, это существенно уменьшает объём
скомпилированного кода.
Также желательно избегать частого вызо─
ва функций с большим количеством парамет─
ров или со сложными типами в качестве па─
раметров.Это увеличивает объём скомпилиро─
ванного кода. Если работы с такими функци─
ями избежать не удаётся, можно объявить
параметры этой функции как глобальные пе─
ременные и инициализировать их данными до
вызова.
Карты игровых уровней и прочие большие
массивы данных, которые нужны не часто,
лучше всего выносить в отдельные страницы
памяти и при необходимости загружать их во
временный буфер в основной памяти. Это за─
медляет программу, но экономит место в па─
мяти, которое можно занять более полезными
вещами.
Чтобы ещё сильнее сэкономить место в
памяти,карты уровней можно вынести в отде─
льные файлы на диске.
Руководство по SDK обещает около55 КБ
под скомпилированный код, однако счётчик
объёма кода врёт.Уже при объёме кода около
38 КБ (эта граница может сдвигаться в ту
или иную сторону в зависимости от структу─
ры программы) могут начаться глюки. Игра
нормально скомпилируется,но может не зара─
ботать,или в процессе игры начнут самопро─
извольно появляться и исчезать какие-либо
объекты. Если подобные странности начали
происходить, то,скорее всего,ваш скомпили─
рованный код превысил максимальный объём.
Чуть выше я сказал, что SDK умеет рабо─
тать со страницами памяти. Для этого вам
понадобятся хедер put_get_mem_atm.h. Для
записи данных в память есть функции:
put_mem() (1 байт),put_memw() (2 байта) и
put_meml() (4 байта). Где параметры:
PG -номер страницы,куда пишутся данные.
ADDR -адрес, куда пишутся данные.
DATA -собственно сами данные.
Будьте внимательны, не пишите данные в
страницы,уже занятые игрой под ресурсы или
код. Посмотреть,какие страницы под что от─
ведены, можно после компиляции проекта в
окошке компилятора. Также следует помнить,
что эти функции предназначены для работы с
памятью ATM2, и у нас есть всего64 стра─
ницы -1 МБ. Адрес, куда пишутся данные,
должен выглядеть так:32768+смещение внут─
ри страницы.
Для получения данных из памяти есть фу─
нкции:get_mem(), get_memw() и get_meml(),
которые возвращают 1, 2 и 4 байта соответ─
ственно.
Теперь о работе с диском. В SDK реали─
зована функция TR-DOS #3D13. Изначально
вызвать её можно только из ассемблерной
вставки,но вadditions.h есть обвязка этой
функции на языкеС:
void DOS (u8 pg, u8 operation, u8 blocks,
u8 sector, u8 track, u16 begin_page)
__naked
Пройдёмся по параметрам.
PG- номер страницы-буфера,в которую или
из которой читаются или пишутся данные при
работе с диском.Значение должно иметь вид:
#0x7f-номер_желаемой_страницы.
Operation- номер операции. Нас больше
всего будут интересовать две операции: 5 -
чтение блока секторов, 6 - запись блока
секторов.
Blocks- количество считываемых секто─
ров.
Sector - начальный сектор, с которого
пойдёт считывание или запись.
Track - начальная дорожка, с которой
пойдёт считывание или запись.
Begin_page- адрес в странице PG, начи─
ная с которого в памяти будут размещены
данные с диска или с которого эти данные
начнут считываться(32768+смещение внутри
страницы).
Всё достаточно просто, но для ещё боль─
шего удобства вadditions.h есть другая
функция:
void load_file
(u8 *filename,u8 page,u8 saveload)
Filename- указатель на буфер, хранящий
имя файла на диске (т.е. строка).
Page- номер страницы, в которую писать
или из которой читать данные.
Saveload- операция: 1 - чтение, осталь─
ные значения - запись (не создаёт файл, он
должен быть на диске).
Функцияload_file читает нулевую дорож─
ку диска в страницу-буфер, указанную в
dospage, затем пробегает по полученным
файловым записям и ищет в них вхождение
имени искомого файла. А затем производит
чтение или запись при помощи функцииDOS.
Чтобы вставить свои файлы в финаль─
ный образ и дать свежескомпилированной
программе к ним доступ, нужно открыть
compile.bat и после строчки
call ..evosdk_compile.bat
вставить строку такого вида:
call trdtool.exe + %output% filename.0
гдеfilename - имя файла, который вы хоти─
те добавить в образ.
Пару слов о дополнительных функциях
вывода текста, которые были добавлены в
additions.h.
Для вывода отдельных символов есть фун─
кции:
void put_char_xy
(u8 n, u8 x,u8 y,u8 pcharmask)
Выводит на экран символn по координа─
тамx,y. Параметр pcharmask указывает спо─
соб рисовки символа:
-если pcharmask=0,то символ рисуется
без учёта прозрачного цвета;
-еслиpcharmask=1,то символ рисуется с
маской (номер прозрачного цвета указывает─
ся черезdraw_tile_key()).
void put_char(u8 n)
Выводит символ для функцииput_str(),
требует заранее устанавливать глобальные
переменныеoutput_x, output_y и pcharmask.
Перед использованием этих функций также
следует выбрать в качестве текущей тайло─
вой карты карту со шрифтом (через вызов
select_image() ).
Для вывода текста по строкам следует
использовать функцию:
void put_str(u8* str,u8 fnt)
Где str - указатель на строку, которую
следует вывести, аfnt - номер изображения
со шрифтом.
Перед использованием следует установить
глобальные переменныеoutput_x, output_y и
pcharmask. Символ'^' используется так же,
как и нуль-терминатор,на этом символе фун─
кция прекратит вывод строки.
Эти функции понимают русский и англий─
ский текст (кодировка зависит от кодировки
в вашем исходнике и вашего шрифта, у меня
CP866 ). В архивеevosdk_3_4_0_hippiman.7z
помимо дополнительных хедеров можно найти
графический файл font.bmp, который можно
использовать как заготовку для своих шриф─
тов. Я думаю,понятно, что для работы текс─
товых функций в проект должно быть загру─
жено это изображение или производные от
него.
В общем-то, и всё. По Evo SDK я описал
самые коварные моменты,всё остальное легко
разбирается по документации SDK. Также как
хороший пример можно разобрать исходники,
которые идут в комплекте со средой.
А для тех, кто не умеет писать наC,на
Evo SDK свет клином не сошелся - есть ещё
множество сред разработки как с программи─
рованием, так и без. Главное, чтобы было
желание, идеи и вдохновение,остальное при─
ложится. Дерзайте!
Other articles: