Adventurer #08
31 августа 1998

Обмен опытом - процедура Движение атрибутной надписи по пикселям (плавающие атрубуты).

     (C) Иван Рощин, Москва, 1998

     Если вы  видели  "ART VISION" demo ,
то  помните,  что  в  последней части там
движется    атрибутная   надпись   "intel
outside" . Так как надпись атрибутная, то
и перемещается она с дискретностью 8 пик-
селей  (1  знакоместо),  что  выглядит не
очень красиво. Я написал программу, кото-
рая,  по существу, реализует тот же самый
полноэкранный, "укладывающийся в прерыва-
ние"  эффект, но теперь перемещение - по-
пиксельное,  что выглядит несравнимо луч-
ше. Программа снабжена подробными коммен-
тариями,  так  что  разобраться  в ней не
составит большого труда.
     Если  вы  захотите  посмотреть,  как
выглядел  этот  эффект  "в  оригинале"  -
просто  уберите  из программы две строки,
помеченные "*".
     Картинка  размером  64*64 знакоместа
взята из "ART VISION" demo  и находится в
массиве  PICTURE. Каждое знакоместо коди-
руется  одним  битом,  таким образом, вся
картинка занимает 512 байт.
     Траектория  движения  задается с по-
мощью  массива CRDS, который содержит 100
элементов следующего вида:

     1  байт  -  смещение (в знакоместах)
левой  стороны фрагмента относительно ле-
вой границы картинки (см. рис.)
     1  байт  -  смещение (в пикселах, по
модулю 8) левой стороны фрагмента относи-
тельно левой границы картинки.
     1  байт  -  смещение (в знакоместах)
верхней  стороны  фрагмента  относительно
верхней границы картинки.
     1  байт  -  смещение (в пикселах, по
модулю 8) верхней стороны фрагмента отно-
сительно верхней границы картинки.

 ┌──────────────────>x
 │                 │── вся картинка
 │  ┌───────┐      │
 │  │       │      │
 │  │       │───────── выводимый
 │  │       │      │   фрагмент
 │  └───────┘      │
 │                 │
 │                 │
 │─────────────────┘
 y

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

        CALL    MAKEADR  ;Подготовка...
        CALL    UNPACK
        CALL    CLS

M1      LD      IX,CRDS  ;адрес таблицы
        LD      D,100    ;кол-во координат
                         ;в таблице
M2      LD      BC,4
        LD      A,(IX)   ;Берем
        LD      (XATR),A ;координаты
        LD      A,(IX+1) ;выводимого окна
        LD      (XPIX),A ;*
        LD      A,(IX+2)
        LD      (YATR),A
        LD      A,(IX+3)
        LD      (YPIX),A ;*


        ADD     IX,BC    ;Увелич. адрес
        PUSH    IX
        PUSH    DE
        CALL    OUTSCR   ;Вывод на экран
        POP     DE
        POP     IX

        XOR     A
        IN      A,(254)
        CPL
        AND     31       ;Если что-то
        RET     NZ       ;нажато, выходим


        DEC     D        ;Продолжаем...
        JR      NZ,M2
        JR      M1

;***************************************
;Проц. OUTSCR выводит на экран фрагмент
;картинки.
;Вход: XATR,XPIX - смещение левой
;стороны фрагмента относительно
;левой границы картинки (XATR*8+XPIX
;пикселов);
;YATR,YPIX - смещение верхней стороны
;фрагмента относительно верхней границы
;картинки.

OUTSCR  DI
        LD      (TO_Q+1),SP ;Сохранили SP
        LD      SP,TAB_SCR

;SP указывает на начало таблицы адресов
;строк экрана. При каждом выполнении
;команды POP со стека снимается адрес
;очередной строки.

        LD      A,(XPIX)
        ADD     A,A
        ADD     A,A
        ADD     A,A
        ADD     A,A
        ADD     A,#80
        LD      H,A
        LD      L,0
        LD      A,(YATR)
        LD      D,A
        LD      E,0
        SRL     D
        RR      E
        SRL     D
        RR      E
        ADD     HL,DE
        LD      D,0
        LD      A,(XATR)
        LD      E,A
        ADD     HL,DE

        POP     DE            ;#4000
        LD      BC,-#10
        EX      DE,HL
        ADD     HL,BC
        EX      DE,HL
        LD      (LP4+1),DE

