ZX-Ревю 1996 №7-8 1995 г.

Этюды - стрелочный интерфейс.



(c) К.Феськов, г.Абакан. 1996.
   Если вы откроете первое издание ZX FORUM, то увидите там программу 
Виккера В.В., которая позволяет организовать удобный  стрелочный интерфейс. Это 
очень удобная программа, но, на данный момент, просто бегающая стрелка мало 
кого удовлетворит. Если мы посмотрим на программы Радионова, на мою последнюю 
программу, то увидим, что стрелка, попадая  на  меню, "зажигает" его. Как же 
реализовать эту функцию? Я приведу незначительные доработки вышеуказанной 
программы, которые позволят реализовать подобный эффект. Хочу упомянуть моего 
друга Старкова Павла, который любезно изложил мне смысл алгоритма.
   Изменения исходного текста программы коснутся ТОЛЬКО процедуры START,  
остальные подпрограммы не изменяются.
   Итак, я приведу сначала подпрограммы, а затем расскажу, что нужно для 
успешной работы программы.

START   LD HL,(CRDS)  ; Берем координаты вывода стрелки.
        LD A,255      ; Заносим число 255 в номер опции, что говорит о том,
        LD (OPC1),A   ; что стрелка на опцию не попала.
        PUSH IX       ; Далее все так, как в программе.
QO      CALL SCRBF
        CALL FORM
        HALT
        IN A,(31)
        PUSH AF
        CALL BFSCR
        POP AF
        LD C,A
        LD E,STEP
        LD D,254
        LD HL,CRDS+1
        BIT 0,C
        CALL NZ,PL
        BIT 1,C
        CALL NZ,MIN
        LD D,190
        DEC HL
        BIT 2,C
        CALL NZ,PL
        BIT 3,C
        CALL NZ,MIN
        BIT 4,C
        JR NZ,EXIT
        CALL COND     ; Вызываем процедуру проверки попадания стрелки.
        CALL BAR      ; Вызываем процедуру закрашивания/стирания опции.
        JR QO
COND    LD IX,(TABLE) ; В IX заносим адрес данных.
        LD A,1        ; Заносим номер первой опции в вспомогательную
        LD (OPC),A    ; переменную.
        LD HL,(CRDS)  ; В HL текущие координаты стрелки.
        SRL H         ; Так как координаты стрелки в пикселях, а программа
        SRL H         ; работает с знакоместами мы делим координаты на 8.
        SRL H
        SRL L
        SRL L
        SRL L
COND1   LD A,(IX+0)   ; В A координата X меню.
        CP 255        ; Если 255, то данные кончились и стрелка не на опции.
        RET Z         ; Выход.
        LD D,A        ; Проверяем попадание по X.
        LD A,H
        CP D
        JR C,PROPOPC  ; Если левее опции, пропускаем ее.
        LD A,D
        LD B,(IX+2)   ; В регистре B длина опции в знакоместах.
        DEC B
        ADD A,B
        CP H
        JR C,PROPOPC  ; Если правее опции, пропускаем ее.
        LD A,(IX+1)   ; В A координата Y.
        CP L
        JR NZ,PROPOPC ; Если не совпадает с текущей координатой Y, пропускаем.
        LD A,(OPC)    ; Если все проверки прошли, значит мы нашли номер опции
        RET           ; загружаем его в A и выходим.
PROPOPC LD DE,3       ; Переходим к данным следующей опции.
        ADD IX,DE
        LD A,(OPC)    ; Номер текущей опции увеличиваем на 1.
        INC A
        LD (OPC),A
        JR COND1      ; Снова проверяем.
BAR     LD L,A        ; После выхода из процедуры COND в регистре A номер
                      ; опции или 255, если стрелка не попала.
        LD A,(OPC1)   ; Поместили в A номер предыдущей опции, сравниваем его
        CP L          ; с новым и если они равны, то закрашивать не надо.
        RET Z         ; Выходим.
        CP 255        ; Если стрелка ушла с опции, то красить новую не надо,
        JR Z,BAR5     ; а надо погасить старую, что и делает BAR5.
        PUSH AF
        LD A,L        ; Заносим новый номер на место старого.
        LD (OPC1),A
        POP AF
        CALL BAR1     ; Стираем старую опцию.
BAR6    LD A,(OPC1)   ; В A номер новой опции.
        CP 255        ; Если это не опция, то красить не надо.
        RET Z         ; Выходим.
BAR1    DEC A         ; Подготовка к закраске новой опции.
        LD H,0
        LD L,A
        PUSH HL
        POP DE
        ADD HL,HL
        ADD HL,DE
        EX DE,HL
        LD IX,(TABLE)
        ADD IX,DE
