ZX Format
#01
31 октября 1995 |
|
IS-DOS - программистам: Оконная система IS-DOS
Рубрика "IS-DOS - программистам". No 1
Елисеев В. А.
"Оконная система IS-DOS"
(журнальный вариант)
(C) PENCRAFT 1995
(C) IskraSoft 1995
Одним из несомненных достоинств опе-
рационной системы IS-DOS можно считать
удобный оконный интерфейс, позволяющий
программисту красиво оформить свою прог-
рамму.
Идея оконного интерфейса, отсутство-
вавшего в традиционной операционной сис-
теме ZX Spectrum, всегда привлекала к се-
бе программистов, мечтавших, чтобы их
произведения выглядели на профессио-
нальном уровне. Одним из шедевров окон-
ной технологии по праву считается знаме-
нитый "Оконный интерфейс Питера Кука",
использовавшийся во многих играх, в фир-
менных программах Art Studio, ASTRO и да-
же в некоторых творениях отечественных
програмистов - DCU, FUT, STM, F Commander
и т.д.
Разработчики системы IS-DOS, естес-
твено не остались в стороне и, осознавая
важность и необходимость реализации в
профессиональной системе оконной техноло-
гии, выделили под нее целый уровень сис-
темы, получивший название WIND.SYS.
Уровень WIND.SYS содержит 23 рестар-
та, обеспечивающих работу с окнами, стро-
ками символов, курсором и т.п. При помо-
щи этих рестартов можно организовать вы-
вод информации на дисплей, оформление ра-
бочего экрана, а также организовать диа-
лог с пользователем при помощи строково-
го редактора.
К сожалению, объем этой статьи не поз-
воляет подробно рассмотреть все 23 рес-
тарта, составляющих уровень WIND.SYS,
поэтому речь сейчас пойдет только о 19 из
них, относящихся непосредственно к рабо-
те с окнами и текстовой информацией в
них. Описанию строкового редактора и сис-
темы управления файловыми панелями будет
посвящена отдельная статья в рубрике
"IS-DOS - программистам".
Создание окон.
Работа любого оконного интерфейса на-
чинается, естественно, с процедуры откры-
тия окна. Окно в системе IS-DOS имеет
следующую структуру (см. рис 1):
┌───────────────────────────────────────┐
│ │
│ │ область окна │ │
│ │ │ рабочая область окна │ │ │
│ │ │ │ │ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓ ░░░░░░░░░░░░░░░░░░░░ ▓▓▒▒ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒ │
│ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒ │
│ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │
│ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │
│ │
│ ▓▓▓ - область рамки │
│ │
│ ░░░ - область печати │
│ │
│ ▒▒▒ - область тени │
│ │
│ - поля │
├───────────────────────────────────────┤
│ Рис. 1: Структура окна в IS-DOS │
└───────────────────────────────────────┘
Область окна определяется значениями
XS (X-size) и YS (Y-size), и измеряется в
знакоместах 8*8 пикселей, область рамки
имеет ширину в 8 пикселей (1 знакоместо
8*8) по всему периметру окна, следова-
тельно, размеры рабочей области окна рав-
ны XS-2 и YS-2. Размер и расположение в
окне поля печати, а также ширина левого и
правого полей определяются prnt pos. и
print size и измеряются в знакоместах
6*8. Верхний и нижний край поля печати
ограничивается только областью рамки.
Область тени представляет собой окан-
товку нижней и правой сторон окна толщи-
ной в 1 знакоместо 8*8 и с отступом в 1
знакоместо от левой и верхней границ об-
ласти окна.
wt (#61)
В системе IS-DOS для открытия окна
используется рестарт wt (код #61). Он
осуществляет формирование на экране окна
с параметрами, заданными в специальной
таблице, называемой "вектором окна".
Адрес вектора окна на момент вызова рес-
тарта должен находиться в регистровой па-
ре IX, при этом содержимое регистра A оп-
ределяет внешний вид окна следующим обра-
зом:
7-й бит, установленный в 1 делает от-
крываемое окно "прозрачным", т. е. окно
открывается только изменением атрибутов,
а пиксели внутри него не сбрасываются.
Остальные биты определяют вид рамки
окна:
000000 - одинарная рамка
000010 - двойная рамка
Все остальные значения приводят к от-
крытию окна без рамки.
Таким образом, формат задания внешне-
го вида окна можно представить в виде
таблицы:
╔═════════╦══════════╤═════════╤════════╗
║ ║ одинарная│ двойная │ без ║
║ Окно ║ рамка │ рамка │ рамки ║
║ ║ │ │ ║
╟─────────╫──────────┼─────────┼────────╢
║ ║ │ │ A=#81 ║
║ прозрач-║ A=#80 │ A=#82 │ A=#83- ║
║ ное ║ │ │ #FF ║
║ ║ │ │ ║
╟─────────╫──────────┼─────────┼────────╢
║ ║ │ │ A=#01 ║
║ непроз- ║ A=#00 │ A=#02 │ A=#03- ║
║ рачное ║ │ │ #7F ║
║ ║ │ │ ║
╚═════════╩══════════╧═════════╧════════╝
Итак, процедура открытия окна в сис-
теме IS-DOS выглядит следующим образом:
LD IX,WIND ;загрузка в IX
;адреса вектора
;окна
LD C,#61 ;загрузка в C кода
;рестарта wt
LD A,n ;загрузка в A зна-
;чения, определяю-
;шего вид окна
RST #10 ;вызов рестарта
Структура вектора окна:
WIND DEFB #00 ;X-координата верх-
;него левого угла
;окна в знакоместах
;8*8 пикселей
DEFB #00 ;Y-координата верх-
;него левого угла
;окна в знакоместах
;8*8 пикселей
значения координат отсчитываются от лево-
го верхнего угла экрана
DEFB #0F ;высота окна в зна-
;коместах 8*8
DEFB #0F ;ширина окна в зна-
;коместах 8*8
DEFB %00000111 ;цвета окна
цвета кодируются стандартным образом:
бит 7 - flash
бит 6 - bright
биты 5...3 - paper
биты 2...0 - ink
DEFB %00000001 ;цвета тени окна
Примечательно, что в цветах тени ок-
на можно задавать как цвет paper, так и
цвет ink, что позволяет сделать видимой
часть информации, на которую падает тень
от окна и обеспечивает максимальную ес-
тественность восприятия. Если байт цве-
тов тени равен #FF, то тень не выводится.
DEFB #01 ;X-координата для
;процедуры печати
;текста в окне
DEFB #12 ;ширина поля печа-
;ти в окне
Последние два параметра выражаются в
знакоместах размером 6*8, а не 8*8 как
остальные, это сделано потому, что такую
систему отсчета используют все рестарты
печати в IS-DOS. Значение X-координаты
печати абсолютное и отсчитывается не от
левой границы окна, а от левой границы
экрана. Перевод координат окна в кооорди-
наты печати и обратно можно осуществить
по формулам:
(1) n=N*8/6
(2) N=n*6/8,
где n - значение в знакоместах 6*8,
а N - значение в знакоместах 8*8.
Y-координата печати не задается, так
как большинство рестартов печати самос-
тоятельно отсчитывает ее от верхней стро-
ки окна.
На экране может быть открыто нес-
колько окон,при этом текущим будет счи-
таться то окно, адрес вектора которого
находится в регистровой паре IX. В целях
более рационального использования объема
ОЗУ, информация, закрываемая окном в мо-
мент его открытия не сохраняется, поэто-
му, если Вам вдруг понадобилось вер-
нуться в предыдущее окно, то придется его
открывать заново.
Рассмотрим простейший пример. Задача
- создать в точке с координатами X=5 и
Y=3 окно размером 28*16 знакомест с двой-
ной рамкой, синей бумагой, белыми черни-
лами и с черно-синей тенью, поле печати
текста определить с отступом в 1 знако-
место от левой и в 5 знакомест от правой
границы окна.
Для создания этой несложной програм-
мы кроме рестарта открытия окна wt(#61)
нам понадобятся еще три подпрограммы -
очистки экрана, ожидания нажатия клавиши
и возврата в IS-DOS.
Действие этих подпрограмм основано на
других рестартах системы IS-DOS, которые
будут описаны в следующих номерах журнала, а по-
ка что просто запомните их:
CLS LD C,#73 ;рестарт cls
RST #10 ;для очистки экрана
RET
WAIT LD C,#07 ;рестарт ttyin
RST #10 ;для ожидания нажа-
RET ;тия клавиши
EXIT XOR A ;стандартный выход
LD A,#F4 ;в IS-DOS
RET
Итак, рассмотрим Листинг 1:
;****************************************
;Листинг 1 Пример создания окна
;Исходные данные:
; X-coord (X) = 5
; Y-coord (Y) = 3
; X-size (XS) = 20
; Y-size (YS) = 16
; W.Colors(WC) = %00001111
; S.Colors(SC) = %00000001
; L.Margin(LM) = 1
; R.Margin(RM) = 5
ORG #5D64
;основная программа
START CALL CLS ;вызов процедуры
;очистки экрана
LD IX,WIND ;адрес вектора окна
LD C,#61 ;код рестарта wt
LD A,2 ;код двойной рамки
RST #10 ;вызов рестарта
CALL WAIT ;вызов процедуры
;ожидания клавиши
JP EXIT ;переход на проце-
;дуру возврата в
;IS-DOS
;вектор окна
WIND DEFB 5
DEFB 3
DEFB 16
DEFB 20
DEFB %00001111
DEFB %00000001
DEFB 8
DEFB 20
;Данные для print position (печать с
;отступом в 1 знакоместо 6*8 от левой
;границы окна) получены путем расчета по
;формуле (3):
; (3) PP=X*8/6+LM,
;где PP - print pos. в знакоместах 6*8
; X - X-коорд. окна в знакоместах 8*8
; LM - левое поле в знакоместах 6*8
;Данные для print size получены путем
;расчета по формуле (4):
; (4) PS=XS*8/6-LM-RM,
;где PS - print size в знакоместах 6*8
; XS - размер окна в знакоместах 8*8
; LM - левое поле в знакоместах 6*8
; RM - правое поле в знакоместах 6*8
;дополнительные процедуры
CLS LD C,#73 ;рестарт cls
RST #10 ;для очистки экрана
RET
WAIT LD C,#07 ;рестарт ttyin
RST #10 ;для ожидания
RET ;нажатия клавиши
EXIT XOR A ;стандартный выход
LD A,#F4 ;в IS-DOS
RET
;****************************************
В результате выполнения программы
Листинг 1 на экране должно получиться ок-
но, соответствующее изображению на рис.2,
в противном случае проверьте пра-
вильность набора программы.
┌───────────────────────────────────────┐
│ │
│ │
│ ╔═══════════════════╗ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ╚═══════════════════╝▒ │
│ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │
│ │
│ │
├───────────────────────────────────────┤
│ Рис. 2: результат работы программы │
│ Листинг 1 │
└───────────────────────────────────────┘
...
box (#62)
Следующий рестарт box(#62) позволяет
нарисовать или стереть в области рамки
окна любую возможную рамку, или любую из
ее сторон в любом сочетании. Поскольку
ширина области рамки в окне IS-DOS равна
8 пикселям, всего возможно 8 различных
одинарных рамок. Вызывая рестарт box нес-
колько раз можно рисовать двойные, трой-
ные и даже счетверенные рамки, а также
рамки различной толщины - всего 256 ком-
бинаций.
В качестве входных параметров рес-
тарт box(#62) использует вектор окна, ад-
рес которого задается в регистре IX, а
также значения отступа от края окна по Y
и по X в пикселях, задаваемые в регис-
трах D и E соответственно, и содержимое
регистра A, определяющее, что именно тре-
буется нарисовать или стереть.
Содержимое регистра A определяется
следующим образом:
бит 7=0 - рисовать, 1 - стирать
биты 6...4 - не используются
остальные биты показывают, с какими из
сторон рамки производится операция:
бит 3=0 - левая сторона рамки
бит 2=0 - правая сторона рамки
бит 1=0 - верхняя сторона рамки
бит 0=0 - нижняя сторона рамки
Для битов 3...0 возможны любые сочетания.
Обшая форма процедуры рисования/сти-
рания рамки выглядит так:
LD IX,WIND ;адрес вектора окна
LD C,#62 ;код рестарта box
LD D,N1 ;отступ по Y
LD E,N2 ;отступ по X
LD A,n ;что делать
RST #10 ;вызов рестарта
Для задания значений отступа рамки
предпочтительнее использовать числа от 0
до 7, причем при загрузке в регистры D и
E значения 0 рамка будет выведена по на-
ружному краю окна, а при загрузке значе-
ния 7 - по внутреннему краю области рам-
ки. Значение 8 даст тот же эффект, что и
0, 9 -тот же, что и 1 и т.д.
Рассмотрим пример. В качестве основы
возьмем Листинг 1, но изобразим сначала
окно без рамки, а потом выведем двойную
рамку так, чтобы ее наружная линия была
вдвое шире внутренней, после чего сде-
лаем левую и правую стороны наружной рам-
ки одинарной толщины.
;****************************************
;Листинг 2 Пример рисования рамки окна
ORG #5D64
;открытие окна
START CALL CLS ;очистка экрана
LD IX,WIND
LD C,#61
LD A,1 ;окно без рамки
RST #10
CALL WAIT
;рисование наружной рамки двойной толщины
;производится в два приема
LD IX,WIND ;адрес вектора окна
LD C,#62 ;код рстарта box
LD D,0 ;отступ по Y
LD E,0 ;отступ по X
LD A,%00000000
;все биты равнеы 0 - рисовать всю рамку
RST #10
LD IX,WIND
LD C,#62
LD D,1
LD E,1
LD A,%00000000
RST #10
CALL WAIT
;рисование внутренней рамки
LD IX,WIND
LD C,#62
LD D,3
LD E,3
LD A,%00000000
RST #10
CALL WAIT
;стирание боковых сторон
LD IX,WIND
LD C,#62
LD D,2
LD E,1
LD A,%10000011
;7-й бит установлен - команда стирания
;установленные 0-й и 1-й биты обозначают,
;не затрагиваемые в этой операции верхнюю
;и нижнюю стороны рамки
RST #10
CALL WAIT
JR EXIT
;вектор окна
WIND DEFB 5
DEFB 3
DEFB 16
DEFB 20
DEFB %00001111
DEFB %00000001
DEFB 8
DEFB 20
;дополнительные процедуры
CLS LD C,#73
RST #10
RET
WAIT LD C,#07
RST #10
RET
EXIT XOR A
LD A,#F4
RET
;****************************************
При необходимости организации рамок,
рисования вертикальных и горизонтальных
линий внутри окна (за пределами области
рамки) также можно пользоваться услугами
рестарта box(#62), однако, для этого при-
дется создать фиктивный вектор окна та-
ким образом,чтобы требуемая рамка вписы-
валась в область рамки этого воображаемо-
го окна.
Поясним на примере:
Пусть необходимо создать внутри окна
(см. Листинг 1) рамку с отступом в 2 зна-
коместа от верхней границы окна, в 4 - от
нижней и в 3 от левой и правой сторон.
Для этого создадим фиктивный вектор
окна WIND1, а для расчета его параметров
воспользуемся следующими формулами:
(5) Y1=Y+UM,
где Y1 - Y-координата рамки,
Y - Y-координата окна,
UM - отступ сверху
(6) X1=X+LM,
где X1 - X-координата рамки,
X - X-координата окна,
LM - отступ слева
(7) YS1=YS-UM-DM,
где YS1 - размер рамки по Y,
YS - размер окна по Y,
UM - отступ сверху,
DM - отступ снизу
(8) XS1=XS-LM-RM,
где XS1 - размер рамки по X,
XS - размер окна по X,
LM - отступ слева,
RM - отступ справа
Все величины измеряются в знакомес-
тах 8*8. Значения цветов выберем такие
же, как и в основном окне, но без тени
(S.Colors=#FF), значения Print pos. и
Print size могут быть любыми.
Итак,
;****************************************
;Листинг 3 Пример рисования внутренних
; рамок при помощи box(#62)
;Исходные данные:
; Up Margin (UM) = 2
; Down Margin (DM) = 4
; Left Margin (LM) = 3
; Right Margin (RM) = 3
ORG #5D64
;открытие окна
START CALL CLS ;очистка экрана
LD IX,WIND
LD C,#61
LD A,2
RST #10
CALL WAIT
;рисовать второе окно не требуется,
;достаточно просто поместить адрес его
;вектора в регистр IX для передачи
;параметров рестарту box
;рисование рамки внутри окна
LD IX,WIND1 ;вектор рамки
LD C,#62
LD D,0
LD E,0
LD A,%00000000
RST #10
CALL WAIT
JR EXIT
;вектор окна
WIND DEFB 5
DEFB 3
DEFB 16
DEFB 20
DEFB %00001111
DEFB %00000001
DEFB 8
DEFB 20
;вектор окна для рамки
WIND1 DEFB 8
DEFB 5
DEFB 10
DEFB 14
DEFB %00001111
DEFB #FF
DEFB #00
DEFB #00
;дополнительные процедуры
CLS LD C,#73
RST #10
RET
WAIT LD C,#07
RST #10
RET
EXIT XOR A
LD A,#F4
RET
;****************************************
В результате работы программы Лис-
тинг 3 на экране должна получиться карти-
на, изображенная на Рис. 3
┌───────────────────────────────────────┐
│ │
│ │
│ ╔═══════════════════╗ │
│ ║ ║▒ │
│ ║ ┌───────────┐ ║▒ │
│ ║ │ │ ║▒ │
│ ║ │ │ ║▒ │
│ ║ │ │ ║▒ │
│ ║ │ │ ║▒ │
│ ║ │ │ ║▒ │
│ ║ │ │ ║▒ │
│ ║ │ │ ║▒ │
│ ║ │ │ ║▒ │
│ ║ └───────────┘ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ║ ║▒ │
│ ╚═══════════════════╝▒ │
│ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ │
│ │
│ │
├───────────────────────────────────────┤
│ Рис. 3: результат работы программы │
│ Листинг 3 │
└───────────────────────────────────────┘
Подобным же образом выполняются вер-
тикальные и горизонтальные линии - они
представляются как стороны воображаемой
рамки и задаются фиктивным вектором окна.
Подбирая содержимое регистров D и E нет-
рудно добиться позиционирования рамки или
линии с точностью до 1 пикселя.
Продолжение следует ...
В следующем номере мы поговорим о другой
не менее важной группе системных рестар-
тов IS-DOS - рестартах печати символов и
строк.
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября