Прикладная графика 1992 г.

Растровая графика - печать нестандартными шрифтами. Шрифты размером менее, чем 8x8. Шрифты размером более, чем 8x8.


2. 8. Печать нестандартными шрифтами.

Воспользовавшись тем, что в данной главе идет речь о раст-
ровой графике и о печати на экране растровых шаблонов, мы не
могли не остановиться и на вопросе о возможности печати растро-
выми шрифтами, отличающимися от стандартно принятых 8X8 пик-
селов. Вопрос этот относится к очень важным, хотя и малоосве-
шенным. можно сказать так. что применение нестандартных шрифтов
в игровых программах имеет более широкий характер, чем освеще-
ние этого вопроса в мировой литературе.

А между тем, коль скоро в предыдущих разделах мы освоили
печать на экране заранее подготовленных шаблонов произвольного
размера, то нам теперь рукой подать до того, чтобы изготовить
шаблоны нестандартных символов и подойти к нестандартным раст-
ровым шрифтам. Более того, мы пойдем дальше и попробуем реали-
зовать такую печать даже из БЕИСИКа с помошью обычного опера-
тора PR INTO, и такая возможность в "Спектруме" предусмотрена."
Ее можно реализовать, организовав новый канал для печати.

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

Е. 5. 1. шрифты размером менее, чем 8X8.

Условимся, что один символ будет иметь размеры в ширину и
в высоту по 5 пикселов. В стандартном символьном наборе для
храненйя шаблона одного символа используются 8 байтов, по одно-
му на каждую пиксельную линию. Причем первый и последний байты,
как правило, равны нулю, этим обеспечивается интервал по верти-
кали между строками текста. Условимся, что наш шаблон одного
символа будет занимать не более 5 пиксельных линий. А для того,
чтобы обеспечить расстояние между строками по вертикали, преду-
смотрим при печати одну пустую пиксельную линию.

Учитывая предложенные.условия, рассчитаем количество выво-
димой на один экран текстовой информации. В одной строке может
■>ыть выведено: г5о/5=51 символ. По вертикали может быть раз-
мешено: 17б/б=29 строк (одна строка - символы по 5 пикселов в
высоту плюс 1 пустая пиксельная линия).

Координаты для вывода символов на экран удобнее задавать
не в пикселах, а в знакоместах, аналогично AT Y,X. но ны, что-
бы значительно не усложнять процедуру печати, координаты будем
задавать не при помоши AT. а при помощи двух системных ячеек,
занося туда значения перед началом печати. В процессе печати
текста значения этих ячеек будем программно менять для того,
чтобы отслеживать текущую позицию печати. Кроме того, опять же
для упрощения процедуры печати, условимся, что по достижении
конца экрана, вывод будет прекращаться. Проверка на необходи-
мость скроллинга и сан скроллинг - достаточно емкая часть про-
цедуры печати, поэтому от них откажемся, уделив особое внимание
тому, как же организовать вывод текста на экран в 29 строк по
51 символу в строке.

Теперь несколько слов надо сказать о символьном наборе,
можно, конечно, использовать символьный набор в стандартном
Формате 8*8 пикселов, задав его таким образом, что символы бу-
дут занимать 5«5 пикселов. Тогда три байта из восьми будут пус-
той тратой памяти, можно сократить эти потери, сформировав сим-
вольный набор так, что на каждый символ будет отведено по 5
байтов. Тогда полный символьный набор для 96 символов будет
иметь объем всего 96»5=480 байтов вместо 768 для стандартного
символьного набора. Можно, в принципе, пойти еше дальше, и со-
кратить недоиспользуемые 3 бита в каждом байте, однако, видимо
это уже нецелесообразно, так как полученная дополнительная эко-
номия (всего-то примерно полторы сотни байтов) частично будет
"съедена" усложнившейся процедурой декодирования, да еше. к то-
му же. из-за этого несколько замедлится работа процедуры печа-
ти. Логичнее, видимо, ограничиться "упаковкой" символьного на-
бора в Формат 5*8 (по 5 байт на символ).

Вручную, конечно, выполнить такую работу трудно, поэтому в
комплект процедуры плотной печати входят две небольшие програм-
мы-утилиты. Во-первых, это "упаковшик" символьного набора из

Формата в*в в Формат 5*8. Он выбрасывает "лишние" три байта
каждого символа и пододвигает следующий символ к предыдущему.
Во-вторых, это "распаковщик", который выполняет противоположную
задачу: "растягивает" упакованный символьный набор до стандарт-
ного формата 8*8 для того, чтобы можно было вносить изменения в
символьный набор при помощи стандартного программного обеспече-
ния. например, "artstudio".

Формирование символьного набора иллюстрирует рисунок 15.
Здесь показан результат работы с русско-латинскин символьным
набором (ASCII, конплект "НС" КОИ-7) в графическом редакторе
"ARTSTUDIO". Обратите внимание: все символы "прижаты" к верх-
нему левому углу поля 8*8 пикселов, занимая, таким образом,
только первые 5 байтов из восьми, ширина символов, по-возмож-
ности, занимает 4 пиксела, однако, там, где это невозможно, на-
пример для букв "Ш". "X", "W" и др. - все пять пикселов. При
этом, правда, не будет разделения с соседним символом. Три вер-
тикальных столбца справа у каждого символа (три младших бита в
каждой байте) вообще не используются.

