Info Guide #12
31 декабря 2017

Игрушки - квест "Неожиданное Путешествие" - взгляд изнутри.

 "Неожиданное путешествие"
"Неожиданное Путешествие" - взгляд изнутри 
STD

   Недавно на zx-pk.ru форумчанин из Пско─
ва  под  ником  STD  выложил  в общий дос─ 
туп  свою  текстово-графическую  адвентюру 
"Неожиданное  Путешествие", которая испол─ 
нена  в достаточно нестандартной манере на 
фоне  массы  современных игр, сделанных на 
AGD -движке. 
   Мы попросили автора рассказать о техни─
ческой части этой игры. 

                  * * *

   Необходимое лирическое вступление:
   Автор  сам прекрасно понимает, что соз─
данный  им  код топорный и деревянный, что
он  жрет  память  Спекки, как не в себя, а
также,что при просмотре листинга мастерами
уровня  Alone Coder и GoodBoy  они рискуют
заработать  глазное  кровотечение. Но. Мой
движок все-таки имеет одно достоинство. Он
вопреки всему работает! Так что рассматри─
вайте  его  и  эту статью как совокупность
неких идей,которые кто-то уже обдумал, как
исходный  материал для своего творчества и
совершенствования, будь на то ваша воля.

   Итак, что представляет собой "Неожидан─
ное Путешествие" с точки зрения программи─ 
ста и как там всё устроено?
   Движок программы мной написан полностью
на  ассемблере  и полностью в ZXASM - 100%
аутентичная разработка в2017 г., что дос─
тавило мне  много удовольствия уже само по
себе.

           Распределение памяти

   При  разработке игры  под  расположение
