RUSH #01
29 мая 1999

Spectrum программинг - Современные методы кодинга и современные способы работы с графикой.

<b>Spectrum программинг</b> - Современные методы кодинга и современные способы работы с графикой.
 СОВЕРШЕННЫЕ МЕТОДЫ КОДИНГА И СОВРЕМЕННЫЕ
         СПОСОБЫ РАБОТЫ С ГРАФИКОЙ

    Год за  годом  на  SPECCY организуются
новые группы, пишутся программы. Это озна-
чает, что где-то появляются  все  новые  и
новые  музыканты,  художники  и конечно-же
программисты,  которые  стремятся  сделать
что-то  интересное,  доселе  невиданное  и
не  превзойденное.  Где-то  сидят  будущие
RST#7'ые, IMP'ы,  STALKER'ы... Изучают ас-
семблер, днями и ночами, вооружившись STS'
ом, разбирают по кирпичикам программы сво-
их предшественников.
    Чтобы помочь всем им, чтобы сэкономить
недели и месяци  которые  нам  приходилось
просиживать  за  листингами программ, то и
дело  отбиваясь  от вездесущих глюков, вы-
думывая то, что уже многим давно известно,
делая то, что еще недавно считалось невоз-
можным  и  подготовлен следующий материал.
В нем собраны  разноплановые советы по ко-
дингу, от совсем элементарных процедур, до
более сложных и эффективных.
    Предыдущий  вариант  этого  текста уже
однажды публиковался в электронном журнале
"Depth 1", который не получил достаточного
распостранения. Здесь же Вы видите его до-
полненный вариант.  Я собираюсь продолжить
данную тему в следующих  номерах, описывая
полезные процедуры и методы кодинга.

    Итак, перейдем собственно к теме...