Полная процедура печати приведена в листинге г. 8.1 ны рас-
положили ее с адре'са АВООН (43776). Утилита-"упаковшик" сим-
вольного набора расположена с адреса АВ80Н (43904), а утилита-
"рзспаковшик" - с адреса АВВ8Н (43960). Весь блок кодов проце-
дуры плотной печати оформлен в Файл "#4"C0DE 43776,256. (Опре-
делим для плотной печати поток #4. ) Упакованный символьный на-
бор расположен сразу же за процедурой печати с адреса АСООН
(44032), и может быть включен в этот же Файл. Значение CHARS
для этого символьного набора будет равно: 44032-32"5=43872
(ЛВ60Н).

на входе в процедуру печати в аккумуляторе должен нахо-
диться код печатаемого символа, а в системных ячейках ABFEH
(44030) и ABFFH (44031) должны быть заданы начальные координаты
печати, соответственно: колонка (0. ..50) и строка (О. ..28).

Листинг 2. 8. 1.

ABOO FE20 CP #20 ; Проверка, не является ли печата-

: емый код управляющим символом.
АВ02 D8 RET с ,Если да. то возврат из пропедуры

; печати.

АВОЗ FE80 CP #80 ; Проверка, не является ли печатае-

; мый код токеном ключевого слова
; или символом блочной графики.
АВ05 DO RET НС ;Если да, то возврат из процедуры.

Следующая часть программы вычисляет координаты в пикселах
места для печати символа по заданным координатам в знакоместах.
Последние заданы при помощи РОКЕ в ячейках ABFEH (координата х)
и ABFFH (координата У). Результат рассчета будет получен в
регистре ВС.

АВ06 F5 PUSH AF :Сохранение на стеке кода печатае-

; мого символа.

АВ07 21FFAB LD HL.#ABFF ;В HL адрес ячейки, в которой на-

;ходится номер строки печати.
АВОА 7Е LD A.(HL) ; Значение, содержащееся там. срав-

АВОВ FE1D CP #1D ; ниваетсяется с максимально

;допустимым (1DH=29 строк),
ABOD D29F1E JP NC.#1E9F ;Если это значение превышено, то

;переход на процедуру REPORT В в

;ПЗУ для вывода сообщения об
:ошибке "Integer out of ranee".
ABio 2B DEC HL ;Теперь в HL адрес ячейки, в ко-

; торой находится значение колонки
; печати.

АВИ 7Е LD A.(HL) ; Значение, содержащееся тан срав-

ав12 fe33 cp #33 ; нивается с максимально допустимым

: <ЗЗН=51 символ в строке).
АВ14 3806 JR С, #АВ1С ;Если результат не превышен, то

; переход на продолжение процедуры
; печати.

АВ16 AF XOR А ;Иначе - переход на новую строку.

АВ17 77 LD (HL), А ; Для этого обнуляется счетчик

АВ16 23 INC HL ;колонок, а счетчик строк

АВ19 34 INC (HL) ; увеличивается на единицу.

ABiA 18ЕЕ JR #АВОА :Возврат на контроль счетчика

; строк, не превышен ли предел.
abic 4f ld С.а ;к этому моменту в аккумуляторе

;находится значение координаты X
; (в знакоместах). Теперь оно и в
; регистре С.

AB1D 87 ADD А. А ;Таким способом производится

ABIE 87 ADD А,А ;умножение этого значения на 5

AB1F 81 ADD А.С ; для рассчета координаты в

: пикселах.

АВ20 4F LD С.А ;Полученная координата X в пикс-

;лах сохраняется в регистре С.
АВ21 23 IHC HL ;Переходим к адресу, где задан

;номер строки печати.
АВ22 7Е LD A.(HL) ; Приняли это значение.

АВ23 47 LD В, А ; Таким способом производится

АВ24 67 ADD А.А :умножение на б для расчета

АВ25 80 ADD А. В ; координаты в пикселах

АВ26 87 ADD А. А ; т. к. шаг строк - б пикселов.

АВ27 47 LD В.А .Значение Y в регистре в.

АВ28 ЗЕАЕ LD А. #АЕ ; Его надо вычесть из числа 174.
АВ2А 90 SUB В ; т. к. отсчет координаты в пикселах

.-ведется из левого нижнего угла.

Максимальное значение координаты У равно 175. однако
выбрана величина 174, т. к. тогда пустая пиксельная линия будет
отделять текст от бордюра, который может иметь тот же цвет, что
и текст. Таким образом предотвращается сливание текста с
бордюром.

АВ2В 47 LD В. А ;Скорректированная координата У

; сохраняется в регистре В.
АВ2С Fi POP AF ; Восстановление кода печатаемого

; символа.

Теперь в аккумуляторе находится код печатаемого символа, а
в регистровой паре ВС - координаты левого верхнего пиксела
его шаблона. Следующая часть программы выполняет печать, а
точнее "копирование" символа по точкам.

AB2D 5F LD Е, А ;Для рассчета адреса шаблона сим-

АВ2Е 1600 LD D.#00 :вола в символьном наборе, надо

:рассчитать дистанцию от начала
;символьного набора. Мы установили
;в DE порядковый номер символа.
АВЗО 2160АВ LD HL.#AB60 :В HL - значение CHARS для упако-

;ванного символьного набора.
АВЗЗ 19 ADD HL. DE ;Добавив к нему пятикратное зна-

АВЗч 19 ADD HL, DE ;чение порядкового нонера,

АВ35 19 ADD HL,DE .получим адрес первого байта.

АВЗб 19 ADD HL, DE ; определяшего интересующий нас

АВ37 19 ADD HL. DE ; шаблон.

АВЗб 1Е05 LD Е. #05 :Организация цикла из 5 шагов для

;сканирования и побитного копиро-
:вания 5 байтов шаблона.
АВЗА С5 PUSH ВС :Сохранение координат для после-

дующего использования.
АВЗВ 7Е LD A. <HL) :В аккумуляторе байт шаблона.

АВЗС В7 OR А : Инициализация Флагов.

AB3D 2611 JR Z.#AB50 ; Если А=0. то не надо продолжать

:печать этой линии и выполняется
;переход на следующую линию.

AB3F 17 RLA ; Если в А не ноль, то ротация для

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

ЛЕЧО ЗООВ JR НС. #AB4D ; Если бит равен нулю, то обход V

; печати.

АВ42 F5 PUSH AF ;Сохранение на стеке

АВ43 Е5 PUSH HL :значений всех регистров, ,

ав44 D5 PUSH DE ; так как они могут быть изменены

АВ45 С5 PUSH ВС ; в процессе работы процедуры PLOT.

АВ46 CDE522 CALL #22e5 ;вызов процедуры PLOT.

АВ49 Ci POP ВС ; Восстановление со стека

АВ4А Di POP DE ; значении всех регистров.

АВ4В El POP HL ;

АВ4С Fl FOP AF ;

AB4D ОС INC С ;Переход к следующему пикселу в

