ZX-Forum №1 1993 г.

Системные программы - Удобный стрелочный интерфейс.


© РиккерВ.В. 1993 г., п.Провидения, Магаданской области.

Как известно, любой программе нужно удобное управление. Особенно удобно, если выбор режимов и команд производится джойстиком. Ниже приведена процедура, которая перемещает по экрану стрелочку и принажатии кнопки "огонь" имеет на выходе в регистровой паре HL адрес в дисплейном файле, соответствующий кончику стрелки ив регистровой паре ВС соответствующий адрес в области атрибутов. Эти адреса можно лихо использовать для определения дальнейших действий. Например, имея адрес атрибутов, можно проверить, скажем, бит 6 - яркость, попали ли Вы на команду или стрелка болтается, где ни попадя. Буду очень рад, если приведенная программка кому-нибудь пригодится.

00010

00020

; Написана в

августе 1993г

00030

; Провидения

00040

; автор

Риккер В.В.

00050

;

00060

ORG

40000

;нужный адрес ассемблирования

00070

ENT

00080

EI

00090

JP

START

п П 1 п п 00100

00110

00120

00130

; * Переменные программах *

00140

00150

;

00160

BUFFS

DEFS

30

;Буфер для сохранения того,

;что под стрелкой на экране.

00170

STS

DEFW

0

;Адрес в видеообласти, соответствующий

;острию стрелки.

00180

CRDS

DEFW

0

;Координаты острия стрелки.

00190

;

00200

;

Шаблоны стрелки

00210

;

00220

ORSH

DEFB

#C0,#E0,#F0

;Шаблон для операции OR

00230

DEFB

#F8,#FC, #FE

00240

DEFB

#FF,#FE, #FC

00250

DEFB

#1C,#0E,#0E

00260

DEFB

#07,#07,#03

00270

XORSH

DEFB

#C0,#A0,#90

;Шаблон для операции XOR

00280

DEFB

#88,#84,#82

00290

DEFB

#81,#86,#B4

00300

DEFB

#14,#0A, #0A

00310

DEFB

#05,#05,#03

00320

;

00330

STEP

EQU

2

;Скорость перемещения стрелки

;(с увеличением скорости

;уменьшается точность)

nm/i п 00340

00350

00360

. *

Подпрограммы *

00370

00380

;

00390

SCRBF

LD

HL,(CRDS)

;Координаты острия стрелки.

00400

LD

C,H

;Подготавливаем регистры для вы

00410

LD

B, L

числения адреса по координатам.

00420

LD

A, B

00430

CALL

#22B1

;Вычисляем адрес (процедура ПЗУ).

00440

LD

(STS),HL

;Сохраняем полученный адрес.

00450

LD

DE, BUFFS

;В DE адрес буфера.

00460

RB0

LD

B,15

;Высота стрелки в пикселах.

00470

RB1

PUSH

HL

00480

LD

C, 2

;Сколько смежных байт сохранять.

00490

RB2

LD

A,(HL)

00500

LD

(DE) ,A

00510

INC

L

00520

INC

DE

00530

DEC

C

00540

JR

NZ,RB2

00550

POP

HL

00560

CALL

DAD1

;Получаем адрес в дисплейном ;файле на 1 пиксел ниже.

00570

DJNZ

RB1

00580

RET

00590

в

;

00600

DAD1

INC

H

00610

LD

A, H

00620

AND

7

00630

RET

NZ

00640

LD

A, H

00650

SUB

8

00660

LD

H, A

00670

LD

A, L

00680

ADD

A,32

00690

LD

L,A

00700

RET

NC

00710

LD

A, H

00720

ADD

A, 8

00730

LD

H, A

00740

RET

00750

в

;

00760

BFSCR

LD

HL,#771A

;Подпрогр. восстановления экрана.

00770

LD

(RB2),HL

;Сначала перепрограммируется ;процедура SCRBF.

00780

CALL

SCRBF

00790

LD

HL,#127E

;Восстанавл. код процедуры SCRBF.

00800

LD

(RB2),HL

00810

RET

00820

00830

; Подпрограмма

создания образа стрелки

00840

; по имеющимся

координатам

00850

FORM

LD

A,(CRDS+1)

;По горизонт. координате получаем

00860

AND

7

;номер бита в байте экрана.

00870

EX

AF, AF'

;Сохраняем его.

00880

LD

IX,ORSH

;Накладываем маску по OR.

00890

CALL

FORMS

00900

LD

IX, MS3

00910

LD

(IX+0),#AA

;Изменяем процедуру FORMS.

00920

LD

(IX+9) ,#AB

00930

PUSH

IX

00940

LD

IX,XORSH

/Накладываем маску по XOR.

00950

CALL

FORMS

00960

POP

IX

00970

LD

(IX+0),#B2

;Восстанавл. код процедуры FORMS.

00980

LD

(IX+9) ,#B3

00990

RET

01000

FORMS

LD

C,15

;Число линий в стрелке.

01010

LD

HL,(STS)

;Берем адрес в экране.

01020

MS1

