IzhNews #0C
31 июля 2001

Nonsense - процедуры печати курсора с подробными пояснениями.

░░░  ░░░   ░▒▒▒░   ░░░  ░░░  ░▒░░  ░░░░░  ░░░ ░░░   ░▒░  ░░░░░░ 
░█▓░ ▓█▒  ░▓████░  ▒█▓  ██░ ░███▓ ░████▓  ▓█▒ ░██░ ▒███▒ ░████▒ 
░██▒ ▓█▓  ▓██████░ ▒██░ ██▒ ▒████░░████▓  ▓█▓░░██░ ▓███▓ ▒████▒ 
░██▓░▓██░░██▓▒▓██▒ ▒██▒ ██▓ ▓█▓█▒ ▒████▒  ▓██░░██▒ ██▓█░ ▓████░ 
░███░▓█▒ ▒██░ ░▓█▓ ▒███░██░ ▓█▒░   ██░    ▓██▓░██  ██░░  ░██    
░███▓▓█▒ ▒█▓   ▒█▓ ▒███▒██░ ▒██░   ██▓▓▒  ▓███▒██  ▓█▓░  ░██▓▓░ 
░██████▒ ▒█▓░  ▒█▓ ▒██████░  ▒██░  ████▒  ▓██████  ░▓█▓░ ░████░ 
░██▓███▒ ▒██▒  ▓█▓ ▒█▓████░   ░██░ ██▓▓░  ▓█▓████    ▒█▓░░██▓▓░ 
░██░███▒ ░███▒▒██▒ ▒█▓▒███░ ░▒░██▓ ██░    ▓█▒▓███  ░░░██▒░██    
▓██ ▓██▒ ░▓██████░░██▓░▓██░░▓████▒ █████ ░██▒░███ ░█████░░████▓ 
▒██ ░██▒  ░▓████░  ▓█▓ ▒██░░▓████░ ████▓ ░██▒ ▓██ ░████▓░░████▒ 
░▒▒  ▒▒░   ░▒▒▒░   ░▒▒ ░▒▒░ ░▒▒▒░  ▒▒▒▒▒  ▒▒░ ░▒▒  ░▒▒▒░ ░▒▒▒▒░ 

                          in basic...

(c) Pix/BrC                         Ижевск
──────────────────────────────────────────
  ┌─┐
  └─┘ вами  в  очередной раз main coder of
Brutal Creators (да простит меня Noviset).
Сегодня я буду глючить на тему  построения
курсора. Я, конечно, не спец в этой облас-
ти, и если вам нужен клёвый и быстрый кур-
сор,  то  это  вам читать противопоказано.
Если  же  вам  побоку  крутость, то читаем
далее.
   Вот, теперь остались  только те, кто не
нашел  статей о курсоре, или те, кто руко-
водствуется  принципом "лишь  бы  пело", а
также  те,  кто  не  очень  крут в кодах и
хочет  понять, как енто оно, блин, работа-
ет. Для последних и написана эта статья.
   Начну  с  проблем, возникающих  у самых
бегинерских  кодеров. Часто  первый собст-
венноручно  написанный  курсор  исчезает в
верхней части скрина или начинает мерцать.
Попытаюсь объяснить причину происходящего.
Для этого  рассмотрим  принцип  построения
изображения  на экране монитора. Как изве-
стно, происходит это замечательное событие
50  раз  в  секунду, сразу  после  прихода
прерывания. Курсор  строится обычно в про-
цедуре обработки прерывания, т.о. курсор и
изображение  строятся одновременно. В про-
цедуре обработки прера происходит примерно
следующее:
   а) восстанавливаем изображение под ста-
рым курсором (стираем его);
   б) сохраняем  изображение в новой пози-
ции;
   в) строим новый курсор;
Т.о. мы  должны  выполнить все 3 пункта до
того  момента, пока видеоконтроллер строит
изображение выше положения курсоров(старо-
го  и  нового). Обычно тормозная процедура
не  успевает  нарисовать  новый  курсор до
того момента, когда место его расположения
начинает  выводится на монитор, поэтому мы
его  и не видим. Отсюда правило: нужно по-
строить  новый  курсор, пока рисуется бор-
дер, а  для этого нужны относительно быст-
рые процедуры. <Примерно то же самое можно
прочитать в ZF#3>.
   Ну, пристипим:
BEGXP   EQU     184  ;начальные координаты
BEGYP   EQU     0    ;у=184 x=0
XY_KOOR DB      BEGXP,BEGYP ;текущие коор.
   Процедуры  наши  должны  быть быстрыми,
