Генерация шаблонов 2x2 с использованием статического RND.
© Владимир Витвинов, р.п. Пышма, Свердловская область
Очень много памяти компьютера при использовании графики занимают шаблоны. К примеру, шаблон 2x2 знакоместа занимает 32 байта. Зачастую приходится для экономии памяти ограничивать количество различных шаблонов, что приводит к однообразию игровых локаций. Программисты используют различные "хитрости" для экономии памяти.
Здесь реализован один из подходов для генерации шаблонов 2x2. Принцип работы программы таков:
1. Инициализируются три переменные для RND - R1, R2, R3. Значения можете выбрать сами. После вызова предлагаемой процедуры шаблоны пойдут в строгой последовательности. Переменная, указывающая на начало UDG-графики, устанавливается на начало буфера BUFF - это для демонстрации.
2. Последовательно вызывается процедура RND, забивая 8 байтов случайными числами. Если сейчас Вы напечатаете полученный символ, то получите ерунду в виде бессистемно
разбросанных точек. "Хитрость" заключается в том, что это знакоместо слева направо зеркально копируется во второе, а затем эти два зеркально сверху вниз в следующие два. В результате получается шаблон 2x2 знакоместа вполне приемлемый для последующего использования в программах (например, для построения из них каких-нибудь объектов, лабиринтов и пр.).
В приведенной ниже программе реализована генерация 4-х видов шаблонов. Процедура построена с 5-ю точками входа: 1 - инициализация, 2 - разворачивает шаблон, как описано выше, 3 - оконтуривает его вдобавок, 4 - включает биты в виде "+", 5 - в виде "х". Последние операции придают законченность шаблону. Один раз, вызвав процедуру, можно сколько угодно печатать полученный шаблон из буфера. Вызвав её ещё раз, получите следующий по порядку и так далее. Листинг генератора шаблонов, набранный в ZEUS ASSEMBLER.
| 00010 |  | ORG | 40000 |  | 
| 00020 |  | ENT |  |  | 
| 00030 | / 1 | - инициализация. |  | 
| 00040 |  | LD | HL,RNEW | /Три начальных значение | 
| 00050 |  | LD | DE, R1 | /копируются в переменные | 
| 00060 |  | LD | BC,3 | / R1, R2, R3 . | 
| 00070 |  | LDIR |  |  | 
| 00080 |  | LD | HL,BUFF | /Переключаем переменную UDG на | 
| 00090 |  | LD | (23675) , HL | /начало буфера (граф. A,B,C,D /будут использ.для демонстрации | 
| 00100 |  | RET |  |  | 
| 00110 | / 2 | - разворачивание шаблона. |  | 
| 00120 |  | LD | HL,BUFF | /8 байтов буфера заполняются | 
| 00130 |  | LD | B, 8 | /случайными числами | 
| 00140 | L0 | CALL | RND | /по статическому RND, | 
| 00150 |  | LD | (HL),A | /что будет соответствовать | 
| 00160 |  | INC | HL | / "А" в графическом режиме. | 
| 00170 |  | DJNZ | L0 |  | 
| 00180 |  | JR | PROD | /Переход на развертку символов. | 
| 00190 | / 3 | - оконтуривание шаблона. |  | 
| 00200 |  | LD | HL, BUFF |  | 
| 00210 |  | LD | B, 8 | /То же, но с включением | 
| 00220 |  | LD | A, #FF | /верхних и левых пикселов. | 
| 00230 |  | JR | L2 |  | 
| 00240 | L1 | CALL | RND |  | 
| 00250 |  | SET | 7,A |  | 
| 00260 | L2 | LD | (HL),A |  | 
| 00270 |  | INC | HL |  | 
| 00280 |  | DJNZ | L1 |  | 
| 00290 |  | JR | PROD |  | 
| 00300 | ; 4 - | включение | битов в виде |  | 
| 00310 |  | LD | HL,BUFF |  | 
| 00320 |  | LD | B, 7 | ;То же, но с включением | 
| 00330 | L3 | CALL | RND | ;нижних и правых пикселов. | 
| 00340 |  | SET | 0,A |  | 
| 00350 |  | LD | (HL),A |  | 
| 00360 |  | INC | HL |  | 
| 00370 |  | DJNZ L3 |  |  | 
| 00380 |  | LD | A, #FF |  | 
| 00390 |  | LD | (HL),A |  | 
| 00400 |  | JR | PROD |  | 
| 00410 | ; 5 - | включение | битов в виде | "х". | 
| 00420 |  | LD | HL,BUFF |  | 
| 00430 |  | LD | B, 8 | ;То же, но с включением | 
| 00440 |  | LD | C, #80 | ;пикселов по диагонали: | 
| 00450 | L4 | CALL | RND | ;с верхнего левого | 
| 00460 |  | OR | C | ;к нижнему правому. | 
| 00470 |  | RR | C | ;#80=10000000 - побитовая рас- | 
| 00480 |  | LD | (HL),A | ;кладка, эту единицу мы будем | 
| 00490 |  | INC | HL | ;вращать и накладывать по OR. | 
| 00500 |  | DJNZ | L4 |  | 
| 00510 | ; Развертка полученного знакоместа. | 
| 00520 | PROD | LD | HL,BUFF | ;Откуда. | 
| 00530 |  | LD | DE,BUFF+ 8 | ;Куда. | 
| 00540 |  | LD | BC,#0808 | ^^чётчик битов, C=счетчик байтов. | 
| 00550 | L5 | PUSH | BC |  | 
| 00560 |  | LD | A,(HL) | ; Принимаем байт. | 
| 00570 | L6 | RRA |  | ;Переносим 0 бит в флаг CARRY. | 
| 00580 |  | RL | C | ;Подхватываем его в регистр С. | 
| 00590 |  | DJNZ | L6 | ;Разворачиваем 8 битов. | 
| 00600 |  | LD | A, C | ;Зеркальный байт перебрасываем | 
| 00610 |  | LD | (DE) ,A | ;в новое место. | 
| 00620 |  | INC | HL | ;Увеличиваем | 
| 00630 |  | INC | DE | ;указатели. | 
| 00640 |  | POP | BC |  | 
| 00650 |  | DEC | C | ;Проверяем, все ли 8 байтов | 
| 00660 |  | JR | NZ,L5 | ;переброшены. Символ "В" готов. | 
| 00670 |  | LD | HL,BUFF | ;Откуда. | 
| 00680 |  | LD | DE,BUFF+23 | ;Куда, здесь перебрасываем | 
| 00690 |  | LD | C, 2 | ;с конца, развернуть надо | 
| 00700 | JUMP | LD | B,8 | ;два символа. | 
| 00710 | L7 | LD | A,(HL) | ;Переброска | 
| 00720 |  | LD | (DE) ,A | ;задом-наперед. | 
| 00730 |  | INC | HL | ;Изменяем | 
| 00740 |  | DEC | DE | ;указатели. | 
| 00750 |  | DJNZ | L7 | ;Все ли байты переброшены, | 
| 00760 |  | DEC | C | ;оба ли символа "C" и "D" | 
| 00770 |  | RET | Z | ;развернуты, если ДА, то выход. | 
| 00780 |  | LD | HL,BUFF+8 | ;Указатели для | 
| 00790 |  | LD | DE,BUFF+ 31 | ;символа "D". | 
| 00800 |  | JR | JUMP |  | 
| 00810 | RND | LD | A,(R1) | ;Процедура взята из | 
| 00820 |  | LD | D, A | ;№ 7-8, 1993 г., стр.154. | 
| 00830 |  | LD | A, (R2) | ;Можете составить свою. | 
/Начальные значения для RND. /Можете
/подставить свои. /Резервируем 32 байт для буфера. Приведенная ниже BASIC-программа демонстрирует возможности процедур.
10 CLEAR 39999: LOAD "rnd" CODE 40000 20 RANDOMIZE USR 40000: LET z=40018 30 GO SUB 500: CLS 40 FOR y=0 TO 18 STEP 3 50 FOR x=0 TO 30 STEP 3 60 RANDOMIZE USR z
70 PRINT AT y,x/"AB": PRINT AT y+1,x/"CD" 80 NEXT x 90 NEXT y 100 GO TO 30
500 PAUSE 0: IF INKEY$="0" THEN STOP 510 IF INKEY$="1" THEN LET z=40018: RETURN 520 IF INKEY$="2" THEN LET z=40032: RETURN 530 IF INKEY$="3" THEN LET z=40052: RETURN 540 IF INKEY$="4" THEN LET z=40071: RETURN 550 RETURN
| 00840 |  | LD | (R1),A | 
| 00850 |  | ADD | A, D | 
| 00860 |  | LD | D, A | 
| 00870 |  | LD | A, (R3) | 
| 00880 |  | LD | (R2),A | 
| 00890 |  | ADD | A, D | 
| 00900 |  | RLCA | / | 
| 00910 |  | LD | (R3),A | 
| 00920 |  | RET |  | 
| 00930 | R1 | DEFB | 0 | 
| 00940 | R2 | DEFB | 0 | 
| 00950 | R3 | DEFB | 0 | 
| 00960 | RNEW | DEFB | 5 | 
| 00970 |  | DEFB | 90 | 
| 00980 |  | DEFB | 37 | 
| 00990 | BUFF | DEFS | 32 | 
 
Подчёркнутые символы в строке 70 набираются в графическом регистре.
Типы шаблонов переключаются клавишами продолжить генерацию шаблонов старого типа.
Результат работы генератора шаблонов Вы можете увидеть на рисунках.
0" - стоп, остальные клавиши
 
Для тех, кто не владеет (пока) ассемблером ZEUS, приводим шестнадцатеричный дамп (с контрольными суммами) кодового блока программы. Нули в последних адресах дампа - это зарезервированный 32-байтный буфер для работы программы.
|  |  | Дамп файла "rnd"CODE 40000 | ,200. |  |  | 
| 9C40 | 21 | E5 | 9C | 11 | E2 | 9C | 01 | 03 | 11 | 
| 9C48 | 00 | ED | B0 | 21 | E8 | 9C | 22 | 7B | C3 | 
| 9C50 | 5C | C9 | 21 | E8 | 9C | 06 | 08 | CD | 91 | 
| 9C58 | CA | 9C | 77 | 23 | 10 | F9 | 18 | 38 | 4D | 
| 9C60 | 21 | E8 | 9C | 06 | 08 | 3E | FF | 18 | 04 | 
| 9C68 | 05 | CD | CA | 9C | CB | FF | 77 | 23 | A0 | 
| 9C70 | 10 | F7 | 18 | 24 | 21 | E8 | 9C | 06 | FA | 
| 9C78 | 07 | CD | CA | 9C | CB | C7 | 77 | 23 | 7A | 
| 9C80 | 10 | F7 | 3E | FF | 77 | 18 | 11 | 21 | 21 | 
| 9C88 | E8 | 9C | 06 | 08 | 0E | 80 | CD | CA | DB | 
| 9C90 | 9C | B1 | CB | 19 | 77 | 23 | 10 | F6 | FD | 
| 9C98 | 21 | E8 | 9C | 11 | F0 | 9C | 01 | 08 | 7F | 
| 9CA0 | 08 | C5 | 7E | 1F | CB | 11 | 10 | FB | 8D | 
| 9CA8 | 79 | 12 | 23 | 13 | C1 | 0D | 20 | F1 | E4 | 
| 9CB0 | 21 | E8 | 9C | 11 | FF | 9C | 0E | 02 | AD | 
| 9CB8 | 06 | 08 | 7E | 12 | 23 | 1B | 10 | FA | 3A | 
| 9CC0 | 0D | C8 | 21 | F0 | 9C | 11 | 07 | 9D | 93 | 
| 9CC8 | 18 | EE | 3A | E2 | 9C | 57 | 3A | E3 | 96 | 
| 9CD0 | 9C | 32 | E2 | 9C | 82 | 57 | 3A | E4 | AF | 
| 9CD8 | 9C | 32 | E3 | 9C | 82 | 07 | 32 | E4 | 60 | 
| 9CE0 | 9C | C9 | 00 | 00 | 00 | 05 | 5A | 25 | 65 | 
| 9CE8 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 84 | 
| 9CF0 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 8C | 
| 9CF8 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 94 | 
| 9D00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 9D |