; линии.

АВ4Е 18ЕС JR #АВЗС ; Повторение действий по печати

; точки.

Сюда программа переходит, когда в аккумуляторе не остает-
ся ни одного включенного бита. Нет необходимости продолжать

ротацию содержимого аккумулятора, если он пуст.

АВ50 ID DEC Е ; Уменьшение счетчика линий.

АВ51 Cl POP ВС ; Прежнее значение координат печати

АВ52 2804 JR Z.#АБ58 ; Если счетчик линий обнулен, то

;переход на завершение процедуры.
АВ54 05 DEC В ;Иначе - переход к печати следую-

: шей пиксельной линии (координата
;Y уменьшается на единицу?.
АВ55 23 INC HL ; Переход к следующему байту

;в символьном наборе.
АВ56 18Е2 JR #АВЗА ;Повторение действий по печати

;пиксельнои линии.

Сюда программа переходит, когда печать символа по точкам
завершена и необходимо провести финишную операцию - перейти к
следующей позиции печати.

АВ58 21FEAB LD HL. #ABFE ; В HL - адрес ячейки. В КОТОРОЙ

; задана колонка печати.
АВ5В 34 INC (HL) :Увеличение на единицу этого

;значения - переход к следующему
; знакоместу.

АВ5С С9 RET ; Выход из процедуры печати.

Следующая часть программы - это утилита-упаковшик символь-
ного набора, исходный символьный набор должен быть загружен под
адрес ВОООН (45056). Эта утилита выполняет "упаковку" символь-
ного набора из стандартного Формата 8»8 в Формат 5«8 и пере-
броску. результата в адрес АСООН (44032).

АВ80 2100В0 LD HL. #В000 ; В HL - начало стандартного

;символьного набора.
АВ83 1100AC LD DE.fcACOO ; В DE - начало области для упако-

;ванного символьного набора.
АВ8б 0660 LD В.#60 ;Цикл для всех 96 символов.
АВ68 С5 PUSH ВС ;Сохранение счетчика на стеке.

АВ89 010500 LD ВС. #0005 ; Число перебрасываемых байтов.
АВ8С EDBo LDIR ;Переброска 5 байтов.

АВ8Е 23 IHC HL ;Пропуск

AB8F 23 INC HL ; оставшихся

АВ90 23 INC HL ;трех байтов.

АВ91 CI POP ВС ; Восстановление со стека значения

;счетчика для контроля.
АВ92 10F4 DJNZ #АВ88 ; Если эта процедура проделана не '

; со всеми 96 символами набора.
;то повторение тех же действий.
АВ94 С9 RET :Если все символы обработаны, то

; выход.

эта часть программы представляет собой утшщту-распаков-
шик. Она выполняет противоположную задачу - восстанавливает
стандартный Формат символьного набора.

АВБ8 2100AC LD HL. #АС00 ; В HL - начало упакованного

;символьного набора.

АВВБ 1Ю0В0 LD DE. #БООО ; в DE - начало области для

; стандартного символьного набора.
АВВЕ ОббО LD В.#60 ;Цикл для всех 96 символов набора.
АВСО С5 PUSH ВС ;Сохранение счетчика на стеке.

АВС1 010500 LD ВС.#0005 ;число перебрасываемых байтов.
АВС4 EDBO LDIR ;Переброска 5 байтов шаблона.

АВСб AF XOR А ; Обнуление

АВС7 12 LD (DE).A ; при помоши

ABC8 13 IHC DE ;аккумулятора

АВС9 12 LD (DE). A ;трех

ABCA 13 IHC DE ;оставшихся байтов

АВСБ 12 LD (DE). A ; символьного

ABCC 13 INC DE i набора.

ABCD Cl POP ВС ; Восстановление со стека значения

;счетчика для контроля.
АБСЕ 10F0 DJHZ #АВСО ;Если эта процедура проделана не

; со всеми символами набора, то
; повторение тех же действий.
ABDO С9 RET ;Если все символы обработаны.

; то выход.

Программные переменные, используемые в работе.

ABFE 00 DEFB ;Колонка печати символа.

ABFF 00 DEFB ; Строка печати символа.

приведенная процедура печати может вызываться из БЕИСИКа
или непосредственно из машинного кода, когда происходит выпол-
нение процедуры печати RST ЮН. При этом, как уже говорилось,
код печатаемого символа должен находиться в аккумуляторе. Но
перед этим необходимо привязать новую пропедуру печати к како-
му-нибудь потоку. Для этого надо предусмотреть инициализирую-
щую подпрограмму, которая будет это выполнять.

Бейсик-программа, приведенная в листинге 2.8.2. демон-
стрирует работу новой процедуры печати.

листинг г. в. г.

1 GO то ю

2 BORDER 7: PAPER 7: INK 0: CLEAR 40000

3 LOAD "#4"CODE 43776

4 LOAD "5*5.fnt"CODE 45056

10 RANDOMIZE 43776: POKE 23566.PEEK 23670:

POKE 23569, PEEK 23671
20 POKE 23590.196: POKE 23591.21:

POKE 23592.63

30 RANDOMIZE (23588-(PEEK 23631+256«PEEK 23632)«•1+65536)
40 POKE 23582.PEEK 23670: POKE 23583.PEEK 23671
90 RANDOMIZE USR 43904
100 LET X=0: LET У=0: GO SUB 1000
110 FOR A= 32 TO 127: PRINT #4: CHRS A: NEXT A
120 GO TO 110
1000 POKE 44030.x: POKE 44031, У: RETURN

Автостарт программы происходит со строки 2, после чего
загружаются блоки кодов: "#4"CODE - это сама процедура печати,
представленная выше, и "5*5. fnt"CODE - это исходный символьный
набор стандартного Формата 8*8. заготовленный при помоши
графического редактора или редактора символов. Формирование
нового канала, подключенного к потоку #4. выполняется в
строках 10... 40. Адрес процедуры плотной печати <4377б = АВ00Н)
задается в строке 10.

Строки 10 и 20 задают информацию по каналу:

- строка Ю - процедуру #PRINT:

- строка 20 - процедуру #INPUT.