1. Рассмотрим  наиболее часто используемые
методы вывода изображений на экран.

 а).Самый простой  способ вывести спрайт -
    перебрасывать   его    последовательно
    байт  за  байтом, строку  за  строкой.
    прорамма, выполняющая  такие действия,
    выглядит примерно так:

       LOOP1   PUSH    BC
               PUSH    HL
       LOOP2   LD      A,(DE)
               INC     DE
               LD      (HL),A
               INC     L
               DJNZ    LOOP2
               POP     HL
               CALL    DOWN_HL
               POP     BC
               DEC     C
               JR      NZ,LOOP1
               RET

      DE-адрес спрайта в памяти,
      HL-адрес в экране,
      B -ширина спрайта в знакоместах,
      C -высота спрайта в пикселях.
      DOWN_HL - переход на строку ниже.

 Данный способ,  несмотря на свою простоту
 и примитивность,  вполне подходит для вы-
 вода  статичной  (неподвижной)   графики.
 Изменив  входные  параметры  в  регистрах
 HL,DE,BC,  можно  вывести картинку любого
 размера в любое место экрана.   К сожале-
 нию, такая гибкость не  свойственна  всем
 остальным способам вывода графики.

 б). Выводить графику с фиксированной
     шириной.

    LOOP1   PUSH   DE
            LDI      ; колличество зависит
            ...      ; от ширины спрайта.
            POP    DE
            EX     AF,AF'
            CALL   DOWN_DE
            EX     AF,AF'
            DEC    A
            JR     NZ,LOOP1
            RET
     HL-адрес спрайта в памяти,
     DE-адрес в экране,
     A -высота спрайта в пикселях.

 Этот способ  несколько  быстрее  предыду-
 щего, но из-за  привязки  к  определенной
 ширине спрайта, менее распостранен.

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

     Адрес графики заносится в регистр SP,
     затем значения  со  стека  последова-
     тельно извлекаются  и заносятся в эк-
     ран. Примерно это будет выглдеть так:

     ...
     POP     HL
     LD      (#4000),HL
     POP     HL
     LD      (#4002),HL
     POP     HL
     LD      (#4004),HL
     ...

        Естественно, что адреса, в которые
     будет   бросаться   графика,  заранее
     фиксированы,  фиксирваны  также  раз-
     меры спрайта.  Длина полученой проце-
     дуры в  памяти  зависит  от  размеров
     спрайта,  и  будет в два раза большей
     чем он.   То есть, если вы перебрасы-
     ваете спрайт на  весь экран (6144б.),
     размер программы будет - 12288б.
         Такое   расточительство    вполне
     оправдано,  так как  скорость   рабо-
     ты этой программы  гораздо  выше  чем
     предыдущих.  Один байт перебрасывает-
     ся за 13 тактов.  Тем  более,  что до
     инсталляции программа  будет занимать
     всего каких-нибудь 100 байтов.

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

     ...
     LD      HL,(#4100)
     LD      (#4000),HL
     LD      HL,(#4102)
     LD      (#4002),HL
     LD      HL,(#4104)
     LD      (#4004),HL
     ...

     Абсолютно не  используется стек  и не
     изменяет регистры, за исключением HL.
     Использует на каждый  перебрасываемый
     байт  графики  по  три  байта памяти.
     Один  байт перебрасывается за 16 так-
     тов.

 д). Наиболее  быстрым способом СКРОЛЛИНГА
     экрана по вертикали и довольно совер-
     шенным методом вывода графики из  па-
     мяти является следующий:

     ...
     LD      SP,адрес-источник
     POP     HL
     POP     DE
     POP     BC
     POP     AF
     POP     IX
     POP     IY
     EXX
     POP     HL
     POP     DE
     POP     BC

     LD      SP,адрес-цель
     PUSH    BC
     PUSH    DE
     PUSH    HL
     EXX
     PUSH    IY
     PUSH    IX
     PUSH    AF
     PUSH    BC
     PUSH    DE
     PUSH    HL
     ...

     Этот метод очень эффективен,  но  все
     равно не позволяет вывести весь экран
     за одно прерывание.

 е). Теперь рассмотрим САМЫЙ совершенный и
     малоиспользуемый способ вывода графи-
     ки:
     Данные перемешиваются  с  программой,
     и получается конструкция типа:

     ...
     LD      SP,адрес в экране
     LD      HL,два байта графики
     PUSH    HL
     LD      HL,очередные два байта
     PUSH    HL
     LD      HL,очередные два байта
     PUSH    HL
     ...

     А теперь давайте немного посчитаем...

     LD    HL,число - 10 тактов,
     PUSH  HL       - 11 тактов.
     Для вывода полноэкранной картинки не-
     обходимо   повторить   этот  фрагмент
     3072 раза = 21*3072 = 64512 тактов.
     LD    SP,число - 10 тактов.
     Стек  изменять  придется  ( хотя и не
     обязательно )  перед  выводом  каждой
     строки,  то есть  192  раза = 10*192=
     =1920 тактов.
        И того, все в целом будет занимать
     64512+1920=66432 такта !!!

    Как  видите,  вполне  реально  вывести
изображение без повторений  на целый экран
за одно прерывание.
    Данный способ вывода графики далеко не
нов и придуман не  мной.  Во всяком случае
им пользовались многие мои друзья из RUSH,
и рассказал мне о нем  IMP  еще  несколько
лет назад...
    При  использовании  этого метода также
 расходуется по два  байта  памяти на каж-
 дый выводимый байт  графики.   Вывод пол-
 ноэкранной картинки  абсолютно  без  пов-
 торяющихся фрагментов  элементарно  укла-
 дывается не только в  пентагоновское пре-
 рывание,  а и в прерывание  на любой нор-
 мальной машине, например, SCORPION, PROFI
 и т.д.   Правда на фирменной машине появ-
 ляются  проблемы  связанные  с тем, что в
 ней раздельные поля памяти,  то  есть эк-
 ранная память работает  гораздо медленее,
 а нам приходится помещать стек в экран...
 Но если бы у фирменного  SPECCY  было ре-
 ально 70000 тактов в прерывании, все  от-
 лично успевало бы  работать,  даже  оста-
 лось бы место для музыки.
      Чтоб заставить  изображение двигать-
 ся, придется  менять  адреса, заносимые в
 SP, но  и  это вполне реально.

    И еще несколько  полезных  советов для
кодеров, которые были  почерпнуты  из мно-
голетнего опыта работы  на  ассемблере как
моего личного, так и  многих  других коде-
ров:

     При  выводе   изображения  по  маске,
спрайт удобнее всего хранить  перемешанным
с маской. Байт графики,  затем  байт маски
и т.д. Выводиться такой спрайт будет так:
       ...
       POP     DE     ; два байта грфики
       LD      A,D
       AND     (HL)
       OR      E
       LD      (HL),A
       INC     L
       ...
Стек при этом должен указывать на графику,
а HL на экран.



     Наиболее  быстрый  способ очистки эк-
рана:
       LD      SP,#5800
       LD      BC,0
       PUSH    BC - повторить 3072 раза.

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



     Теперь  очень  важная  вещь,  которую
следует знать  всем,  кто решил писать ка-
чественные программы на  SPECCY.   При вы-
воде большого  количества  графики,  веро-
ятность того,  что телевизионный луч пере-
сечется с выводимым в  данный момент  бло-
ком графики  очень  велика.   Это приведет
к тому, что  в  месте пересечения с лучем,
динамическое  изображение   будет  дискри-
ровать.  Например,  при  скроллинге  боль-
шого  фрагмента  экрана  верхняя часть его
будет сдвинута,  затем  луч "догонит" мес-
то вывода, и дальнейшая  половина картинки
будет  выводиться  с  отставанием на  один
кадр.   Еще более ужасная  картина получа-
ется, если изображение на экране времменно
стирается,  развертка может попасть именно
на такой момент, и  тогда  могут появиться
исчезающие спрайты,  промигивающие курсоры
и прочее лэймерство.
     Как с этим бороться:
Можно постараться,  чтобы развертка не пе-
ресекалась с выводом  на  протяжении всего
прерывания.   Так, можно  сначала  вывести
графику в среднюю и нижнюю  трети  экрана,
а в  конце,  когда  лучь  уже пройдет вер-
хнюю  половину экрана, можно вывести верх-
нюю треть. Этот метод используется доволь-
но  часто,  но  из-за  огромных различий в
конструкции  компьютеров развертка на раз-
ных типах SPECCY  может сильно отличаться,
что  станет  причиной  дискрирования изоб-
ражения.   Стоит  посмотреть  как работает
"SHOCK" на Пентагоне, и вам все станет яс-
но.
     Самым  эффективным и практичным мето-
дом в данном случае  является  использова-
ние  дополнительного  экрана  в  машинах с
ОЗУ  128к  и больше. Наличие двух экранов,
которые можно  переключить  мгновенно  при
помощи одного  единственного  OUT'а, очень
сильно облегчает жизнь программисту.
     Работа  с двумя экранами производится
следующим образом:  на прерывания (не обя-
зательно)  вешается  небольшая  программа,
которая поочередно подключает  то  7 стра-
ницу и обычный экран,   то  5  страницу  и
теневой экран. Выглядеть  это  может  при-
мерно так:

SCREEN_CHANGER:

SCR     LD      A,#55       ; %01010101
        RRCA
        LD      (SCR+1),A
        LD      A,#17       ; 16+7
        JR      C,PAGER
        LD      A,#1D       ; 24+5
PAGER:
        LD      BC,#7FFD    ; 32765
        OUT     (C),A
        RET

     Все  процедуры, работающие с экраном,
должны быть написаны  с  учетом  того, что
экран теперь  находится  не с адреса #4000
(16384 dec), а с адреса #C000 (49152 dec).
Процедуру DOWN_HL  менять  не нужно, она и
так будет работать корректно.
     Суть  данного  метода  состоит в том,
что изменять  (стирать, двигать и т.д.) Вы
будете не тот экран,  который отображается
в данный момент на  мониторе,   а тот, ко-
торый находится в памяти  и  не виден зри-
телю. Никакого, дискрирования не будет аб-
солютно, даже если Вы будете изменять весь
экран целиком. Так например сделано в сло-
вацкой демке "ECHOLOGY", и она великолепно
работает на всех машинах, вкючая Пентагон,
за исключением MULTICOLOR'ов,  разумеется.
Кстати, MULTICOLOR - это и  есть дискриро-
вание...
      Конечно писать  программы  используя
один  экран - круче,  но  на  практике это
не  целесообразно. Я советую Вам не мучить
пользователей  и писать soft под два экра-
на.


      А  теперь  совет, не имеющий прямого
отношения к работе  с  динамической графи-
кой,  но  он  может  пригодиться Вам в том
случае, если у Вас не хватает процессорно-
го времени на проигрывание музыки,  а сво-
бодной памяти остается  много.     В таком
случае можно поступить следующим образом:
      Музыка  раскладывается  на составля-
ющие компоненты  и затем проигрывается ми-
нуя player.   Простой вывод данных в порты
будет занимать  каких-нибудь  300  тактов,
если  сравнить  с тем, что player от "ASM"
требует более 8000  тактов - разница  ощу-
тима.
      Желательно не  подгружать уже разло-
женную на данные музыку  с диска, а созда-
вать  ее  непосредственно  перед  запуском
программы ,  так-как  размеры  полученного
блока  данных   могут  достигать  десятков
киллобайт.   Можно  также попробовать ком-
прессировать повторяющиеся фрагменты.
      Данный  метод  использовался во мно-
гих демонстрациях  -  "ECSTASY",  "SHOCK",
"SATISFACTION", "INSULT" и др.


      А вот наиболее  красивый  и компакт-
ный способ отключения звука на AY, который
я видел (писал его не я):

SHUT_UP:
          LD      HL,#000D
SHUT1     LD      BC,#FFFD
          OUT     (C),L
          LD      B,#BF
          OUT     (C),H
          DEC     L
          JR      NZ,SHUT1
          RET


    В том случае, когда вам необходимо оп-
ределить  нажатие  любой клавиши,  включая
Caps Shift  и  Simbol Shift  очень  удобно
пользоваться  "классической" процедурой из
ПЗУ, которая  находится по десятичному ад-
ресу 654.  Процедура возвращает в регистре
Е код 255  (#FF) , если  не нажата ни одна
клавиша.

    Пример использования:

WAIT:
        CALL    654
        INC     E
        JR      Z,WAIT
        RET


      Если кто-то  не  понял, что именно я
имел  в  виду  под  процедурой DOWN_HL или
DOWN_DE, я привожу ниже их текст:

DOWN_HL:
          INC     H
          LD      A,H
          AND     7
          RET     NZ
          LD      A,L
          ADD     A,#20
          LD      L,A
          RET     C
          LD      A,H
          SUB     8
          LD      H,A
          RET

DOWN_DE:
          INC     D
          LD      A,D
          AND     7
          RET     NZ
          LD      A,E
          ADD     A,#20
          LD      E,A
          RET     C
          LD      A,D
          SUB     8
          LD      D,A
          RET


   Если Вам нужно опуститься вниз на целое
знакоместо, нужно выполнить следующие дей-
ствия (адрес в HL), а не вызывать восемь
раз в цикле DOWN_HL, как делают некоторые
наивные ребята... :

LOWER_HL:
          LD      A,L
          ADD     A,#20
          LD      L,A
          RET     NC
          LD      A,H
          ADD     A,8
          LD      H,A
          RET


   Иногда бывает нужно пересчитать адрес в
экране  в  адрес  соответствующий  данному
знакоместу  в  области  атрибутов. Сделать
это можно так:

SCR_ATR:
          LD      A,H
          RRCA
          RRCA
          RRCA
          AND     3
          OR      #58
          LD      H,A
          RET


    На  сегодня  хватит...  Конечно спосо-
бов   повышения   эффективности   программ
может  быть  бесконечное  множество.   Для
каждого  конкретного случая есть свои при-
емы и тонкости.  Их нужно  знать не только
для  того, чтобы  писать  сногсшибательные
эффекты...
      Не  умея  пользоваться  достижениями
современных кодеров,  вы не сможете писать
качественные динамические  игрушки,   да и
хорошей системной  программы  написать не-
возможно, пользуясь  методами десятилетней
давности.
     Поэтому  дерзайте !   Возможно, скоро
Вам удастся  написать полноэкранный multi-
color или еще какое-нибудь чудо кодинга !

              Good luck !!!



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

AMIGA NEWS - AMIGA OS v3.5 - вопросы и ответы.

AMIGA NEWS - Описание Viewer'а графических файлов - Fast JPEG.

AMIGA NEWS - Программинг на Amiga: О Amiga изнутри, Графика, Сопроцессоры, Особенности ассемблера.

AMIGA NEWS - События 1998 года (обзор событий).

AMIGA NEWS - Cheat'ы Для Amiga-игр: After The War, Magicland Dizzy, Fantasy World Dizzy, Alien Breed, Exolon, Jagar Zj2200, Goblins, Mega Ball, Prince Of Persia,Projects-x, UGH!, Rick Dangerous-2.

AMIGA NEWS - Амига GFX-чип Permedia2.

AMIGA NEWS - Амига сегодня.

Spectrum программинг - Быстрые 3D-расчеты: продвинутый алгоритм.

Spectrum программинг - Звуковые эффекты для музыкального процессора и их совмещение с основной мелодией.

Spectrum программинг - Зеркальное отображение байтов и Восстановление фона из буфера.

Spectrum программинг - Краткое пособие для системного кодера. Советы автору "boot'a", паковщика, Музыкального редакторы.

Spectrum программинг - Современные методы кодинга и современные способы работы с графикой.

The End - эпилог.

ZX-SOFT - "Черный Ворон II": Готовьтесь к очередному хиту от Copper Feet !

ZX-SOFT - Описание программ: Real Commander v1.6

ZX-SOFT - споры о демо: Forever vs Refresh.

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

Виртуальный Спекки - Конвертация графики на Спектрум с PC и Амиги.

Виртуальный Спекки - Эмулятор от CodeBusters на Амиге.

Виртуальный Спекки - Эмуляторы ZX-SPECTRUM на PC: Где взять последнии версии FAQ по эмуляции ZX-Spectrum, Какие эмуляторы наиболее удобны - эмулятор Лунтера, UKV v1.2, Шалаева. Что за файлы с расширением *.$b,*.$c,*.$s,*.$z,*.$w ? Как прочесть формат "hobeta". Как и в каком эмуляторе можно работать в iS-DOS. Конвертация файлов .z80 в .$ и обратно. Файлы с расширением .fdi. Проблемы с эмулятором UKV. Как получить чистый файл образа диска (.trd) для эмулятора Шалаева. Существует ли Российский ZX-ориентированный FTP или WWW сервер? Hobeta отказывается читать/писать диски 3.5" - что делать?

Вступление - история создания журнала.

Вступление - О целях сценового журнала - RUSH.

Интервью - Большое интервью с группой ANTARES.

Интервью - Интервью с Kvazar'ом из RUSH.

Интервью - Интервью с группой из Витебска Power group.

Информацриум - CD с эмуляторами и ZX-софтом.

Информацриум - Интересные INTERNET адреса.

Информацриум - Обзор журналов и книг об Амиге.

О журнале - Платформобесие - многоплатформенная оболочка для журнала.

Параллельные миры - История центральных процессоров и Windows.

Параллельные миры - обзор моделей компьютера Macintosh.

Развитие Spectrum - 128 цветов на Спектруме (описание расширения графической палитры).

Развитие Spectrum - Блокировка порта клавиатуры SPECCY при подключении C-DOS модема.

Развитие Spectrum - Новый Speccy - AZXMONSTRUM 512K.

Развитие SPECTRUM - Новый Spectrum от Синклера.

Развитие Spectrum - Потомки процессора Z80.

Реклама - подробный прайслист фирмы Скорпион.

Реклама - Реклама и объявления...

Реклама - Реклама фирмы X-Trade.

Смысл без смысла - Рассказы: Самый счастливый человек, Третий глаз, Спаситель Вселенной, Цветик-семицветик, Жизнь только начинается, Страшный суд.

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

Сценохрония - Живучий Спектрум: Spectrum дорог большинству из нас. Почему ?

Сценохрония - Краткий обзор новостей от группы RUSH.

Сценохрония - Обзор сцено-событий: Alliance, Alchemist Research, Asphyxia, Brokimsoft, CodeBusters, Concern Chaos, Copper Feet, Crystal Dream, Digital Reality, E0Mage, Energy Minds, Entire, Excess, Fatality и т.д.

Сценохрония - Отголоски Fun Top'98.

Сценохрония - Проект Long Live Amiga, призванный помочь становлению и развитию амиговской сцены.

Управление оболочкой - о ZX версии оболочки.

Клуб виртуальной реальности portal в барнауле barnaul.warpoint.ru.

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

Похожие статьи:
Юмор - Смехопилорама.
Обмен опытом - Game Making 2: всевозможные методы вывода спрайтов (по мотивам игры Full Shit).
Ринг - сравнительный анализ двух файловых коммандеров Real Сommander VS Quick Сommander.
От авторов - Содержание страницы. Вступление.
Реклама - Реклама из Челябинской области.

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