Scenergy #02
31 декабря 1999

Coding - Принцип упаковки анимаций в демо JAM.

<b>Coding</b> - Принцип упаковки анимаций в демо JAM.
         Упаковка анимаций в JAM

 В данной  статье  будет  рассмотрен метод
упаковки анимаций, примененный в последней
деме  Digital  Reality - JAM (2-е место на
CC'999).

 Если  Вы уже видели это demo (а я надеюсь
что  видели),  то  вы  понимаете  о  каких
анимациях идет речь.

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

 В последнее время  использование анимации
как   части   демы  становится  все  более
популярным.  Однако,  как   правило,  люди
используют  т.н. chunk'овые анимации, т.е.
анимации  в разрешении 64x32 или 64x48 при
16 градациях яркости и размере "точки" 4x4
пикселя.  Согласен,  это  неплохо.  Но  со
временем  начинает  надоедать. Кроме того,
подобный   тип   анимаций   совершенно  не
подходил   для   реализации  наших  планов
относительно   JAM'а   -  нам  нужны  были
анимации именно в планарном режиме, т.е. в
разрешении  256x192  и в 2 цветах т.к. все
равно  танцующие  фигуры  должны были быть
силуэтными.  Кроме  этого  было необходимо
соблюсти еще несколько критериев:

 - Максимально возможная степень упаковки.
 - Максимально    высокое   быстродействие
   распаковщика/плеера.   Фактически  было
   необходимо  распаковывать кадр анимации
   со скоростью 50 или 25 fps.

 Сразу  скажу  что то, что удалось сделать
при  написании  JAM в полной мере отвечает
описанным  выше  требованиям. Судите сами,
вот  статистика  реальных  данных из нашей
демы:
Количество анимаций: 14
Суммарное количество кадров: 686
Объем распакованных данных: 1,585,314 байт
Объем упакованных данных: 162,517 байт
Степень сжатия: 10.25%

 При  этом  анимации  дополнительно  можно
ужать  HRUST'ом  еще  где-то  процентов на
20-30,  т.е. 2.5 стандартных TR-DOS'овских
диска  анимаций  с  легкостью уместились в
100 с небольшим килобайт. Кроме того, могу
сказать,  что  если  бы  у нас было больше
времени,  то  можно  было  бы добиться еще
большего  качества  сжатия использовав две
дополнительные фичи:

 - Упаковка кадров анимации с учетом того,
   что  кадры образуют последовательность,
   т.е.   реально   паковать  не  кадры, а
   различия  между  ними. В JAM'е же из-за
   недостатка   времени   был  использован
   плеер, играющий  анимации сжатые только
   как  набор независимых кадров. Однако в
   упаковщике этот режим поддерживается, и
   я  могу  сказать,  что выигрыш при этом
   получается  небольшой  (всего несколько
   процентов).

 - Дополнительная  обработка   кадров  для
   сглаживания контуров изображения. Из-за
   того,   что   кадры  анимации  для  JAM
   вырезались вручную,  их края получились
   достаточно неровными что соответственно
   снижает качество упаковки.

 Прежде   чем  перейти  непосредственно  к
описанию   алгоритмов   сжатия   я  должен
сказать огромное спасибо Дмитрию Пьянкову,
автору таких известных программ как HRUST,
HRUM   и  Laser  Compact.  Он  оказал  мне
неоценимую  помощь  в  разработке  формата
упакованных данных, и именно благодаря его
советам   и   рекомендациям   мне  удалось
добиться такого качества упаковки.

 Итак, прежде всего определимся с тем, что
именно мы хотим получить в результате. Нам
необходимо  упаковать изображение. Причем,
поскольку  данный  алгоритм разрабатывался
для  упаковки  строго  определенных  видов
изображений  и  учитывает их специфику, то
необходимо  описать,  в  чем  состоит  эта
специфика. Итак, изображение которое будет
паковаться наилучшим образом, должно быть:

 - Планарное,  т.е. его  формат аналогичен
формату    стандартного    Спектрумовского
экрана,  где  1  байт представляет собой 8
последовательных пикселов на экране.

 - Силуэтное.   Изображение   представляет
собой  сплошной силуэт некоторой фигуры (в
случае   с   JAM   это  фигура  танцующего
человека).   В   идеале   этот  силуэт  не
содержит внутренних отверстий и полутонов.
Т.е.  сканированные изображения, конверсии
выполненные  с использованием dithering'а,
изображения  с  большим количеством мелких
деталей  и  пиксельным  "мусором" и прочие
изображения  подобного  рода  будут жаться
плохо.

 - Одиночное,  т.е.  в   кадре  изображена
только   одна   фигура  или  несколько  не
связанных    между    собой   фигур.   Под
отсутствием  связи  здесь  подразумевается
то,   что   в   каждом  байте  изображения
находятся  части  только  одной  фигуры. К
связанным  частям  также  относятся близко
расположенные   части   невыпуклой  фигуры
(например,  ноги человека стоящего прямо).
Для лучшего понимания того о чем идет речь
посмотрите на приведенные ниже картинки.







  Фигуры не связаны      Фигуры связаны

 Это, конечно, не обязательное условие, но
его соблюдение улучшит качество паковки.

 Теперь, когда мы разобрались с тем, какие
изображения   будут  паковаться  наилучшим
образом  при использовании данного метода,
необходимо  определиться еще с двумя очень
важными составляющими, которые, по сути, и
определяют  формат  упакованных  данных, а
значит  и  алгоритм  упаковки.  Это способ
перекодировки    изображения    и   способ
кодирования упакованных данных.

 Под  перекодировкой  изображения  я здесь
подразумеваю то в какой последовательности
будут   обрабатываться   байты   исходного
изображения.
 Для  того  типа  изображений, которые  мы
собираемся   сжимать,  подходят  3  метода
перекодировки:
 1) Изображение представляет собой обычный