Адреса обоих этих процедур должны быть заданы для любого
канала. Так как для вывода на экран предусмотрена только проце-
дура PRINTS, то для INPUT в строке 20 задается адрес 15С4Н.
как для основного экрана, это обеспечивает вывод сообщения об
ошибке, "invalid stream" при попытке сделать INPUT #4. строка
30 обеспечивает правильную работу инициализирующей подпрограм-
мы. независимо от наличия или отсутствия у Вас интерфейса дис-
ковода. Необходимое смешение информации о каналах рассчитывает-
ся, учитывая значение систеннои переменной CHANS.

Строка 90 "упаковывает" символьный набор стандартного Фор-
мата е»е в Формат 5*6 и переносит его в рабочую область, под
адрес АСООН (44032).

здесь надо сказать о том. что эта БЕЙСИК-программа всего
лишь демонстрирует возможности печати и потому все подгоняется
под простоту внесения изменении. Если Вы захотите внести изме-
нения в символьный набор, то легко сможете это сделать при по-
мощи графического редактора, так как исходный ("неупакованный")
символьный набор всегда у Вас под рукой - Файл "5»5fnt"CODE. Вы
можете его легко изменить и проанализировать результаты. Когда
Вы решите, что в таком виде символьный набор Вас устраивает, то
можно сохранить "упакованный" символьный набор на ленте вместе
с самой процедурой печати 1так как сам по себе он все равно
смысла не имеет». Это можно сделать командой: SAVE "#4"CODE
43776.736. к блоку кодов длиной 256 байтов добавляются по 5
байтов для всех 96 символов.

Строка 100 при помощи подпрограммы 1000 задает начальную
позицию печати: о строка и о колонка, т. е. левый верхний угол
экрана. Строка 110 выполняет демонстрационную печать по потоку
#4. который подключен к новой процедуре печати. По достижении
последнего знакоместа в последней строке печать прекращается с
сообщением об ошибке, как это предусмотрено, если позиция печа-
ти выходит за установленные пределы. Результат работы программы
показан на Рис. 16.

Исходный символьный набор, как ухе говорилось. Вы можете
сформировать при помоши редактора символьного набора или гра-
фического редактора. Но если Вы по какин-то причинам не можете
поступить таким образом, то ниже приводится дамп уже упакован-
ного символьного набора (480 байт».

лсоо:

оо

00

00

00

00

го

го

го

: ОС

лсов:

00

го

50

50

00

00

00

50

:С4

ACIO:

F8

50

F8

50

70

28

70

АО

:F4

АС18:

70

С8

DO

го

58

98

бо

БО

:9С

Асго:

А8

90

69

го

40

00

00

00

:СС

АС28:

10

го

го

го

10

40

го

го

:D4

лсзо:

го

40

50

го

70

го

50

00

:вС

АСЗв:

го

70

го

00

00

00

00

го

:В4

АС40:

40

00

00

78

00

00

00

00

:А4

АС48:

00

60

60

08

10

20

40

80

:ЛС

АС 50:

60

90

90

90

60

20

60

го

:0С

АС 58:

го

70

60

90

20

40

F0

ЕО

:В4

лево:

10

60

10

ЕО

90

90

F0

ю

: ВС

ЛС68:

ю

F0

80

ЕО

10

ЕО

60

во

:44

АС70:

ЕО

90

60

F0

10

20

40

40

:8С

АС78:

60

90

60

90

60

60

90

70

:С4

лево:

10

60

00

20

00

20

00

00

: DC

АС88:

го

00

го

40

00

го

40

го

: 34

АС90:

00

00

70

00

70

00

00

40

:5С

АС98:

го

40

00

60

10

20

00

го

: 54

АСАО:

70

ВО

ВО

80

70

60

90

90

АСА8:

F0

90

ЕО

90

ЕО

90

ЕО

60

F4

АСВО:

90

80

90

60

ЕО

90

90

90

.ЕС

АСВ8:

ЕО

F0

80

ЕО

80

F0

F0

80

74

АССО:

ЕО

80

80

60

80

ВО

90

60

,СС

АСС8:

90

90

F0

90

90

70

20

20

54

ACDO:

20

70

30

10

10

90

60

90

DC

ACD8:

АО

СО

АО

90

80

80

80

80

14

АСЕО:

F0

88

D8

А8

88

88

90

DO

F4

АСЕ8:

ВО

90

90

60

90

90

90

60

D4

ACFO:

ЕО

90

ЕО

80

80

60

90

90

ACF8:

ВО

70

ЕО

90

ЕО

АО

90

60

А4

ADOO:

80

60

10

60

70

20

20

20

CD

AD08:

20

90

90

90

90

60

90

90

95

AD10:

90

F0

60

А8

А8

А8

F8

50

DD

AD18:

90

90

60

90

90

88

50

20

5D

AD20:

20

20

F0

10

60

80

F0

30

0D

AD28:

20

20

20

30

80

40

20

10

55

AD30:

08

60

20

20

20

60

20

70

95

AD38:

20

20

20

00

00

00

00

F8

3D

AD40:

30

40

F0

40

F0

60

90

90

FD

AD48:

F0

90

ЕО

80

ЕО

90

ЕО

АО

С5

AD50:

АО

АО

F0

10

30

50

50

50

5D

AD58."

F8

FC

80

ЕО

80

F0

70

А8

D5

AD60:

А8

70

20

70

40

40

40

40

В5

AD68:

90

90

60

90

90

90

90

ВО

85

AD70:

DO

90

60

90

ВО

DO

90

90

0D

AD78:

АО

СО

АО

90

30

50

5Q

50

D5

AD80:

90

88

D8

А8

88

88

90

90

F5

AD88:

F0

90

90

60

90

90

90

60

В5

AD90:

F0

90

90

90

90

70

90

70

DD

AD98:

50

90

ЕО

90

ЕО

80

80

60

D5

ADAO:

90

80

90

60

70

20

20

20

1D

ADA8:

20

90

90

70

10

60

А8

А8

С5

ADBO.

70

А8

А8

ЕО

90

ЕО

90

ЕО

DD

ADBS:

SO

80

EO

90

EO

90

90

DO

. A5

ADCO:

BO

DO

60

90

20

90

60

88

.75

ADC8:

A8

A8

A8

F8

EO

10

70

10

:D5

ADDO:

EO

AS

A8

A8

F8

08

90

90

•75

ADD8:

70

10

10

CO

40

60

50

60

: 25

Число в конце каждой строки после двоеточия - это кон-
трольная сумма строки. Она поможет Вам при наборе этого блока
кодов. Для набора блока кодов можно воспользоваться программой
шестнадцатиричного ввода, которая приведена в листинге 2. 6. 3.
Данные вводятся непосредственно при помоши INPUT Периодически,
вводя "S". вы имеете возможность сохранить на ленте то, что уже
введено. Приведенные выше коды напечатаны вразрядку, да еше с
разделителями ":". это сделано для удобочитаемости данных. Вам
при наборе надо будет вводить их подряд, например для первой
строки:

АС0000000000002020200С [ENTER]

Никаких пробелов или двоеточий вводить не надо. Ошибки,
допущенные при вводе, будут отмечены звуковым сигналом, после
чего Ван будет предложено повторить ввод.

Листинг 2. 8. 3

1 GO ТО 100

2 LOAD "5*5. fnf'CODE

4 GO ТО О

5 SAVE "INPUT" LINE 2' STOP

100 BORDER 7: PAPER 7: INK 0: CLEAR 29999

110 DIM a(10)

120 DEF FN A(a$> =(CODE a*(l>-48-(7 AND at(1>>"9")>«16 +
(CODE ai(2>-48-(7 AND a$<2)>"9"))
1000 POKE 23658.8 INPUT "DATA:"; LINE h*
1010 IF h*="S" THEN GO TO 2000
1020 LET a$=h«
1030 LET sum=o
1040 FOR 1=1 TO 2
1050 LET b$=a*(2«l-l TO 2*1»

1060 LET ail)= FN Alb»)
1070 NEXT 1

1080 LET add=ail)«256*ai2)
1090 LET sum=a(l)*a<2)
1100 FOR 1=3 TO 10
1110 LET b»=h»(2«l-l TO 2*1)
1120 LET a(l)=FN Alb»)
1130 LET sum=sum»a(l)
1140 POKE add, ail)
1150 LET add:add+1
1160 NEXT 1