движка в  памяти  я отвел место с26000 по
32767(#7FFF), то есть до самого конца 2-го
окна памяти или всего около7 КБ. В дейст─
вительности  же  в  откомпилированном виде
движок  занял  4 с небольшим килобайта, но
менять я ничего не стал.

   С адреса 32768 (#8000) и до 37900 рас─
положен  буфер для обработки текущей сцены
игры. Таким образом, любая отдельно взятая
сцена  игры  не  может занимать более5123
байта памяти. О сценах подробнее далее.
   С адреса 37900  и до 38000 расположено
место  под  флаги в игре.1 флаг = 1 байт.
Таким  образом, в  игре  можно оперировать
сотней флагов.
   С 38000  расположен  буфер для вырезки
разных маленьких спрайтов. Я его использо─
вал  для вырезки и временного хранения ку─
сочков экрана, когда открывал окно "листо─
чки" (в  котором  игрок выбирал все дейст─
вия), т.к. оно имело не строго прямоуголь─
ную форму, ввиду чего стандартная заложен─
ная в программу  процедура сохранения гра─
фики под открываемым окном с ним не справ─
лялась.
   С адреса47000 хранится шрифт игры: 2КБ
в кодировке 866 до самого конца 3-го окна
памяти, то есть по49151 (#BFFF) включите─
льно.

   Как  видно, с  адреса38000 до 47000 аж
целых 9 КБ  места. Для  вырезки маленьких
спрайтов столько, конечно, не надо. Да так
уж получилось, что такая дырка осталась.

   С адреса 49152  (#C000), как  известно
даже  малышам, начинается 4-е окно памяти,
куда на128K можно подключать банки (стра─
ницы) памяти0,1,3,4,6,7. Их я использовал
следующим образом:
  Страница 0 - в неё всегда грузятся бло─
ки сцен, т.е. собственно текстовые файлы с
описанием локаций,команд и т.д.В моей игре
на  диске  они имеют именаblsc00, blsc01,
blsc02, ... blsc13.
  Страница 1 - в неё грузятся блоки спра─
йтов, которые игрок видит в окне "фотогра─
фии" и которые сопровождают показ текстов.
На диске это файлыblsp00 ... blsp05.
  Страница 3 - в неё  грузятся  отдельные
спрайты, нужные для игры (скрепыш, медаль─
ка в окне достижений, мем "мудрый старик",
дискета  "сохранить" и "листочки" для окна
выбора действия"). Все они хранятся в фай─
леgfx00.
  Страница 4 - с адреса  #C000 в ней хра─
нится  главное меню игры, с адреса57000 -
основной  игровой  экран (собственно блок─
нот, ручка, фотография).
  Страница 6 - не используется.
  Страница 7 - отведена под буфер для со─
хранения  содержимого экрана под открывае─
мым окном. Процедура сохранения может сох─
ранить последовательно до4 открытых окон.
Программисту об адресах, куда именно это в
пределах  данной страницы сохраняется, ду─
мать не надо.

        Принцип построения движка

   Движок можно разделить4 логически обо─
собленные части.

  1.Часть инициализации.
   Начиная  отORG 26000 и до метки GLV00.
Этот кусок кода работает только при первом
запуске программы, выводит на экран заста─
вки, инициализирует  внутренние переменные
программы,грузит шрифт и загружает в стра─
ницу0 первый текстовой файл с первым бло─
ком сцен игры -blsc00.
   Поле этого движок переходит кп.2.

  2.Переброска текущей сцены в буфер об─
работки. 
   С меткиGLV00 до GLV02  небольшой кусо─
чек программы берёт из внутренний перемен─
ной движкаPOZGL (то есть ПОЗиция ГЛобаль─
ная) адрес начала конкретной сцены в блоке
сцен, которую  сейчас надо обрабатывать, и
перебрасывает  её  из этого адреса в выше─
указанный  буфер  текущей  сцены  на32768
(#8000). При этом одна сцена от другой от─
деляются маркером#FE. То есть в результа─
те работы этой части программы кусок памя─
ти  из  нулевой страницы с адресаPOZGL до
первого встреченного кода#FE будет переб─
рошен  в адреса  с32768 (#8000). При этом
этот кусок, как я уже писал,не должен быть
больше5123 байт, иначе он затрёт флаги!
   При  первом запуске программыPOZGL за─
носится#C000, поэтому  процедура GLV00...
GLV02  перебросит  в  буфер  самую  первую
(нулевую) сцену изblsc00.
   После того, как  программа встретит код
#FE, переброска сцены заканчивается. В пе─
ременную POZIC (т.е. текущая ПОЗИЦия) за─
носится число#8000, то есть встаём на на─
чало  буфера, куда  попала  обрабатываемая
сцена, и переходим кп.3.

  3.Обработка  текущей  сцены  или "блок
распознания управляющих кодов". 
   Начинается с меткиOSN00 и идёт до мет─
ки OSN34. В данном блоке  движок работает
90% времени.
   Из  переменной POZIC  берется  адрес в
буфере  обработки  текущей  сцены. Если мы
только начали обрабатывать сцену,это будет
#8000. Теперь  берём из этого адреса имена
команд и начинаем их сравнивать с команда─
ми, зашитыми  в данной части движка. Имена
всех  возможных команд зашиты в этом блоке
программы. Как  только  все три последова─
тельно  считанные из буфера буквы совпадут
с  тремя буквами какой-либо команды, заши─
тыми  в  этом блоке, то этот блок вызывает
из4-й части программы уже непосредственно
её обработчик. После обработки в4-й части
программы  и выполнения команды управление
вновь  возвращается сюда, переменнаяPOZIC
увеличивается (так как после команды обыч─
но  ведь идут её параметры, которые только
что  использовали, обработали, и теперь их
надо  пропустить) на столько байтов, чтобы
она начала указывать на следующую команду,
и управление  возвращается  в начало этого
блока.
   Если  в данном  блоке  попалась команда
"перейти к другой сцене", то  после её вы─
полнения  в переменнуюPOZGL будет занесён
адрес  этой сцены, к которой надо перейти,
и управление вернётся не в начало блока3,
а будет передано на блок2.

  4.Процедуры  обработки управляющих ко─
дов. 
   Если  блок 3 программы лишь распознаёт
команды  и после  распознания  вызывает их
обработчики, то в блоке4 содержатся имен─
но эти самые обработчики.
   То  есть  тут  находятся  все процедуры
"открыть окно","закрыть окно", "напечатать
спрайт","напечатать текст", "ждать нажатия
любой клавиши" и т.п.
   Больше, собственно, сказать нечего. Это
нижний уровень, сама основа программы.

                 Команды

   Для  реализации  своей  игры я придумал
следующие  команды, которых  мне хватило с
лихвой:

  WWN- устанавливает  параметры текущего
окна, с которым дальше будут  работать все 
процедуры окна; 
  WC1- очищает всё текущее окно целиком,
включая поле рамки; 
  WC2- очищает внутреннюю часть текущего
окна целиком, без поля рамки; 
  WCL- заливает текущее окно цветом;
  WRM- рисует в текущем окне рамку;
  WCT- вырезает  фон под текущим окном в
буфер. Можно  последовательно  сохранить 4 
окна! Вырезанный  фон  окон  помещается  в 
банк 7; 
  WST- полностью  рисует  текущее окно -
очищает его,заливает цветом,рисует рамку; 
  WPT- восстанавливает  сохраненный  фон
из-под окна из буфера. Процедура может по─ 
следовательно восстановить фон 4 окон, со─ 
хранных процедуройWCT;
  WN1- быстрая установка текущимИ ВЫВОД
окна игры 1 (т.е. собственно страница дне─ 
вника, где печатается весь текст); 
  W2O- быстрая установка, сохранение фо─
на и вывод спрайта окна "Листочки"-"выбора 
действия"; 
  W2С- быстрое закрытие окна "выбора де─
йствия"; 
  W3O- быстрая установка,сохранение фона
и вывод спрайта окна "помощь"; 
  W3C- быстрое закрытие окна "помощь";
  W4O- быстрая установка,сохранение фона
и вывод спрайта окна "достижение"; 
  W4C- быстрое  закрытие  окна "достиже─
ние"; 
  ";"- комментарий.Весь дальнейший текст
игнорируется до перевода строки; 
  "Enter"- знак  перевода строки игнори─
руется. Введено  для удобства редактирова─ 
ния; 
  BNK- "Включение выбранного банка памя─
ти. Байт  с  номером  страницы  памяти +48 
(т.е. просто текстовая цифра от 0 до 9)"; 
  PAU- ожидание нажатия любой клавиши;
  CLS- очищает экран;
  FDI- зажигает экран;
  FDO- гасит экран;
  LDF- загрузка файла по имени. Загрузка
происходит всегда  по адресу#C000и в тот 
банк  памяти, который в этот момент впеча─ 
тан в этот адрес командойBNK;
  TXT- команда печати текста. Имеет свои
собственные управляющие коды; 
  CSP- вырезка произвольного спрайта;
  PSP- печать произвольного спрайта;
  SP1- выводит  спрайт  с  номером от00
до16 из  блока спрайтов в окно "фотогра─ 
фии"; 
  JMP- безусловный  переход  к  сцене  с
указанным номером в текущем блоке сцен; 
  FON- включает  выбранный  флаг в блоке
переменных; 
  FOF- выключает  выбранный флаг в блоке
переменных; 
  JMF- переход  к сцене в зависимости от
того, включен выбранный флаг или нет; 
  VIB- переход на сцену в соответствии с
нажатием клавиш1-4,в окне "листочков"; 
  VIN- спецоператор в игре. Используется
единственный раз, для проверки,выполнил ли 
главный  герой все три задания, и если да, 
то перебрасывает его к горе ведьмы. 

   Этих  немудрёных  команд хватило, чтобы
написать игру. Скажу больше, из них всех в
95% случаев используется с десяток.
   Команды WN1,  W2O, W2С, W3O, W3C, W4O,
W4C  введены  для удобства набора сцен. Их
можно  было бы не вводить, но тогда выпол─
нение очень частых действий, типа открытия
и  закрытия окон "скрепыша", "листочков" и
т. д. приходилось бы выполнять серией опе─
раторовWWN, WC1, WCT, WST, WPT с парамет─
рами. Поэтому  я посчитал, что самые глав─
ные окна в игре можно обозначить собствен─
ными операторами и открывать, закрывать их
надо  по  "имени  собственному", например,
W2O/W2С. Раз - и всё!

           Строение блоков сцен

   Весь текст игры занимает порядка180КБ.
Он  разбит  на  файлы  размерами  до16КБ:
blsc00, blsc01, blsc02, ... blsc13.
   В  каждый  момент  времени в страницу0
может  быть  загружен  только один из этих
файлов.
   Внутри каждый файл состоит из отдельных
сцен, которые между собой разделены марке─
рами#FE.
   Каждая сцена состоит из команд для дви─
жка, параметров  этих  команд и текста для
игрока, который печатается на экране кома─
ндойTXT.
   Движок забирает из загруженного в стра─
ницу 0  блока сцен одну сцену (называемую
текущей) в буфер обработки текущей сцены с
адреса #8000 и в этом буфере последовате─
льно обрабатывает все её команды.
   Так как сцена обрабатывается в этом бу─
фере, а  не  в нулевой странице, то в ходе
выполнения этой текущей сцены находящимися
в ней командами можно спокойно переключать
банки памяти, грузить туда спрайты,грузить
другие  блоки  сцен  и  переходить на них.
Буфер был введён именно для этого.
   Ну  а теперь, для примера, кусок исход─
ного текста блока сцен. Как это выглядит в
игре, вы  видели, а  вот  как это выглядит
для её автора в Notepad++:

;Сцена  00 "Меню"
BNK 1 - включили банк 1
LDF blsp00 C - загрузили туда первый блок
               спрайтов
BNK 4 - включили банк 4
FDI 49152 - вывели оттуда картинку
            главного меню игры, которая
            туда уже была загружена
BNK 0 - вернулись к банку 0
FOF 03:FOF 04:FOF 05:FOF 06 FOF 07:FOF 08
FOF 09:FOF 10:FOF 11:FOF 12:FOF 13:FOF 14
FOF 15:FOF 16:FOF 17:FOF 18 FOF 19:FOF 20
FOF 21:FOF 22 - сбросили все флаги игры
JMP 01 - перешли на сцену 1
· - это #FE маркер конца сцены

;Сцена 01 "Меню"
VIB 3,02,06,03 - сцена состоит из одной
                команды: ждём, когда игрок
             нажмёт одну из трёх возможных
              клавиш: 1, 2 или 3,
               и соответственно переходим
                на сцены 2, 6 или 3.
·

;Сцена 02 "Вступление"
WWN 03,03,26,18,096,180,06,04
WCT:WST - этими командами мы вывели окно
          для вступления, сохранив фон под
          ним
TXT
 Здравствуй, мой юный друг!

Я не  знаю  кто ты,  а ты,  в
свою  очередь, не  знаешь, что
за книга у тебя в руках. И хо-
тя твоя личность для меня нав-
сегда  останется  тайной, свою
тайну я тебе открою.

Это -  Дневник.  Более того -
это ЖИВОЙ дневник, который со-
держит мои ЖИВЫЕ воспоминания.

Раз  ты держишь  его в руках,
значит я, наконец,спустя годы,
нашел время, чтобы записать те

PAU:WC2:TXT - ждём нажатия любой клавиши,
              очищаем и печатаем дальше...

                Заключение

   Мне кажется, что всё получилось в целом
очень  просто и весьма элегантно. Если ис─
пользовать  именно  такой интерфейс, как у
меня, то  игру в данном стиле, но со своим
сюжетом может, в принципе, разработать че─
ловек, вообще не знакомый ни с Бейсиком,ни
с ассемблером,просто в Notepad++ (конечно,
если  не  учитывать необходимость создания
блоков  спрайтов для "фотографий", которые
я также формировал  ассемблерными програм─
мами, и  необходимости изменения титульных
экранов). Но в целом, всё-таки...
   Безусловно, есть определённые шерохова─
тости  и нелепости даже в придуманных мной
командах. Уже в процессе набора сцен я по─
нял, что  пару  из них следовало бы весьма
изменить, но было набрано уже много игры,и
переделывать я не стал. Именно это обусло─
вило  наличие  в  ней многих "технических"
сцен, которые не видны игроку, но их приш─
лось вводить для того, чтобы правильно га─
сить окно диалога при ветвлениях сюжета.
   В целом меня весьма увлекла идея возмо─
жности  разработки действительно универса─
льного движка для такого типа игр, о чём я
уже писал на форуме. Мне кажется, это было
бы здорово, если бы на ZX-платформе появи─
лся  такой  продукт, который  бы  позволял
использовать разные шрифты, задавать пара─
метры своих окон, и прочая, и прочая,и всё
это - не  выходя за пределы Notepad++. Это
был  бы  наш  с вами  AGD - Адвентюре Гейм
Дисингер фром Раша виз Лав!8)

Всегда Ваш, STD. 



Другие статьи номера:

Помощь - об оболочке: произошли некоторые изменения в кнопках.

Предисловие - от авторов: Прошедшие два года были очень насыщенными.

Комьюнити - ZX Spectrum: Как это было в Рязани (1980-е).

Комьюнити - ZX Spectrum: Как это было в Рязани (1991-1993).

Комьюнити - ZX Spectrum: Как это было в Рязани (1993-1995).

Комьюнити - ZX Spectrum: Как это было в Рязани (1995-1997).

Комьюнити - сценеры шутят.

Код - этюды: вызов процедур по списку адресов.

Код - 3D демы на ZX Spectrum: история развития 3д движков.

Код - 3D движок: оптимизация на прообразе 3D Construction Kit.

Код - 3D движок: фрагменты.

Код - Посекторный движок для 3D-шутера от Destr.

Код - 3D скролл на ZX Spectrum (часть 1).

Код - 3D скролл на ZX Spectrum: реализация (часть 2).

Графика - графические редакторы: Старый софт от Alone Coder'а.

Графика - палитра: Палитровые эффекты в играх.

Музыка - биперные движки: Двоичная модуляция (часть 1).

Музыка - биперные движки: Двоичная модуляция (часть 1).

Системки - история операционной системы CP/M для Спектрума (часть 1).

Системки - история операционной системы CP/M для Спектрума: ограничения (часть 2).

Системки - NedoLang: Начало - самый простой процедурный язык (часть 1).

Системки - NedoLang: Путь к самокомпиляции (часть 2).

Системки - NedoLang: Проклятие языка Си (часть 3).

Системки - NedoLang: Памяти под самокомпиляцию не хватало (часть 4).

Системки - NedoLang: ускорение (часть 5).

Системки - NedoLang: Куда плыть дальше (часть 6).

Металлолом - Знакомьтесь, ATM-turbo 3! ATM-turbo 3 (v8.0) - что это такое и с чем его едят.

Металлолом - Из истории Betadisk'а: Дисковый интерфейс от Technology Research был.

Дикий ум - Компрессия: Первые компрессоры графики на Speccy (часть 1).

Дикий ум - Компрессия: Фичи с эвристикой, Потоковая декомпрессия, Сжатие музыки (часть 2).

Игрушки - От редакции: 2017-й год вышел очень богатым на события.

Игрушки - интервью с автором игры Mickey the Basic game (Sergio).

Игрушки - квест "Неожиданное Путешествие" - взгляд изнутри.

Игрушки - Nomad: интервью с автором скролл-шутера Nomad (Hippiman).

Игрушки - Скроллинг в Evo SDK.

Игрушки - Hints & Tips: Mickey, Nomad.

Мыльница - Errata: ошибки в Info Guide #11, ACNews #65.

Письма - отзывы о журнале от: raver, destr, sirx, survivor, Ellvis, Utz и Николая Амосова.

Об авторах - Авторы журнала.


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

Похожие статьи:
Почта - письма читателей: Николай Сергеев, Jobman, Николай Парфёнов, Дмитрий Залисский.
На досуге - об истории создания ZX-SPECTRUM, о ее триумфальном шествии по рынкам мира.
Вступление - Вступление от редактора.

В этот день...   21 июля