;HL указывает на строку изображения;
;DE - на адрес в видеопамяти, куда
;нужно переслать эту строку
;(в данном случае это самая верхняя
;строка экрана, с адресом #4000).

        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI

;Пересылаем оставшиеся (7-YPIX) строки:

        LD      (HL_S1+1),HL

        LD      A,(YPIX)
        LD      B,A
        LD      A,7
        SUB     B
        JP      Z,SCRH

LP4     LD      HL,0
        POP     DE
        LD      BC,-#10
        EX      DE,HL
        ADD     HL,BC
        EX      DE,HL
        LD      (LP4+1),DE
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        DEC     A
        JP      NZ,LP4

;Теперь еще 23 раза пересылаем по 8 стр.

SCRH    LD      YL,23  ;Счетчик
HL_S1   LD      HL,0   ;Адрес очередной
        LD      BC,#40 ;пересылаемой
        ADD     HL,BC  ;строки
        LD      (HL_S1+1),HL

;Подготавливаем адреса для переброски:

        EX      DE,HL   ;Сохранили HL
        LD      C,#10
        POP     HL      ;Куда пересылать
        LD      (SP_0+1),HL
        ADD     HL,BC
        LD      (SP_01+1),HL
        POP     HL      ;На строку ниже
        LD      (SP_1+1),HL
        ADD     HL,BC
        LD      (SP_11+1),HL
        POP     HL      ;На строку ниже
        LD      (SP_2+1),HL
        ADD     HL,BC
        LD      (SP_21+1),HL
        POP     HL      ;На строку ниже
        LD      (SP_3+1),HL
        ADD     HL,BC
        LD      (SP_31+1),HL
        POP     HL      ;На строку ниже
        LD      (SP_4+1),HL
        ADD     HL,BC
        LD      (SP_41+1),HL
        POP     HL      ;На строку ниже
        LD      (SP_5+1),HL
        ADD     HL,BC
        LD      (SP_51+1),HL
        POP     HL      ;На строку ниже
        LD      (SP_6+1),HL
        ADD     HL,BC
        LD      (SP_61+1),HL
        POP     HL      ;На строку ниже
        LD      (SP_7+1),HL
        ADD     HL,BC
        LD      (SP_71+1),HL
        LD      (PUT_SP+1),SP ;Сохр. SP


        EX      DE,HL   ;Восстановили HL
        LD      BC,-#20
        ADD     HL,BC
        LD      SP,HL
        POP     AF      ;Взяли первые
        POP     BC      ;16 байт
        POP     DE      ;пересылаемой
        POP     HL      ;строки
        EXX
        POP     BC
        POP     DE
        POP     HL
        POP     IX
        LD      (TWO+1),SP

SP_0    LD      SP,0    ;Записываем их
        PUSH    IX      ;на экран
        PUSH    HL      ;в 8 соседних
        PUSH    DE      ;строк
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_1    LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_2    LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_3    LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_4    LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_5    LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_6    LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_7    LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX

TWO     LD      SP,0
        POP     AF      ;Взяли вторые
        POP     BC      ;16 байт
        POP     DE      ;пересылаемой
        POP     HL      ;строки
        EXX
        POP     BC
        POP     DE
        POP     HL
        POP     IX

SP_01   LD      SP,0
        PUSH    IX      ;Записываем...
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_11   LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_21   LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_31   LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_41   LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_51   LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_61   LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX
SP_71   LD      SP,0
        PUSH    IX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        EXX
        PUSH    HL
        PUSH    DE
        PUSH    BC
        PUSH    AF
        EXX

PUT_SP  LD      SP,0    ;Восст. SP
        DEC     YL      ;Уменьшаем счетчик
        LD      A,YL
        AND     A
        JP      Z,END_ML ;Вывели 23 строки

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

        CP      12
        JP      NZ,HL_S1
        LD      HL,0
        ADD     HL,SP
        LD      SP,(TO_Q+1)
        PUSH    IY
        LD      IY,#5C3A
        EI
        HALT
        DI
        POP     IY
        LD      SP,HL
        JP      HL_S1

;Если YPIX<>0, нужно вывести последние
;строки в самом низу экрана:

END_ML  LD      A,(YPIX)
        AND     A
        JP      Z,TO_Q

        LD      HL,(HL_S1+1)
        LD      BC,#20
        ADD     HL,BC
        POP     DE
        LD      BC,-#10
        EX      DE,HL
        ADD     HL,BC
        EX      DE,HL
        LD      (LP5+1),DE
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI

;Пересылаем оставшиеся строки:

        LD      A,(YPIX)
        DEC     A
        JP      Z,TO_Q
        LD      B,A

LP5     LD      HL,0
        POP     DE
        LD      BC,-#10
        EX      DE,HL
        ADD     HL,BC
        EX      DE,HL
        LD      (LP5+1),DE
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        LDI:LDI:LDI:LDI:LDI:LDI:LDI:LDI
        DEC     A
        JP      NZ,LP5

TO_Q    LD      SP,0     ;Восстановили SP
        LD      IY,#5C3A ;---/--- IY
        EI
        RET     ;Выход из процедуры

;***************************************
;Проц. MAKEADR создает таблицу с
;адресами всех 192 строк экрана,
;в которой каждый адрес увеличен на #10.
;Адрес таблицы - TAB_SCR.

MAKEADR LD      HL,TAB_SCR
        LD      DE,#4010
        LD      B,192

LP_MAKE LD      (HL),E
        INC     HL
        LD      (HL),D
        INC     HL
        CALL    DOWN_DE
        DJNZ    LP_MAKE
        RET

DOWN_DE INC     D
        LD      A,D
        AND     7
        RET     NZ
        LD      A,E
        SUB     #E0
        LD      E,A
        RET     NC
        LD      A,D
        SUB     8
        LD      D,A
        RET

;***************************************
;Проц. UNPACK распаковывает картинку
;по адресу PICTURE на #8000-#FFFF

UNPACK  LD      HL,#8000
        LD      DE,PICTURE
LP_UP1  LD      B,8
        LD      A,(DE)
LP_UP2  RLA
        LD      C,#FF
        JR      C,TO_MEM
        LD      C,0
TO_MEM  LD      (HL),C
        INC     HL
        DJNZ    LP_UP2
        INC     DE
        LD      A,H
        CP      #90
        JR      NZ,LP_UP1

        LD      HL,#8FFF
        LD      DE,#9FFF
        AND     A
        PUSH    AF

LP_UP3  POP     AF
        LD      A,(HL)
        RLA
        PUSH    AF
        LD      (DE),A
        DEC     HL
        DEC     DE
        LD      A,L
        CP      #FF
        JR      NZ,LP_UP3
        LD      A,H
        AND     #0F
        CP      #0F
        JR      NZ,LP_UP3
        LD      BC,#2000
        ADD     HL,BC
        EX      DE,HL
        ADD     HL,BC
        EX      DE,HL
        LD      A,D
        CP      #0F
        JR      NZ,LP_UP3
        POP     AF
        RET

;***************************************
;Проц. CLS устанавливает атрибуты:


CLS     LD      HL,#5800
        LD      (HL),5
        LD      DE,#5801
        LD      BC,#2FF
        LDIR
        RET

;****************************************
;Картинка #40х#40 = #1000 бит = #200 байт

PICTURE
      DB #00,#00,#00,#00,#7F,#F0,#00,#00
      DB #00,#00,#00,#1F,#FF,#FF,#80,#00
      DB #00,#00,#00,#7F,#FF,#FF,#E0,#00
      DB #00,#00,#03,#FF,#FF,#FF,#FC,#00
      DB #00,#00,#1F,#FF,#FF,#FF,#FE,#00
      DB #00,#00,#3F,#FF,#FF,#FF,#FE,#00
      DB #00,#00,#FF,#FE,#1F,#FF,#FC,#00
      DB #00,#01,#FF,#F0,#03,#FF,#FC,#00
      DB #00,#07,#FF,#00,#00,#1F,#F8,#00
      DB #00,#0F,#F8,#00,#00,#0F,#F8,#00
      DB #00,#1F,#C0,#00,#00,#C1,#F0,#00
      DB #00,#3F,#00,#18,#00,#E0,#70,#00
      DB #00,#7E,#00,#18,#01,#E0,#20,#00
      DB #00,#F0,#00,#18,#01,#E0,#00,#00
      DB #01,#F0,#01,#FF,#81,#C0,#04,#00
      DB #03,#E7,#03,#FF,#31,#C0,#0E,#00
      DB #03,#C7,#00,#1C,#79,#C0,#0F,#00
      DB #07,#87,#00,#18,#F9,#C0,#0F,#80
      DB #0F,#00,#5E,#19,#99,#C0,#1F,#C0
      DB #0F,#0E,#7E,#19,#99,#C0,#1F,#C0
      DB #1E,#0E,#67,#39,#B1,#C0,#3F,#F0
      DB #1C,#0E,#67,#31,#B1,#C0,#3F,#F0
      DB #1C,#0C,#67,#33,#E1,#C0,#0F,#F8
      DB #38,#0C,#67,#33,#C1,#C0,#07,#F8
      DB #30,#1C,#67,#33,#89,#C0,#03,#F8
      DB #30,#18,#67,#31,#99,#80,#01,#FC
      DB #30,#18,#67,#31,#99,#80,#00,#FC
      DB #60,#18,#07,#31,#F1,#80,#E0,#7C
      DB #60,#18,#03,#30,#E1,#80,#E0,#7E
      DB #60,#00,#00,#30,#00,#00,#E0,#3E
      DB #E0,#00,#00,#00,#00,#00,#E0,#3E
      DB #E0,#00,#00,#00,#00,#00,#E0,#1E



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

От автора - помощь: Новые глюки в новой оболочке.

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

Презентация - Авторские программы: Installer to AUTORUN DISK v2. 0, адвентюрная игра Diamond.

Презентация - программа для защиты программ TRICK v1. 003b.

Презентация - HELP Z_80: Руководство пользователя.

Интерфейс - письма читателей: Черный ворон, Секрет игры NEW DIZZY, Об ошибках игры APOLLO, о новой веросии отладчика STS 6.2, Как пройти игру Святогор.

Интерфейс - PC vs Amiga: Так ли AMIGA RULEZ? Первые впечатления неофита.

Интерфейс - о поддержке производителями "железа" своих "творений" после того, как они (творения) попадают в руки пользователей.

Интерфейс - мысли вслух: "SPECCY компьютер для молодых. Если у нас так много крутых кодеров, то почему так мало крутого отечественного soft'а?"

Интерфейс - загоны от CAV inc: "SPECCY это не работа, это отдых, это, даже, больше, чем отдых, это стиль жизни, и, если за это вам еще удается получить деньги..."

Интерфейс - SPECCY за и против, Размышления Spy/Eternity Industry.

Система - Обзор системных программ: ZX-IBM Editor v1.5M , PPF v1.05, Multistudio v2.0p, Mods Player v2.0, Bitmap Viewer v2.0, Corrector v2.0, Storm v1.1, 866 v1.2, HRUM v3.5, TDU v1.0, HRUST v1.0, RLE-Compressor v1.21, Оверлеи Consul Commander.

Обзор игрушек - Обзор новых игровых программ: Rabbit Jazzy, Quadrax, Komplex, Math of the day, Cue Boy, Zly Sen, Prva Aakcia, Outlaw, The Dark Empire, Gary Linekers.

Обзор игрушек - демоверсии: Little Ghost, The Dark Empire, Worms, Смагли 3, Monster Land, Цивилизация, Тайны капитана Шелтона.

Гости - Презентация группы группы из Коврова - Eternity Industry.

Гости - Filix о создании игры ВИННИ ПУХ-2.

Гости - экстремальщики: новая рубрика, освещающая аспекты жизни и творчества экстремальных рыбинских музыкантов. Сегодня в гостях Марат и Демон - стоявшие у истоков такой известной (в узких кругах) команды "Disgust".

Раскрутка - Как играть в игру Encyclopedia of WAR.

Раскрутка - прохождение игры Where time Stood Still.

Раскрутка - описание игры Elopement: back to the Earth.

Раскрутка - прохождение текстовой адвентюры Остров тьмы (Island Darkness).

Раскрутка - прохождение текстовой адвентюры Knightmare.

Обмен опытом - Русские глюки: игра Остров тьмы (о том, как НЕ НАДО писать адвентюрные игры).

Обмен опытом - Доработка ZX-ASM v3.0 от Ивана Рощина.

Обмен опытом - Особенности видеоконтроллера ZX Spectrum (для программистов).

Обмен опытом - Графический эффект IRIS (плазма).

Обмен опытом - процедура вывода окна с рамкой.

Обмен опытом - о том как оперировать в ассемблере с длинными числами типа Long.

Обмен опытом - Art Studio и принцип открытой архитектуры (как написать свои модули к редактору).

Обмен опытом - процедура Движение атрибутной надписи по пикселям (плавающие атрубуты).

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

Оттяг - Тест "Формацевт, проверка на подлинность".

Оттяг - Тест "Ты случайно не тупая задница".

Оттяг - Тест "Есть ли у тебя чувство юмора".

Оттяг - Тест "Какой из тебя студент".

Оттяг - Как ПРАВИЛЬНО убить Windows'95.

Оттяг - Винни-Пух и все-все-все - 2.

Новелла - Сказки Капрала Джилана (по игре Laser Squad).

Новелла - Побег из космоса (по игре Elite).

Новелла - Ежики мутанты.

Новости - новости от Рыбинских спектрумистов: Infosoft, Shrsoft, Surgeon, Chasm, Protecvision, Groboclone, Volume 4, Expеrience, Mr. Vano, Ant, Demon, Miguel, Veka, RDM, Auryn.

Новости - новости от Ярославских спектрмистов: Marchy, Kav Software, Nicolas Viper, Dr Shura, Harkonnen, MacKeymn, DJ Reason.

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


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

Похожие статьи:
ANOTHER WORLD - PENTIUM II Xeon - быстродействующая версия процессора.
Проходилка - Описание комбинаций клавиш для управления бойцами в игре " MORTAL KOMBAT ".
Примьера - новые игр и программы: Sprite Generator v2.0, EDAS v3.3, Mazics, Block, Super Copy Utilite v1.11.

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