1170 LET b»=h»(2l TO )

1180 LET CS=FN Alb»)

1190 LET CSl=Sum-256«INT (Sum/256)

1200 IF csocsi THEN PRINT a»; INVERSE 1; " ERROR ! ":
BEEP 1.0: LET add=add-8: GO TO 1000
1210 PRItyT a»( TO 4): GO TO 1000
2000 SAVE "5 «5. flit "CODE 44032,480
2010 VERIFY "5*5. fnt'CODE
2020 CLS : PRINT a»< TO 4): GO TO 1000

Набрав эту БЕЙСИК-программу, сделайте RUN 5 для записи ее
на магнитную ленту (автостарт со 2-й строки обеспечит в даль-
нейшем автоматическую подгрузку уже частично набранного кодово-
го Файла), после этого запустите программу RUN и начинайте
ввод Файла "5*5. fnt" CODE. При перерывах в работе сохраняйте
его на магнитной ленте, вводя "S".

2. 8. 2. Шрифты размером более, чем 8X8.

Аналогично тому, как была организована процедура плотной
печати, когда размер символа был 5*5 пикселов, может быть орга-
низована .процедура печати, когда размер одного символа превыша-
ет 8*8 пикселов, это может потребоваться для печати символов
повышенного качества (например, "объемный" шрифт с тенью).

Самое простое - использовать для печати одного символа 4
знакоместа: два по горизонтали и два по вертикали Однако, для
96 символов набора потребуется 768*4=3072 байта памяти! Да и
сами символы размером 16»16 пикселов могут оказаться слишком
крупными для размещения достаточного количества информации на
одном экране. Вот, если бы можно было печатать символами разме-
ром крупнее, чем 8*8. но мельче, чем 16«16. т.е. произвольными
символами.

В принципе, раз мы однажды уже реализовали процедуру плот-
ной печати, то. используя те же принципы, можно реализовать и
другую процедуру, назовем ее процедурой качественной печати.

Процедура качественной печати выполняет печать символами с
шагом в высоту 13 пикселов и в ширину 12 пикселов. При этом на
экране умещается 176/13=13 строк и в каждой строке может быть
напечатано по 256/12=21 символу. Условимся, аналогично тому,
как это было сделано в процедуре плотной печати, что высота
символа не может превышать и пикселов, а 2 пустые линии будем
использовать для разделения строк. Шаблон каждого символа в
символьном наборе будет состоять из двух половин: левой и пра-
вой. Каждая половина будет состоять из 11 байтов, то есть шаб-
лон одного символа будет занимать 22 байта памяти. Всего на та-
кой символьный набор будет отведено 22*96=2112 байтов. Это за-
метно меньше, чем в том случае, когда используется печать 1б«1б
пикселов. По причинам, указанным ранее, мы не будем заниматься
еше и экономией недоиспользуемых ч младших битов в правой поло-
вине символа.

Условимся, что расположение байтов в символьном наборе.

определяющих шаблон символа, будет таким, как показано на

t

Рис. 17. Ножно применить и другой вариант. - это непринципиаль-
но. однако надо что-то принять за основу и в дальнейшем придер-
живаться этого условия. Такой символьный набор может быть сфор-
мирован при помоши обычных символьных наборов, если один символ
исполнять из четырех стандартных символов, причем расположены
они должны быть определенным образом, как показано на Рис. 18.

При помоши таких четверок задается каждый символ для ка-
чественнои печати. Таким образом, для того, чтобы сформировать
символьный набор из 96 символов, нам нужны четыре стандартных
символьных набора. В первом - будут заданы 24 символа с кодами
с 32 ("пробел") по 55 ("7"); во втором - с 56 ("в") по 79
("О"); в третьем - с 60 i"P") по 103 ("в"); в четвертом - с 104
i"h") по 127 ("копирайт").

К вопросу о формировании такого символьного набора мы еше
вернемся, а пока предположим, что он уже сформирован и располо-
жен. как и в процедуре плотной печати, начиная с адреса АСООН
144032). Значение CHARS для такого символьного набора будет
равно: 44032-22*32-43326 (А940Н).

