Info Guide #11
05 июля 2015

Игрушки - Разработка игр на Evo SDK (часть 1).

  Разработка игр на 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 умеет работать со спрайтами16x16px
(до 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 свет клином не сошелся - есть ещё 
множество сред разработки как с программи─
рованием, так  и  без. Главное, чтобы было
желание, идеи и вдохновение,остальное при─
ложится. Дерзайте!




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Размышления - Проект "Суперспектрум".
Тема ОС - Решились мы все-таки на организацию специального раздела для обсуждения темы, которая, несмотря на смелые заявления некоторых личностей,тем не менее очень волнует спектрумистов.
События, факты, комментарии - затопление станции "Мир", новые игрушки....

В этот день...   21 сентября