Спектрумовский  экран. Плюс этого метода в
том,   что   при  распаковке  не  придется
заниматься  расчетом  экранного адреса при
помещении   распакованного   байта  т.к. в
памяти  байты  распакованного  изображения
будут  расположены последовательно. Однако
при  использовании  данного  метода  можно
будет  сжимать только изображения размером
с  целый  экран,  что  делает  этот  метод
неприменимым.

 2) Изображение представляет  собой спрайт
с  кодировкой  по  строкам:

                   0123
                   4567
                   89AB
                   CDEF

 Это   позволит   снять   ограничение   на
фиксированный размер анимации. Кроме того,
при   данном   методе  пересчет  экранного
адреса при распаковке необходим только при
переходе  к  следующей  строке экрана, что
экономит время распаковки.
 3) Изображение представляет  собой спрайт
с кодировкой по столбцам:

                   048C
                   159D
                   26AE
                   37BF

 Этот  метод  имеет  самый  высокий расход
времени  на  пересчет  экранного  адреса -
расчет  производится  для  каждого  байта.
Однако   этот  метод  имеет  одно  большое
преимущество  перед  остальными  методами.
Оно обусловлено спецификой Спектрумовского
экрана.  Как  вы  знаете - экран Спектрума
состоит  из  знакомест.  Каждое знакоместо
выглядит   на   экране   как  квадрат  8x8
пикселов. Однако в памяти это отнюдь не 64
байта,  а  всего  8  байт  т.к. 1 точке на
экране  соответствует  отдельный бит, а не
байт.  Извиняюсь  за  то,  что говорю всем
известные вещи, но это важно для понимания
сути.  Так вот, если посмотреть на то, как
расположены байты составляющие знакоместо,
то   мы   увидим,   что   они  расположены
вертикально.  Т.е.  если  расположить их в
памяти   последовательно,  то  вероятность
того,  что  эти байты  образуют однородную
последовательность  (которая, естественно,
хорошо  пакуется) намного выше, нежели при
использовании    последовательности   байт
образующих  горизонтальную  линию. А такую
последовательность   байт   мы  как  раз и
получим  в  случае перекодировки исходного
изображения  в вид спрайта с кодировкой по
столбцам.  Забегая  вперед, скажу, что при
использовании    этого   метода   качество
паковки  анимаций из JAM возрастает аж в 3
(в  три)  раза!  Так  что  ради  подобного
увеличения  качества  сжатия стоит принять
определенные    неудобства,   связанные  с
необходимостью пересчета экранных адресов.

 Как  вы  понимаете  - лучше всего выбрать
3-й метод, хотя паковщик  также, на всякий
случай, поддерживает и 2-й метод.

 Теперь   давайте   разберемся  со  второй
составляющей - способом кодирования данных
при паковке.
 Как  Вам  наверняка известно - существует