Процедура качественной печати приведена в листинге 2. 6. 4.
Она в основной похожа на процедуру плотной печати, имеет анало-
гичное построение, расположена в тех же адресах и имеет те же
входные параметры.

Листинг 2. 6. 4

АВОО FE20 CP #20 :Проверка, не является ли печатае-

;мыи код управляющим символом.
АВ02 D8 RET С ;Если да. то возврат из процедуры

; печати.

АВОЗ FE80 CP #80 ;Проверка, не является ли печ^тае-

; мыи код токеном ключевого слова
;или символом елочной графики.
АВ05 DO RET NC : Если да. то возврат из процедуры.

Следующая часть программы вычисляет координаты в пикселах
места для печати символа по заданным координатам в знакоместах.
Последние заданы при помощи РОКЕ в ячейках ABFEH (координата X)
Л ABFFH (координата У). Результат рассчета будет получен
в регистре ВС.

АВОб F5 PUSH AF ; Сохранение на стеке кода печатае-

мого символа.

АВ07 21FFAB LD HL.#ABFF ;В HL засылается адрес ячейки, в

;которой находится нонер строки
; печати.

АВОА 7Е LD A. (HL) ; Значение, содержащееся там. срав-

АВОВ FEOD CP #0D - ;нивается.с максимально допустимым

; (ODH-13 строк).
ABOD D29F1E JP NC,#1E9F ; Если это значение превышено, то

;переход на процедуру REPORT В в
; ПЗУ- для вывода сообшения об
; ошибке "integer out of ranee".
ABIO 2B DEC HL ;Теперь в HL адрес ячейки, в кото-

; рой находится значение колонки
; печати.

АВ11 7Е LD A. (HL) ;Значение, содержащееся там. срав-

АВ12 FE15 CP #15 ;нивается с максимально допустимым

;115Н=21 символ в строке).
АВ14 3606 JR С. #АВ1С ;Если результат не превышен, то

; переход на продолжение процедуры
; печати.

АБ1б AF XOR А ;Иначе - переход на новую строку.

АВ17 77 LD (HL).A ; для этого обнуляется счетчик

АВ16 23 INC HL ;колонок, а счетчик строк

АВ19 34 INC (HL) ;увеличивается на единицу.

ABlA 16ЕЕ JR #АВ0А ;После этого возврат на контроль

; счетчика строк, не превышен ли
; предел.

ABIC 4F LD С. А ;Теперь значение колонки печати.

.•находится и в регистре С.
AB1D 67 ADD А. А :Таким способом производится

ABIE 61 ADD А. С :умножение этого значения на 12

AB1F 67 ADD А. А ; для рассчета координаты

АВ20 87 ADD А. А ; в пикселах.

АВ21 4F LD С. А ; Полученная координата X сохраня-

;ется в регистре С.
АВ22 23 INC HL ; Переходим к адресу, где задана

;колонка печати.
АВ23 7Е LD A.(HL) ;Взяли ее значение в аккумулятор

АВ24 47 LD В. А ; Таким способом

АВ25 87 ADD А. А ; производится умножение

АВ26 60 ADD А. В ;этого значения на 13

АВ27 87 ADD а. А ; для рассчета

АВ26 87 ADD А. А ; координаты в пикселах

АВ29 60 ADD А. В ; т. к. шаг строк - 13 пикселов.

АВ2А 47 LD В. А :Полученное значение У сохраняется

; в регистре В.

АВ2В 3EAD LD A. #AD : Его надо вычесть из числа 173,
AB2D 90 SUB В ; так как отсчет координаты в

; пикселах ведется из левого
; нижнего угла экрана.

Аналогично предыдущей процедуре, выбрана величина 173, а
не 175, т. к. тогда две пустые верхние пиксельные линии будут

отделять текст от бордюра.

АВ2Е 47 LD В. А ;скорректированное значение Y

;сохраняется в регистре В.
AB2F Fl POP AF ; Восстановление кода печатаемого

; символа.

АВЗО 5F LD Е.А ;Для расчета адреса шаблона сим-

АВ31 1600 LD D. #00 ;вола в символьном наборе, надо

:рассчитать его смешение от начала
.символьного набора. В DE устанав-
ливаем порядковый номер символа.
АВЗЗ D5 PUSH DE ;Через стек это значение

АВ34 El POP HL ;переписывается в HL.

АВ35 '29 ADD HL. HL ; таким способом

АВЗб 29 ADD HL.HL ; порядковый номер символа

АВ37 19 ADD HL.DE ; умножается на 22. так как

АВЗб 29 ADD HL.HL ;это число является шагом.

АВ39 19 ADD HL. DE ; определяющим число байтов на 1

АВЗА 29 ADD HL.HL ; символ в символьном наборе.

АВЗВ 1140А9 LD DE.#А940 ; В DE - значение CHARS для упако-

;ванного символьного набора.
АВЗЕ 19 ADD HL.DE .'Сложив с ним величину, получен-

; ную в HL. получим адрес первого
; из 22 байтов, определяющих шаблон
; символа.

AB3F 160В LD D. #0В ;Организация цикла из и повторений

;для 11 пиксельных линий.
АВ41 1Е02 LD Е.#02 :Организация цикла из 2 повторений

; для левой и правой половины символа.
АВ43 С5 PUSH ВС ; Двукратное сохранение координат на

ав44 С5 PUSH вс ;стеке для простоты последующих

: рассчетов.

АВ45 7Е LD A.(HL) ;В аккумуляторе байт шаблона .