посему  все  сложные  (тормозные)  расчеты
сделaем один раз. Например, печатать спри-
та  с точностью до пиксела можно только по
y-ку, а по x шаг дискретный (8pix). Но нам
нужно печатать как по y, так и по x с оди-
наковой точностью,равной 1 pixel. Для это-
го нужно двигать спрайт на кол-во пикселей
равное  остатку от деления на 8. т.е. если
х=10, то  p=x%8=2, значит, нужно  сдвинуть
спрайт на 2 пискела вправо,а затем напеча-
тать  его  в  позицию x/8(char), y(pixel).
Делать это можно в процессе печати, но это
будет  медленно, посему  сделаем  к нашему
исходному спрайту еще 7 образовнных из не-
го  путем сдвига. Их-то мы и будем исполь-
зовать  в процессе вывода. Всей этой муте-
нью будет заниматься процедура инициализа-
ции:
INIT_CUR        ;собственно процедура инициализации курсора.
        LD      A,BEGXP
        LD      (XY_KOOR),A
        LD      A,BEGYP
        LD      (XY_KOOR+1),A
   Создадим таблицу адресов экрана для бы-
строй печати по Y. Для этого переберем все
строки от 0 до 192 и запишем адреса их на-
чал в Tabl_adr.
INT_TAB LD      DE,#4000      ; начало экранной области
        LD      HL,TABL_ADR   ; HL = адрес таблицы
        LD      B,192         ; кол-во строк
INT_TB1 LD      (HL),D        ; заносим адрес строки, который
        INC     HL            ; находится в DE.
        LD      (HL),E        ; ..
        INC     HL            ; ..
        CALL    DOWN_DE       ; Вычислим адрес следующей строки
        DJNZ    INT_TB1       ; переберем все строки.
 Теперь создадим спрайты, о  которых гово-
рилось  выше.  Одновременно  смешаем его с
маской.
        LD      HL,SUR_CUR    ; исходный спрайт
        LD      DE,CURSPR     ; там и будем смещать.
        LD      BC,32         ; длина одного спрайта с маской
        LDIR                  ; первый - смещение #00
INT_SPR LD      B,8           ; вроде кол-во новых спритов.
        LD      DE,NEW_SPR    ; новый спрайт написано.
INT_SP0 PUSH    BC            ; для циклу :)
        LD      HL,CURSPR     ; начало сприта
        LD      IX,CURSPR+16  ; начало маски
        LD      B,16          ; длина сприта или маски
INT_SP1 LD      A,(IX)        ; берем маску
        LD      (DE),A        ; кладем, куда надо
        INC     DE            ; след. элем.
        LD      A,(HL)        ; берем сприт
        LD      (DE),A        ; калдем.
        INC     DE            ; след.
        INC     HL            ; след.спр.
        INC     IX            ; нехт.маск.
        DJNZ     INT_SP1      ; ну, цикл, вроде.
   Вот, смешали  маску со спрайтом, теперь
имеем  сприт  с  маской  в  формате маска,
сприт, маска, сприт...со смещением #00.Te-
перь будем двигать.
        LD      HL,CURSPR     ; исход для смещений.
        LD      B,8           ; высота, вроде
INT_SP2 LD      A,(HL)        ; берем
        OR      A             ; cy=0
        RRA                   ;  ->
        LD      (HL),A        ; ложим на место
        INC     HL            ; след.
        LD      A,(HL)        ; берем 2-ой байт сприта
        RRA                   ;  ->
        LD      (HL),A        ; кладем
        INC     HL            ; далее
        DJNZ    INT_SP2       ; ну и так далее...
        LD      HL,CURMASK    ;
        LD      B,8           ;
INT_SP3 LD      A,(HL)        ; Тожа самое для маски
        SCF                   ; cy=1
        RRA                   ;  ->
        LD      (HL),A        ;
        INC     HL            ;
        LD      A,(HL)        ;
        RRA                   ;
        LD      (HL),A        ;
        INC     HL            ;
        DJNZ    INT_SP3       ; с масками все...

        POP     BC            ;
        DJNZ    INT_SP0       ; след. смещение, след. сприт
        LD      A,#37         ;
        LD      (CUR_PR),A    ; кое-какие предустановки
        JP      PR_CUR_       ; ну и все,инсталл закончен, появ-
                              ; ляем первый куроср.

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

  Теперь  процедуры  печати  курсора. Тут,
вроде,все просто: немного математики, оче-
нь  немного.  Никакого  стекового  вывода.
Скорость  достигается  отсутствием  сдвига
спритов.Здесь же процы восстановления зна-
комест под старым курсором. Думаю,разбере-
тесь сами, мне уже лень... :)

PR_CUR  LD      A,0
        LD      B,0
        LD      C,A
        SLA     C
        RL      B
        LD      HL,TABL_ADR
        ADD     HL,BC
        LD      D,(HL)
        INC     HL
        LD      E,(HL)
PR_CUR0 LD      A,0
        SRL     A
        SRL     A
        SRL     A
        ADD     A,E
        LD      E,A
        JR      NC,PRCO
        INC     D
PRCO    LD      HL,SPR_BUF
        LD      B,8