множество  методов упаковки данных. Однако
все   методы   дающие   высокое   качество
паковки  нам  в  данном случае не подходят
т.к.  они  используют хранение упакованных
данных  как  битового потока, а операции с
битами  на  Спектруме  -  вещь  достаточно
медленная и не соответствует требованиям к
скорости распаковщика.

 "Мы пойдем другим путем!" (c) В.И.Ленин
 
 Для  увеличения  скорости обработки будем
хранить   упакованные   данные  как  набор
байтов.  Соответственно упакованный кадр у
нас  будет представлять собой набор блоков
данных следующего формата:

+0 [byte] Тип операции.  В этом  же  байте
          для экономии места будем хранить
          дополнительные флаги.
+1 [data] Длина последовательности.
+n [data] Дополнительные данные.

 Естественно,  что  все данные кроме байта
типа  операции  могут  менять  размер  или
вообще отсутствовать.
 Необходимо  также выбрать набор операций,
которые будут использоваться распаковщиком
для восстановления упакованного кадра.
 Исходя  из специфики изображения, которое
мы   собираемся   паковать,  были  выбраны
следующие  типы  операций  (в скобках даны
названия   этих  операций  используемые  в
дальнейшем):
 - Пропуск группы байт (Skip).
 - Инверсия группы байт (Inverse).
 - Заполнение группы байт определенным
   значением (Fill byte).
 - Заполнение группы байт значением #FF
   (Fill #FF).
 - Заполнение группы байт значением #00.
   (Fill #00).
 - Помещение в память спец. байта.
   (Spec. byte).
 - Помещение в память последовательности
   байт (Sequence).
 Некоторые  пояснения  по поводу выбранных
типов операций.

 Операции  "пропуск"  и  "инверсия" группы
байт применимы только в случае, если кадры
анимации  пакуются  с  учетом  предыдущего
кадра. Но распаковщик использованный в JAM
поддерживает  распаковку только независимо
упакованных  кадров  и  поэтому эти 2 типа
операций по сути не нужны. Однако с учетом
того, что в будущем можно будет написать и
распаковку   последовательности  кадров  -
пришлось ввести и реализовать и эти 2 типа
операций.

 Заполнение  группы  байт значениями #00 и
#FF  вынесены  в отдельные операции исходя
из  специфики  пакуемого  изображения т.к.
именно   эти  значения  будут  встречаться
наиболее часто.
 Операция "Помещение в память спец. байта"
тоже введена исходя из специфики пакуемого
изображения.   Дело   в  том,  что  байты,
образующие   границу   силуэтного  объекта
будут  также встречаться достаточно часто.
А   ведь   всех  возможных  значений  этих
байтов для изображения, специфика которого
была оговорена в начале статьи, всего 16:
         %01      %10
         %011      %100
         %0111      %1000
         %01      %10
         %0001      %1110
         %001      %110
         %01      %10
         %1      %0
 Таким  образом,  вынесение  этих байтов в
отдельную  операцию позволит избавиться от
операции   "Помещение   последовательности
байт",   которая  применялась  бы  к  этим
байтам и в результате мы получим выигрыш в
размере упакованного изображения.

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

 При  паковке  кадров зачастую встречается
ситуация, когда есть две хорошо пакующиеся
последовательности разделенные всего одним
байтом. Типичный пример - граница объекта.
Мы  имеем  последовательность  #FF,  затем
байт границы объекта и за ним идет большая
последовательность   #00.   Соответственно
байт на границе объекта будет упакован как
последовательность  из  1 байта, что очень
неэкономично.  Поэтому для каждой операции
вводится  дополнительный флаг, сохраняемый
в  0-м  бите байта типа операции - признак
того,  что  после выполнения этой операции
необходимо будет поместить в кадр еще один
байт,  значение  которого  записано  сразу
после  данных для этой операции. Есть одно
исключение из этого правила - для операции
помещения   последовательности  байт  этот
флаг отсутствует т.к. не имеет смысла.

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

 Теперь,  когда все типы операций описаны,
перейдем к описанию еще одной очень важной
вещи - способа кодирования  длины пакуемой
последовательности.

 Нам  необходимо иметь возможность задания
большого  размера  последовательности  при
использовании   по   возможности  меньшего
объема   данных.  Дима  Пьянков  предложил
следующий метод:
 Под  каждую  операцию отводится некоторое
определенное количество кодов. Допустим на
операцию  заполнения  байтом #FF отводится
50 кодов  начиная с кода 80. Отняв от кода
операции значение начального кода операции
(в  данном  случае - 80)  мы получим длину
последовательности. Бит 0 содержит признак
того,  что после операции необходимо будет
сохранить  дополнительный байт данных. Так
что всего мы имеем 50/2=25 различных кодов
длины    последовательности.  Назовем  это
лимитом длины.

 Итак,  мы имеем длину последовательности.
Сначала  проверяем  -  если  эта  длина не
равна  0,  то  это  и  будет  длина, иначе
реальная длина хранится в следующем байте.
Берем этот байт и проверяем - больше ли он
лимита длины этой операции (в нашем случае
25)?  Если  больше  - то это и есть длина.
Если  же  нет  -  то это лишь старший байт
реальной  длины,  а  младший байт хранится
в следующем байте данных.
 Таким  образом,  данный метод кодирования
при  лимите  длины  N  позволяет создавать
последовательности  с длиной до N*256+255.
Например,  для  нашего случая (лимит длины
равен  25) размер последовательности может
быть  вплоть до 25*256+255=6655 байт, т.е.
даже больше чем размер экрана!

 Лимит  длины  для  каждой операции свой и
зависит  от  того,  сколько кодов отведено
для кодирования этой операции. Т.к. каждая
операция  имеет свою вероятность появления
при  паковке  кадра, то и количество кодов
выделенных  для  них различно. Вот таблица
распределения  кодов  между  операциями. В
JAM'е  была  использована  немного  другая
таблица,  однако  внесенные мной изменения
в   результате   дали  повышение  качества
упаковки для тестовой анимации на 3%
   ┌─┬─┬─┐
   │   Тип    │ Стартовый │Количество│
   │ операции │    код    │  кодов   │
   ├─┼─┼─┤
   │Skip      │   0 (#00) │ 32 (#20) │
   │Inverse   │  32 (#20) │ 16 (#10) │
   │Fill byte │  48 (#30) │ 32 (#20) │
   │Fill #FF  │  80 (#50) │ 50 (#32) │
   │Fill #00  │ 130 (#82) │ 50 (#32) │
   │Spec. byte│ 180 (#B4) │ 32 (#20) │
   │Sequence  │ 212 (#D4) │ 43 (#2B) │
   │End marker│ 255 (#FF) │  1 (#01) │
   └─┴─┴─┘

 Ну и, как обычно, есть пара исключений из
правила:
1) Для операций  Fill #FF и Fill #00 длина
последовательности  в 1 байт не требуется,
т.к.  ее  можно  закодировать помещением в
кадр соответствующего спец. байта. Поэтому
лимит  длины для этих операций увеличен на
1  за  счет  того, что реально хранится не
лимит, а лимит-1.
2) Для End marker лимит длины не задается.

 Еще  пару  слов скажу о формате файла для
хранения анимаций. Вообще-то их 2 - формат
для хранения отдельного упакованного кадра
и непосредственно анимации.

Формат для хранения отдельного кадра (ZXF)

+0 [data] 'ZXF' (ZX Frame). Сигнатура,  по
          которой можно  определить формат
          файла.
+3 [byte] Версия  формата  файла.  Наличие
          этого  байта позволяет без труда
          определить формат файла, который
          может  со  временем меняться. На
          данный   момент  текущая  версия
          формата - #01.
+4 [byte] Байт  флагов.  Содержимое  этого
          байта  позволяет  определить тип
          упаковки который был использован
          для  этого  файла и использовать
          соответствующий плеер.
          Подробнее   о  значении  каждого
          флага см. ниже.
+5 [byte] X  координата   левого  верхнего
          угла окна для вывода кадра.
+6 [byte] Y  координата   левого  верхнего
          угла окна для вывода кадра.
+7 [byte] Размер кадра по X.
+8 [byte] Размер кадра по Y.
+9 [data] Упакованные данные.

 Следует  заметить, что т.к. этот алгоритм
упаковки  работает  с  последовательностью
байт,  то X координата и размер по X будут
всегда  кратны  знакоместу. Соответственно
эти параметры задаются в знакоместах. Т.е.
значение  X  координаты равное 5 означает,
что  левый  верхний угол окна вывода кадра
расположен  начиная с 5 знакоместа, а не с
5 пикселя экрана. То же самое и с размером
по   X.  Соответствующие  параметры  для Y
задаются в пикселях.



    Формат для хранения анимации (ZXA)

+0 [data] 'ZXA' (ZX Animation). Сигнатура,
          по   которой   можно  определить
          формат файла.
+3 [byte] Версия  формата  файла.  Наличие
          этого  байта позволяет без труда
          определить формат файла, который
          может  со временем  меняться. На
          данный   момент  текущая  версия
          формата - #01.
+4 [byte] Количество кадров в анимации.
+5 [byte] Байт  флагов.  Содержимое  этого
          байта  позволяет  определить тип
          упаковки который был использован
          для  этого  файла и использовать
          соответствующий плеер.
          Подробнее   о  значении  каждого
          флага см. ниже.
+6 [data] Таблица  смещений  начала данных
          каждого кадра анимации. За точку
          отсчета  смещений берется первый
          байт упакованных данных. Так что
          смещение  первого  кадра  всегда
          будет нулевым.  Размер  таблицы:
          2*(+4)  байт, где (+4) - байт по
          смещению +4 от начала файла.
+n [data] Упакованные кадры анимации.  Они
          располагаются  последовательно и
          их формат аналогичен формату ZXF
          приведенному выше за исключением
          отсутствия  сигнатуры  и  версии
          формата, а также байта флагов.
           Прибавив  адрес  первого  байта
          данных  этого  раздела к каждому
          элементу в таблице смещений (+6)
          мы получим таблицу указателей на
          каждый кадр анимации.


 Как  следует  из  описания формата - этот
формат  не  позволяет  хранить  больше 255
кадров  анимации  или  создавать  анимации
размером  больше 65535 байт. Но для Speccy
это в самый раз.
 Кто-то еще может указать на то, что здесь
тратится,  по сути, без дела целых 4 байта
на  хранение  сигнатуры  и версии формата.
Но, если подумать, то можно понять, что за
потерю  4  байт  мы  получаем  возможность
точно идентифицировать формат файла. Та же
BestView  "зная"  формат  файла этого типа
для  каждой  версии сможет получить точную
информацию  о  его  содержимом.  А в самом
demo   можно   будет   хранить   маленький
менеджер,  который  по  заголовку  формата
сможет  определять  -  какой  плеер  нужно
использовать   для   этой  анимации  и  не
потребуется  каждый  раз  лезть  в код при
изменении файла анимации.
 Теперь  подробнее о значении каждого бита
в байте флагов:
 На данный момент  определены значения для
следующих битов:
 Bits 0..2 - указывают   тип   плеера  для
данной  анимации.  Содержимое  этих  битов
определяет, какой плеер нужно использовать
для проигрывания этой анимации.
 Возможные значения:
000 - Обычный плеер.
001 - Чересстрочный  плеер.  Отличается от
      обычного  тем,  что выводит анимацию
      не на каждую строку, а через одну. В
      упакованной   анимации  единственным
      отличием  данных от нормальных будет
      то,  что  сохраняются  только четные
      или только нечетные строки исходного
      изображения  в  зависимости от того,
      какое  значение  имеет  Y координата
      левого верхнего угла этого кадра.
010 - C64  плеер.  Этот  плеер  использует
      метод  вывода изображения, который я
      впервые  увидел  на  C64. Этот метод
      был  впервые  применен  мной  в деме
      Binary  Love (в начале второй части,
      где  вращаются  кубики).  Этот метод
      дает эффект "разорванности" картинки
      на  экране  и, кроме того, позволяет
      обсчитывать  изображение  в  4  раза
      меньшее,  чем изображение на экране.
      Соответственно единственным отличием
      упакованных  данных  будет  то,  что
      исходное  изображение будет сжато по
      X и по Y в два раза.
 Значения  011..111  на данный момент пока
не определены и зарезервированы.
 Хочу  заметить  что,  по сути, эти методы
отличаются  только  размером  изображения,
поэтому  они взаимозаменяемы и любой плеер
сможет  проиграть анимацию для любого типа
плееров.  Естественно  только,  что  после
распаковки   другим   плеером  изображение
будет выглядеть сжатым/растянутым.

 Bit 3 - способ перекодировки изображения.
Если  этот бит сброшен - кадры упакованы с
перекодировкой  по  строкам, если этот бит
установлен - то использована перекодировка
по столбцам. Об этих методах перекодировки
я  уже  писал  выше.  Скажу  также, что на
данный  момент существует только плеер для
анимаций с перекодировкой по столбцам. Это
связано  с  тем,  что,  как я уже говорил,
этот  метод  дает  намного большую степень
упаковки.  Однако  любой  плеер  можно без
проблем  переделать  под использование для
анимаций с перекодировкой по строкам.

 Bit 4 - способ сжатия  последовательности
кадров.  Если  этот  бит равен 0, то кадры
анимации  сжимались  с  учетом предыдущего
кадра.  Т.е.  перед  тем  как сжать кадр -
он накладывается по XOR на предыдущий кадр
и  пакуется  результат этой операции. Если
же  этот  бит  равен 1 - то кадры анимации
упакованы  независимо, каждый сам по себе.
Необходимо также учитывать тот момент, что
у кадров, упакованных с учетом предыдущего
размер окна распаковки, положение и размер
которого   записаны  в  заголовке  каждого
кадра,  будут  различными.  Для независимо
упакованных  кадров  окно распаковки будет
одинаковым для всех кадров.
 На  данный  момент  есть плеер только для
независимо упакованных кадров. Это связано
с тем,  что существующий алгоритм депакера
эффективен только для таких анимаций.
 Необходимо  также  заметить, что значение
этого бита определено только в ZXA файлах,
для ZXF файлов этот бит неопределен.
 Остальные  биты  в  этом флаге для данной
версии   формата  неопределены  и  поэтому
всегда сброшены.

 Ну  вот,  на  основании  всех этих данных
каждый  сможет написать набор процедур для
упаковки   и   распаковки   анимаций.  Вся
необходимая информация для этого описана в
этой статье.
 Но это не все. Кроме того, для того чтобы
вам  легче было разобраться со всем этим и
не тратить время (которого нам всем всегда
не  хватает)  на то чтобы написать все это
самим   -   я  отдаю  вам  для  изучения и
использования   свою  библиотеку  работы с
этими анимациями - ZXA library.
 Подробно  использование  компонентов этой
библиотеки описано в статье ZXA library, к
которой я вас сейчас и отсылаю.



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

A.O.S.S. - "Сцена больна" переживания Random'a.

A.O.S.S. - Raver рассуждает о сценовой журналистике.

A.O.S.S. - аналитическая статья о музыкальной сцене от Andy Fer.

A.O.S.S. - легко ли быть органайзером группы?

A.O.S.S. - О журналах (мысли вслух).

A.O.S.S. - о канонах демосцены на примере журнала Deja Vu #9.

A.O.S.S. - Сегодня и Завтра отечественной демосцены.

A.O.S.S. - спектрумовская банерная сеть.

Charts - all time favorites.

Charts - current rules (fall edition 1999).

Charts - indexed.

Charts - voting rules.

Coding - 16-битная процедура быстрого возведения в степень.

Coding - Flying представляет макробиблиотеку: Memory Management Library.

Coding - Texture Mapping - реализация от SaiR00S/EI.

Coding - Texture mapping + Phong shading реализация от Senat/Eternity Industry.

Coding - ZXA library: библиотека, предназначенная для создания и проигрывания анимаций.

Coding - Баг в STS?

Coding - Комментарии к исходникам, опубликованным в Scenergy #1

Coding - о библиотеках в программировании на спектруме.

Coding - Принцип упаковки анимаций в демо JAM.

Coding - процедура быстрого умножения.

Coding - разбор интро Daingy от Cryss/Razzlers.

Demo Party - Cafe'2000: Официальное приглашение

Demo Party - CC999.999 information (eng).

Demo Party - D-Man/EI: отчет о Di:Halt:99.

Demo Party - Hartman: отчет о CC'999.

Demo Party - Maxwell и Mr. John: отчет о CC'999.

Demo Party - Merlin/CC: отчет о CC'999.

Demo Party - Paradox'99 - как это было, но лучше б он mUst dIe!!!

Demo Party - PHAT'9: список посетителей.

Demo Party - POL/PHT: отчет о Doxycon '99.

Demo Party - Random/CC: обьемный отчет о CC'999.

Demo Party - SerzhSoft: сказание о CC'999.

Demo Party - Zlincon 2e3 party: минирепортаж.

Demo Party - информация о предстоящем пати PHAT'0.

Demo Party - информация по демопарти CC999.999.

Demo Party - неофициальные результаты Di:Halt'99 с коментариями Diver'a.

Demo Party - обзор демосцены за 1999 год.

Demo Party - отчет организаторов CAFe'99.

Demo Party - пресс релиз Латвийского демопати PHAT'9.

Demo Party - приглашение на латвийское демопати PHAT'9.

Demo Party - рассказ о поездке Antares в Казань на CAFe'99

Demo Party - результаты CC.999.999

Demo Party - результаты CC999.999.

Demo Party - результаты Chaos Construction 999.

Demo Party - результаты Computer Art Festival 1999.

Demo Party - результаты Doxycon'99.

Demo Party - результаты Millenium Party.

Demo Party - результаты Paradox'2k demoparty.

Demo Party - результаты Латвийского демопати PHAT'9.

Demo Party - результаты Ростовского пати Paradox'99.

Demo Party - репортаж Gasman'a с Forever 2e3.

Demo Party - репортаж с Минского демопати Millennium'2000.

Demo Party - финальные результаты Forever 2E3.

Editorial - вступительное слово от Arty.

Editorial - выступительное слово от Random.

Editorial - загоны Raver'а на тему Сцены.

Groups - анкеты действующих групп: Amaltiya Incoropration Software.

Groups - анкеты действующих групп: Antares.

Groups - анкеты действующих групп: Ascendancy Creative Labs.

Groups - анкеты действующих групп: Crushers.

Groups - анкеты действующих групп: E-mage.

Groups - анкеты действующих групп: Eternity Industry.

Groups - анкеты действующих групп: Excess team.

Groups - анкеты действующих групп: Extreme Entertainment.

Groups - анкеты действующих групп: Fatality.

Groups - анкеты действующих групп: Jupiter 77.

Groups - анкеты действующих групп: Proxima Centauri.

Groups - анкеты действующих групп: RaZZLeRs.

Groups - анкеты действующих групп: RUSH.

Groups - анкеты действующих групп: Smash Hackers Band.

Illegal Corner - Razzlers оправдываются за релиз демки First Association.

Illegal Corner - Scenergy Release Charts - конкурс крэков.

Illegal Corner - Welcome to Scenergy Release Charts (SRC).

Illegal Corner - софтография Fatality Group.

Lits - Pussy: история создания знаменитой игры от Fatality.

Lits - Scenergized beyond the belief.

Lits - speed.

Lits - история образования Ростовской ассоциации PartyZans.

Lits - история создания игры "Белый орел - товарищ известен".

Lits - рассказ о том как Fatality выпускает игрушки.

Mail Box - письма: Ellvis и Fatality довольны Scenergy #1, Ulterior поносит Antares и BrainWave, Realtimer разочарован.

News - Doom'a не будет!

News - Виртуальное пати Millennium, X-Raizor вернулся на сцену, Andrew Fer организовал новую группу, провал Германского пати Spectrology, новости от 3SC, Zero Team, Extreme.

News - мнение Megus'a о dentro compo СС'2000.

News - новости от OHG, Delta Hackers Group, Die Crupps, Волгодонских спектрумисто и от группы SpeedWay.

Scenergy - адреса для связи с редакцией.

Scenergy - благодарности соавторам журнала.

Scenergy - новое в облочке журнала.

Scenergy - обещанного видео в статьях не будет...

V.I.P. - Random берет интервью у Unbel!ever/Sage/XTM.

V.I.P. - The most noble tale of the scene.

V.I.P. - интервью с Arny и Mythos, создателями клона Elite игры Awaken.

V.I.P. - Интервью с Fatality, широко известными крэкерами и гейм-мэйкерами

V.I.P. - интервью с одним из авторов игры Elite.

V.I.P. - интервью с одним из самых прогрессивных художников на спектруме Diver/4D.

V.I.P. - Интервью, взятое у Random'а каким-то PC-журналом

Warez Pack - описание Inertia Player.

Warez Pack - описание демо 1140.

Warez Pack - описание импортной демки 'no work'.

Стрейч пленка оптом, свое производство. Выгодные цены.

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

Похожие статьи:
Chaos Constructions '999 - отчёт (продолжение).
Чемпионат - Чемпиопнат Европы по футболу - турнирные таблицы.
Кодерам - вариант организации работы с Дисководом.
Enlаit - нeсколько слов о 'NОnSense'.
Железо - Как избавиться от wait'а в компьютере "таганрог 128".

В этот день...   18 апреля