АВ46 В7 OR А Инициализация Флагов (в частности

;для нас важен принудительный
;сброс Флага переноса.
АВ47 2611 JR Z. #АВ5А ; Если в А ноль, то нет необходи-

; мости продолжать работу по печати

; этой части символа и выполняется
; переход к следующему байту.

АБ49 17 RLA :Если в А не ноль, то ротациеи

;через флаг переноса определяем
; необходимость печати данной
; точки.

АВ4А зоов JR NC, #АВ57 ; Если Флаг сброшен, то обход

; печати.

АВ4С F5 PUSH AF ;Сохранение на стеке значений

AB4D Е5 PUSH HL : регистров, т. к. они могут быть

АВ4Е D5 PUSH DE ; изменены в процессе

AB4F С5 PUSH ВС ;работы процедуры PLOT.

ав50 CDE522 CALL #22E5 ;вызов процедуры PLOT.

АВ53 Cl POP ВС ;Восстановление со стека

AB5t Dl POP DE ; значений регистров.

АВ55 El POP HL ;

AB56 F1 POP AF ;

AB57 ОС IHC С ;Переход к следующему пикселу.

АВ58 18ЕС JR #АВ4б ;Повторение действий по печати

: точек.

Сюда программа проходит, когда в аккумуляторе не остается
ни одного включенного бита. Нет необходимости продолжать сдви-
гать содержимое аккумулятора, если он пуст.

АВ5А Cl POP ВС ; Восстановление координат со

; стека.

АВ5В ID DEC Е ;Переход к правой половине

;шаблона символа.
АВ5С 2807 JR Z.#АВб5 ; Если правая половина уже напе-

; чатана. то переход к следующей
; пиксельной линии символа.
АВ5Е 79 LD А. С ;Иначе - увеличение

AB5F Сбое ADD "А, #08 ; координаты X на 8 пикселов.
АВ61 4F LD С.А ;Новое значение - опять в С.

АВ62 23 INC HL ;Переход к следующему байту

; символьного набора.
АВбЗ 18DF JR #АВ44 ; Повторение действий для правой

;половины символа.

АВ65 Cl POP ВС ; Восстановление координат со

; стека.

АВ66 15 DEC D :Проверка счетчика пиксельных

; линий.

АВ67 2604 JR Z.»AB6D ;Если достигнут ноль, то переход

;на завершение процедуры.

АВ69 05 DEC В ;Переход к следующей пиксельной

;линии (координата Y уменьшается. )

АВ6А 23 INC HL ;Переход к следующему байту

. шаблона.

АВ6В 18D4 JR #АВ41 :Повторение действий по печати

;пиксельной линии.

Сюда программа проходит, когда печать символа по точкам
завершена и необходимо провести Финишную операцию - перейти к
следующей позиции печати.

AB6D 21FEAB LD HL,#ABFE ;В HL - адрес ячейки, В которой

.задана колонка печати.

АВ70 34 INC (HL) ; Увеличение на единицу этого зна-

;чения - переход к следующему
; знакоместу.

АВ71 С9 RET ; выход из процедуры печати.

Следующая часть программы - это утилита-упаковшик символь-
ного набора. Исходные четыре символьных набора должны быть за-
гружены под адреса: В500Н (46336). B800H (47104). ВВООН (47672)
и ВЕООН (46640). Эта утилита выполняет "упаковку" символьного
набора и переброску результата в адрес АСООН (44032).

АВ60 DD2100B5 LD IX. #В500 :В IX - начало первого стандарт-

;ного символьного набора.
АВ84 2100АС LD HL,#AC00 ;В HL - начало области для упако-

;ванного символьного набора.
АВ87 0660 LD В. #60 ; Цикл для всех 96 символов набора.
АВ89 С5 PUSH ВС ;сохранение счетчика на стеке.

АВ6А 0606 LD В. #08 iЦикл для восьми верхних линий

, символа.

АБбС DD7E00 LD A.i1Х*0) ;В аккумуляторе - байт левой

; половины.

AB8F 77 LD (HL)>А ;Упаковка его в новый симв. набор.

АВ90 гз INC HL .Переход к следующему адресу.

АВ91 DD7E08 LD A, (IX+8) ;В аккумуляторе - байт правой

. половины.

АВ94 77 LD (HD.A .Упаковка его в новый симв. набор.

АВ95 гз INC HL ;Переход к следующему адресу.

АВ96 DD23 INC IX ;Переход к следующему адресу

;в исходном символьном наборе.
АВ96 10F2 DJNZ #АВ8С ;Повторение для всех 8 пиксельных

; линий, определяющих верхнюю часть
; символа.

ав9а п0800 LD DE. #0008 ; при помощи смешения в 8 байт вы-
AB9D DDI9 ADD IX. DE ; полняется переход к адресам, оп-

;ределяюшим нижнюю часть символа.
AB9F 0603 LD В. #03 ' :Здесь организуется цикл из трех

; шагов, т. к. 6 уже сделано и до 11
;осталось сделать три.
ABAi DD7E00 LD A. (IX+0) I эта часть программы
ABAt 77 LD (HL).А полностью идентична

АБА5 23 INC HL той. которая расположена

АВАб DD7E08 LD a. (IX+8) в адресах АВ8СН .. . АВ98Н.
АВА9 77 LD (HL).A

АВАА 23 INC HL

АВАВ DD23 INC IX
ABAC 10F2 DJNZ #АВА1

ABAF U0D00 LD DE. #000D При помоши смешения в 13 байтов
АВВ2 DDI9 ADD IX.DE .выполняетеяется переход к следу-

;юшеи группе байтов, определяющих
;четверку символов в исходном
;символьном наборе.
АВВ4 Cl POP ВС ;Восстановление счетчика символов

АВВ5 10D2 DJNZ #АВ89 ; со стека и его проверка. Если не

;достигнут конец, то повтор тех же
;действий для следующего символа.
АВВ7 С9 RET ;Иначе - выход из процедуры.

Следующая часть программы - это утилита-распаковшик сим-
вольного набора. Упакованный символьный набор должен быть рас-
положен начиная с адреса АСООН (44032). Четыре стандартных сим-
вольных набора будут получены в адресах: В500Н (46336). В600Н
(47104). ВВООН (47672) и ВЕООН (46640).

стартовая часть программы обнуляет область для получаемых
символьных наборов, это необходимо сделать, так как при работе
распаковщик "перескакивает" через неиспользуемые ячейки, в
которых могла остаться какая-то информация.

АВВв 2Ю0В5 LD HL. #В500 ; В HL - начало области для перво-

;го стандартного символьного
; набора.

АВВВ 3600 LD (HL).#00 ;Обнуление первого байта.
ABBD 1Ю1В5 LD DE. #В501 ; Подготовка параметров
АВСО 01FF0B LD BC.#OBFF : для LDIR.

АВСЗ EDBO LDIR ; Обнуление памяти при помоши LDIR.

Далее - собственно процедура, противоположная упаковщику.

АВС5 DD2100B5 LD 1Х.#В500 ; В IX - начало области для перво-

;го стандартного символьного
; набора.

АВС9 2100AC LD HL.ttACOO ; В HL - начало упакованного

;символьного набора.
АВСС 0660 LD В. #60 ;Иикл для всех 96 символов набора.
АБСЕ С5 PUSH ВС ; Сохранение счетчика на стеке.

ABCF 0606 LD Б. #06 . Цикл для восьми верхних линий

; шаблона.

ABD1 7Е LD A.(HL) ; В аккумуляторе байт упакованного

; символьного набора.
ABD2 DD7700 LD (1Х+0).А :Перенесение его в стандартный

:символьный набор.
ABD5 23 INC HL ;Переход к следующему адресу.

ABD6 7Е LD A.(HL) ;Следуюший байт упакованного

; символьного набора.
ABD7 DD7708 LD <1Х+8),А Перенесение его в стандартный