PRC__   LD      A,(HL)
        INC     HL
        LD      (DE),A
        INC     DE
        LD      A,(HL)
        LD      (DE),A
        DEC     DE
        INC     HL
        CALL    DOWN_DE
        DJNZ    PRC__
WOST_PR OR      A
        RET     C
PR_CUR_ LD      A,(XY_KOOR)
        LD      (PR_CUR+1),A
        LD      B,0
        LD      C,A
        SLA     C
        RL      B
        LD      HL,TABL_ADR
        ADD     HL,BC
        LD      D,(HL)
        INC     HL
        LD      E,(HL)
        LD      A,(XY_KOOR+1)
        LD      (PR_CUR0+1),A
        SRL     A
        SRL     A
        SRL     A
        ADD     A,E
        LD      E,A
        JR      NC,PRC0
        INC     D
PRC0    LD      A,(XY_KOOR+1)
        AND     7
        LD      BC,NEW_SPR
        LD      H,0
        LD      L,A
        ADD     HL,HL
        ADD     HL,HL
        ADD     HL,HL
        ADD     HL,HL
        ADD     HL,HL
        ADD     HL,BC
        LD      IX,SPR_BUF
        LD      B,8
PRC1    LD      A,(DE)
        LD      (IX),A
        INC     IX
        AND     (HL);MASK
        INC     HL
        XOR     (HL);CUR
        INC     HL
        LD      (DE),A
        INC     DE
        LD      A,(DE)
        LD      (IX),A
        INC     IX
        AND     (HL);MASK
        INC     HL
        OR      (HL);CUR
        INC     HL
        LD      (DE),A
        DEC     DE
        CALL    DOWN_DE
        DJNZ    PRC1
        RET

   Ну и загрузим спритик курсора и маски.

SUR_CUR LCODE   "CurSpr22.C";fixed line noatr (sm5.11)

   Что!? Давненько не видели столь убогого
коду? Погодите, еще  не такое напишу! Ведь
никто не против? Ну, ладно, все, пухните и
пишите че-нить, можете какие-нить статейки
к нонсенсу, а то будете  читать только мoй
бред.
──────────────────────────────────────────



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

Вступление - Постоянство - лучший способ уважать традиции.

Scene news - пополнение в Power of Sound Web Team. Unbeliever не покинул спектрум. Новости от Optical Brothers и Delirium Tremens. Nemo выпустил книгу об IS-Dos. Результаты ASCii. Распалась группа "Proxima Centauri". Triumph ROXX!

IzhNews - история проведения ASCII 2001. Таблица ижевских спектрумистов на лето 2001.

ЭСМИнец - обзор свежей прессы: Body, MSF, Inferno, Psychoz, Insanity, Scream.

Рапорт - Первый республиканский фестиваль комьютерного искусства ASCII 2001: NoViSeT рассказывает как это было.

Рапорт - секретный отчет с Hidden part ASCII 2001.

Visitors - список гостей первого Ижевского демопати ASCII 2001.

Откровения - откровения GAS 13 о конрверсиях на спектруме.

Допрос - Himik's ZxZ берет интвервью по телефону у ASC - Andrew Strikes Code.

Elite - Кто такой кульный сценер? Элитарные спектрумисты, кто они? Unbeliever и Arty?

Copyright - Спектрум является некоммерческой платформой. Есть ли авторское право на спектруме?

Диалог - Assholes Speak Russian: Raver покрывает грязью руcско-говорящую сцену.

Millenium - история газеты "IZH NEWS".

Nonsense - процедуры печати курсора с подробными пояснениями.

Commanders - Размышления об идеальном файловом коммандере.

Cheats - несколько фирменных CHEAT'ов к игре Черный Ворон.

Pokes - Abu Simbel Profanation, Alien Highway, А-10 ТB, Beach Vollei, Bear George, Chase H.Q. 2, Continental Circus, Dizzy A, Dragon Ninja и т.д.

Результаты - Результаты анкетирования пользователей Ижевской BBS.

Netmail - письма читателей: Глущенко Кирилл (Kristoph), Никитин Олег (NIK-O), Гаркушин Алексей (GAS-13), Энгельгардт Юрий (X-MAN), Колесников Сергей (SKL-KEEPER), Чичканёв Константин (ERASER), Токарчук Денис (D-W-T), Кленин Дмитрий (RamTop).

Рулезники - продолжение рассказа.

Дефикации - прогоны от sinn/dtr/fdm.

ENDец - послесловие и размышления Pixel'a о том как зарождалаксь ZX сцена.

Реклама - бесплатные обьявления из Ижевска.


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

Похожие статьи:
Лит. страничка - Три веселых буквы: отзывы к газете.
От авторов - Ну привет пиплы! Как ваши глаза? Не выпали от удивления? Да вы не ошиблись это я Powercom...
БаЙкИ АвТоРоВ - Да вот и вышел третьий номер нашей юмор-газеты в этом номере вы увидети много рассказов много анекдотов, стихов...

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