LD

D,B

;Обнуляем DE.

01030

LD

E,B

01040

EX

AF, AF'

01050

LD

B, A

;В рег.В номер бита в адр.экрана.

01060

EX

AF, AF'

01070

DEC

B

;Проверяем его на ноль.

01080

INC

B

01090

LD

D,(IX+0)

;В DE байт из шаблона стрелки.

01100

JR

Z, MS21

;Если 0, то обходим ротацию DE.

01110

MS2

SRL

D

;Сдвигаем шаблон.

01120

RR

E

01130

DJNZ

MS2

01140

MS21

LD

A,(HL)

;Накладываем полученную маску.

01150

MS3

OR

D

;Команды OR D и OR E заменяются

;на XOR D и XOR E и обратно.

01160

LD

(HL),A

01170

INC

L

;Переходим к следующему байту.

01180

LD

A, L

01190

AND

#1F

;Если вышли за правую границу

01200

JR

Z, MS4

;экрана, то обход.

01210

LD

A, (HL)

;Иначе накладываем маску и на

;соседний байт.

01220

OR

E

01230

LD

(HL),A

01240

MS4

DEC

L

;Переходим на нижнюю линию

01250

INC

IX

;и на следующий байт в шаблоне.

01260

CALL

DAD1

01270

LD

A, H

;Проверяем, вышли ли

01280

CP

#58

;за низ экрана.

01290

RET

NC

;ДА - выход.

01300

DEC

C

;НЕТ - уменьшаем счетчик строк

01310

JR

NZ,MS1

;в стрелке и повторяем фокус.

01320

RET

П 1 Я. "3 п

013 3 0

01340

01350

* Головная программа *

01360

01370

01380

START

LD

HL,#64 64

;Начальные координаты стрелки.

01390

LD

(CRDS),HL

01400

PUSH

IX

01410

Q0

CALL

SCRBF

; Сохраняем...

01420

CALL

FORM

; Формируем...

01430

HALT

; Отдыхаем...

01440

IN

A,(31)

; Опрашиваем...

01450

PUSH

AF

01460

CALL

BFSCR

; Восстанавливаем^„

01470

POP

AF

01480

LD

C,A

01490

LD

E,STEP

01500

LD

D,254

;Задали максимум по Х.

01510

LD

HL,CRDS+1

;Изменяем координаты согласно

01520

BIT

0,C

;тому, что нажали

01530

CALL

NZ, PL

;на джойстике.

01540

BIT

1,C

01550

CALL

NZ,MIN

01560

LD

D, 190

;Максимум по Y.

01570

DEC

HL

;Перешли на координату Y.

01580

BIT

2,C

01590

CALL

NZ, PL

01600

BIT

3,C

01610

CALL

NZ,MIN

01620

BIT

4,C

01630

JR

NZ,EXIT

01640

JR

Q0

01650

в

;

01660

PL

LD

A,(HL)

01670

LD

B, E

01680

L0

CP

D

01690

JR

Z, END

01700

INC

A

01710

DJNZ

L0

01720

END

LD

(HL),A

01730

RET

01740

в

;

01750

MIN

LD

A,(HL)

01760

LD

B, E

01770

INP

AND

A

01780

JR

Z, END

01790

DEC

A

01800

DJNZ

INP

01810

LD

(HL),A

01820

RET

01830

в

;

01840

EXIT

LD

HL,(STS)

01850

PUSH

HL

01860

LD

A, H

01870

AND

#18

01880

RRCA

01890

RRCA

01900

RRCA

01910

OR

#58

01920

LD

B, A

01930

LD

C, L

01940

POP

HL

01950

POP

IX

01960

RET

01970 01980

; Конец программы

Комментарий "ИНФОРКОМА "

В строках 220-310 программы задается рисунок стрелки. Две маски (по OR и по XOR)

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

Набор программы был выполнен нами при помощи ассемблера ZEUS. Для тех, кто хочет без лишних хлопот с ассемблером получить готовую программу, приводим шестнадцатеричный дамп (с контрольными суммами) кодового блока с адреса 40000. Его длина 328 байтов.

Теперь несколько слов тем, кто захочет усовершенствовать программу. Приведенный вариант программы работает только от KEMPS TON-джойстика (см. строку 1440). Это может оказаться не для всех удобно. Поэтому со своей стороны мы можем порекомендовать ввести дополнительные строки для опроса клавишей, например, SINCLAIR-джойстика, сохранив и KEMPSTON.

9C40

FB

C3

27

9D

00

00

00

00

5E

9C48

00

00

00

00

00

00

00

00

E4

9C50

00

00

00

00

00

00

00

00

EC

9C58

00

00

00

00

00

00

00

00

F4

9C60

00

00

00

00

00

00

C0

E0

9C

9C68

F0

F8

FC

FE

FF

FE

FC

1C

FB

9C70

0E

0E

07

07

03

C0

A0

90

29

9C78

88

84

82

81

86

B4

14

0A

7B

9C80

0A

05

05

03

2A

64

9C

4C

A9

9C88