; символьным набор.
ABDA 23 INC HL i Переход к следующим адресам

ABDB DD23 INC IX ; символьных наборов.

ABDD 10F2 DJNZ #ABD1 ; Повторение для всех в верхних

: линий.

ABDF 110800 LD DE. #0008 ; При помощи смешения в DE, увели-
АВЕ2 DDI9 ADD IX.DE ;чение на 8 байтов адреса в

; стандартной символьном наборе.
АВЕ4 0603 LD В. #03 ; Цикл для трех нижних линий

; шаблона.

АВЕб те LD A.(HL) I Эта часть программы

АВЕ7 DD7700 LD (IX+O). А I полностью идентична
АВЕА 23 INC HL I программе в адресах

АВЕВ 7Е LD A.(HL) IABDIH... ABDDH

АВЕС DD7708 LD (IX+8).А
ABEF 23 INC HL

ABFO DD23 INC IX
ABF2 10F2 DJNZ #ABE6 I

ABF4 llODOO LD DE. #oooD !При помощи смешения в DE. увели-
ABF7 DDI9 ADD IX, DE ; чение адреса на 13 байтов, что

; обеспечивает переход к следующей
;четверке символов.
ABF9 Cl POP ВС ; Восстановление со стека значения

ABFA 10D2 DJNZ #АВСЕ ; счетчика символов и его проверка.

;Если не достигнут конец, то пов-
, торение действий для следующего
; символа.

ABFC С9 RET . Если конец достигнут, то выход.

Системные ячейки, используемые в работе программы.

ABFE оо DEFB ; колонка печати символа.

ABFF оо DEFB ; Строка печати символа.

Если мы хотим, чтобы эта новая процедура качественной пе-
чати ногла работать из БЕИСИКа по команде PRINT# или из машин-
ного кода по команде RST юн. то нам необходимо открыть новый

канал. Пусть, например, он будет подключен к потоку #5.

Беисик-программа. приведенная в листинге 2. 8. 5, демонстри-
рует работу этой процедуры печати Это только демонстрационная
программа, поэтому в строке 4 в ней предусмотрена загрузка
только одного стандартного символьного набора - второго, опре-
деляющего синволы с "8" по "О".

Листинг 2. 8. 5.

1 GO ТО 10

2 BORDER 7: PAPER 7: INK О: CLEAR 40000

3.LOAD "#5"CODE 43776

4 LOAD "11» 12. fnfCODE 47104.768
10 RANDOMIZE 43776: POKE 23593,PEEK 23670:

POKE 23594.PEEK 23671
'20 POKE 23590.196 POKE 23591,21' POKE 23592,83:
POKE 23595,PEEK 23853: POKE 23596.PEEK 23584:
POKE 23597.PEEK 23855
30 RANDOMIZE (23593-(PEEK 23631+256«PEEK 23632)+1*65536)
40 POKE 23584.PEEK 23670: POKE 23585.PEEK 23671
90 RANDOMIZE USR 43904
100 LET X-0: LET У=0: GO SUB 1000
110 PRINT #5; "89:; <=>?@ABCDEFGHIJK"
120 GO TO 110
1000 POKE 44030.x: POKE 44031.У RETURN

Теперь несколько слов о тон. как сформировать символьный
набор для процедуры качественной печати. Это можно сделать
опять же при помощи графического редактора "ARTSTUDIO", только
теперь обьем работы будет больше, каждый символ "качествен-
ного" символьного набора сначала надо сформировать, пользуясь
лупой с увеличением хб (режим MAGNIFY X в). Начинать работу
надо в левом верхнем углу экрана, так, как это показано на
Рис. 20. Надо строго следить за тем, чтобы символы располага-
лись точно с шагом 16*16 пикселов. Всего их должно быть 24,
согласно распределению по четырем символьным наборан. которое
было приведено выше,

Рис. 20

Когда работа будет закончена, картина должна иметь примерно
такой вид. как показано на Рис. 21.

Здесь дан второй символьный набор из четырех. Теперь,
задав окно так. как зто показано на Рис. 21 . войдем в меню
"Font editor" и выполним операцию "Capture font", как это
показано на Рис. 22.

Указатель текущего символа должен быть установлен на пер-
вый символ. Необходимое условие: окно должно быть задано точно
шириной в 16 пикселов, иначе фрагменты символов будут считаны
со смешением, такую же процедуру надо повторить для второго и
третьего столбцов символов (см. Рис. 21 ). каждый раз передвигая
указатель текущего символа на новое место (см. Рис.22). После
окончания работы символьный набор примет вид. показанный на
Рис. 22. Теперь он готов к упаковке.




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
От авторов - Новое в оболочке. Поправки к уставу zxnet.
Бук - рассказ "Интим-полигон".
Вступление - О создании нового электронного издания "X-RAY".
Интервью - интервью с разработчиком клона HOBBIT (2-я часть).
Сплошные приколы - 5 приколов. Учись стрелять! Если игра мешает делу...

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