BAR3    LD H,(IX+0)
        LD L,(IX+1)
        CALL FILL     ; Процедура FILL закрашивает, либо стирает опцию.
        RET
BAR5    LD A,L
        LD (OPC1),A
        JR BAR6
FILL    LD A,L        ; Следующие строки выссчитывают адрес опции в атрибутах.
        AND 7
        RRCA
        RRCA
        RRCA
        ADD A,H
        AND #18
        RRCA
        RRCA
        RRCA
        OR #58
        LD H,A
        LD A,(HL)     ; Берем байт атрибута.
        PUSH AF       ; Следующие строки инвертируют опцию меняя местами
        AND 7         ; INK и PAPER. BRIGHT не учитывается.
        SLA A
        SLA A
        SLA A
        LD D,A
        POP AF
        AND 56
        SRA A
        SRA A
        SRA A
        OR D
        LD B,(IX+2)   ; В регистре B длина опции в знакоместах.
FILL1   LD (HL),A     ; Если опция напечатана на многоцветном фоне, то в цикл
        INC HL        ; следует включить строки, начиная с "берем байт
        DJNZ FILL1    ; атрибута".
        RET
START1  LD (TABLE),HL ; Эта отдельная процедура, которая задает координаты
        LD A,(HL)     ; стрелки так, чтобы она попадала на первую опцию.
        ADD A,A
        ADD A,A
        ADD A,A
        LD D,A
        INC HL
        LD A,(HL)
        ADD A,A
        ADD A,A
        ADD A,A
        LD E,A
        INC HL
        LD A,(HL)
        ADD A,A
        ADD A,A
        ADD A,A
        SUB 4
        LD D,A
        LD (CRDS),DE
        RET
TABLE   DEFW 0        ; Здесь будет адрес таблицы.
OPC     NOP           ; Номер новой опции.
OPC1    NOP           ; Номер старой опции.
TABLE1 X,Y,L,X1,Y1,L1, ... ,255      ; Данные меню.

   Для успешной работы требуется:
   Составьте таблицу описания опций меню в таком порядке - сначала  координата
X, затем Y, затем длина опции в знакоместах. X и Y задаются в знакоместах.
   Как практически использовать процедуру:

PROGRAM LD HL,TEXT    ; Печатаем текст меню.
        CALL PRINT
        LD HL,TABLE1  ; В HL адрес таблицы данных меню.
        CALL START1   ; Заносим его в переменную TABLE и центрируем стрелку.
L1      CALL START    ; Вызов процедуры стрелки.
        LD A,(OPC1)   ; В A помещаем номер опции, на которой до нажатия
                      ; выстрела стояла стрелка.
        CP 255        ; Если в A 255, то стрелка на меню не попала и мы вновь
        JR Z,L1       ; рисуем стрелку (можно реагировать по другому).
        CP 1          ; Далее проверяем на какой опции стояла стрелка и
        CALL Z,PROG1  ; делаем переход на нужную подпрограмму.
        CP 2          ; Номер НЕ ЗАВИСИТ от того как напечатаны опции на
        JR Z,PROG     ; экране, а зависит от составленной таблицы.
        и т.д.

   После нажатия выстрела опция остается гореть, но это не  всегда  приемлемо.
Для принудительного гашения опции, после команды CALL START надо подать  
команду CALL BAR6.
   Не редкость такая ситуация, когда нам не надо зажигать опцию, но необходимо
знать, попала ли стрелка туда, куда нам надо. Для этого:

PROGRAM LD HL,TABLE1  ; В HL адрес таблицы, которая состоит только из кода 255
        CALL START1
        CALL START    ; Вызываем подпрограмму стрелки.
        LD HL,TABLE2  ; В HL адрес настоящей таблицы описания.
        LD (TABLE),HL ; Заносим его в переменную.
        CALL COND     ; Ищем номер опции. После выхода номер будет в A, а не
        CP 255        ; в переменной OPC1!!!
        JR Z,PROGRAM  ; Далее обрабатываем номер как угодно.
        CP 1
        CALL Z,PROG
        и т.д.
TABLE1  DEFB 255      ; Пустая таблица.
TABLE2  X,Y,L,255     ; Настоящая таблица.

   На этом позвольте закончить свое повествование. Рад, если кому-то эта 
информация поможет.



СОДЕРЖАНИЕ:


  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



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

Похожие статьи:
Hовости - Рязань.
С Битой по миру - критическое разоблачение "Компьютерная энциклопедия для мальчиков".
Реклама - реклама и обьявления.
Книга о вкусной пище - Холодные закуски, горячие закуски и супы. (кулинарные рецепты). Реклама: часы командирские.
TOP TEN - Лучшая десятка игр.

В этот день...   21 ноября