45

78

CD

B1

22

22

62

9C

A1

9C90

11

44

9C

06

0F

E5

0E

02

27

9C98

7E

12

2C

13

0D

20

F9

E1

0A

9CA0

CD

A6

9C

10

F0

C9

24

7C

B4

9CA8

E6

07

C0

7C

D6

08

67

7D

2F

9CB0

C6

20

6F

D0

7C

C6

08

67

22

9CB8

C9

21

1A

77

22

98

9C

CD

F2

9CC0

84

9C

21

7E

12

22

98

9C

83

9CC8

C9

3A

65

9C

E6

07

08

DD

3A

9CD0

21

66

9C

CD

F6

9C

DD

21

EC

9CD8

0E

9D

DD

36

00

AA

DD

36

EF

9CE0

09

AB

DD

E5

DD

21

75

9C

01

9CE8

CD

F6

9C

DD

E1

DD

36

00

B4

9CF0

B2

DD

36

09

B3

C9

0E

0F

F3

9CF8

2A

62

9C

50

58

08

47

08

BB

9D00

05

04

DD

56

00

28

06

CB

D2

9D08

3A

CB

1B

10

FA

7E

B2

77

76

9D10

2C

7D

E6

1F

28

03

7E

B3

B7

9D18

77

2D

DD

23

CD

A6

9C

7C

E4

9D20

FE

58

D0

0D

20

D5

C9

21

CF

9D28

64

64

22

64

9C

DD

E5

CD

3E

9D30

84

9C

CD

C9

9C

76

DB

1F

8F

9D38

F5

CD

B9

9C

F1

4F

1E

02

4C

9D40

16

FE

21

65

9C

CB

41

C4

E3

9D48

62

9D

CB

49

C4

6C

9D

16

DB

9D50

BE

2B

CB

51

C4

62

9D

CB

80

9D58

59

C4

6C

9D

CB

61

20

16

7D

9D60

18

CD

7E

43

BA

28

03

3C

C4

9D68

10

FA

77

C9

7E

43

A7

28

DF

9D70

F9

3D

10

FA

77

C9

2A

62

19

9D78

9C

E5

7C

E6

18

0F

0F

0F

3D

9D80

F6

58

47

4D

E1

DD

E1

C9

67

Другим, более изощренным моментом является изменяемая скорость перемещения стрелки

по экрану. Эти строки мы адресуем тем, кто захочет использовать предложенный интерфейс в серьёзной программе, претендующей на повышенное удобство для пользователя. Как Вы видите из приведенного листинга, скорость перемещения стрелки постоянна и зависит от значения, заданного в строке 330. Слишком быстрая скорость перемещения стрелки приведёт к необходимости более точно "прицеливаться" для попадания в нужное место и к более быстрой реакции Вашей руки, но, в то же время, не потребуется много времени для того, чтобы "перегнать" стрелку от одного края экрана к другому. При медленном перемещении всё наоборот. Великолепная точность попадания и удобство "прицеливания" сочетаются с томительным ожиданием, когда же, наконец, заветная фигурка доползет до нужного поля меню, находящегося почему-то как раз в противоположном конце экрана.

Проблему можно решить следующим образом. Организуется цикл подсчёта количества прерываний, произошедших с момента нажатия любой клавиши перемещения джойстика до её отпускания. При этом начальная скорость перемещения стрелки - минимальна. Если, скажем, через 64 или 32 прерывания кнопка не отпущена, изменяется параметр, задающий скорость перемещения стрелки - её движение убыстряется. Как только кнопка отпущена - счётчик тут же обнуляется и восстанавливается начальное значение параметра, определяющего скорость. Можно ограничиться одной ступенью увеличения скорости, а можно продолжать отсчёт дальше. Если ещё через 32 цикла кнопка не отпущена - скорость увеличивается ещё больше (в одной из версий ART STUDIO, например, увеличение скорости четырехступенчатое - управление при этом очень удобно). Это, так называемое интеллектуальное управление. Конечно, все числовые параметры должны быть тщательно подобраны и сбалансированы для обеспечения максимального удобства управления.

Применение прерываний 2-го рода для создания резидентных процедур всегда представляет особенную трудность для тех, кто делает только первые шаги в машинном коде. Мастерское же владение этим инструментом открывает перед программистом огромные возможности для создания собственных программ. Мы довольно редко получаем письма от наших читателей, в которых есть примеры подобных процедур, да и те далеко не всегда выдерживают наше тестирование. Поэтому мы особенно рады предложить нашим читателям работу, выполненную сотрудником Крымской Астрофизической Обсерватории. Программа прошла тестирование без проблем.




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Мысли читателей - Очередной план спасения Спектрума.
Статьи - Радиолюбитель news
Ответы на письма №1-3.
Двигатель торговли - Куплю м/с К1107ПВ1, 1810ВТ37, 1816ВЕ35, 170АП2, 170УП2
Новости - дела у Real Software из Бреста обстоят не лучшим образом: часть людей покинула спектрум, оставив на произвол одного Pawel/rs...

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