Процедура "Снег"
---------------------------------
(С) Роман Щербаков,
г.Москва, 1995.
----------------------------------
Прочитав в ZX-РЕВЮ-94, N5 на
стр. 5 программу Константина Ко-
роткова "Звезды", я решил поде-
литься еще одной аналогичной
программой на тему точек. Наде-
юсь, эффект понравится читателям
РЕВЮ и будет полезен тем, кто же-
лает прекрасно оформить свою
программу.
При запуске программы в первый
раз на экране появляются случай-
ным образом точки разного размера
- снежинки, а при последующих за-
пусках все эти точки сдвигаются
вниз. Только это не скроллинг, а
наложение по OR на имеющееся
изображение с запоминанием того,
что было в этом месте экрана в
специальном буфере, поэтому "сне-
жинки" на своем пути ничего не
стирают, а как бы падают на зад-
нем плане, за изображением. Ско-
рость точек тоже не одинакова:
более ближние (большие) точки
двигаются быстрее, чем дальние
(маленькие). Процедура хороша для
оформления меню и титульных зас-
тавок: создается впечатление, что
меню летит в космосе между звезд.
Эффект похож на тот, что ис-
пользуется в игре SANXION, но в
этой программе я встретил такую
кашу, что не теряя сил и времени
решил воспроизвести эффект сам.
Процедура полностью релоцируе-
мая и может загружаться под любой
адрес и стартовать с адреса заг-
рузки.
---------------------------------------------------------------------
00010 ; *Program 'SNOW' *
00020 ; (C) Sherbakov Roman
00030 ;
00032 ORG 40000
00034 ENT
00040 CALL #007C ;Эта часть служит
00050 DEC SP ;для настройки программы
00060 DEC SP ;на работу с любого адреса;
00070 POP IX ;в регистре IX получается
00080 LD BC,#0061 ;адрес расположения
00090 ADD IX,BC ;таблицы-буфера.
00100 LD C,#03 ;Количество типов снежинок - три.
00110 TYPES LD B,#07 ;Число снежинок каждого типа - по 7 шт.
00120 TYPE1 LD L,(IX+00) ;В HL заносится адрес текущей снежин-
00130 LD H,(IX+01) ;ки из таблицы.
00140 LD E,(IX+02) ;В Е значение экранного байта, находя-
;щегося в буфере.
00150 LD (HL),E ;Печать содерж.Е - снежинка исчезает.
00160 LD A,C ;Проверка типа снежинки. Необходимо по-
00170 CP #03 ;тому, что крупные - имеют размер два
00180 JR NZ,LOOP1 ;пиксела, значит на экране надо восста-
;новить два байта. Если тип снежинки не
;третий (крупная), то переход на LOOP1.
00190 INC H ;Восстановление на экране
00200 LD D,(IX+03) ;нижнего байта
00210 LD (HL),D ;(для типа снежинки 3).
00220 LOOP1 ADD A,H ;Содержимое Н увеличивается на столько,
;каков тип снежинок (на 1-3 байта).
00230 LD H,A ;Расчет адреса
00240 AND #07 ;в дисплейном
00250 JR NZ,PLOTS ;файле: расчет
00260 LD A,H ;трети экрана,
00270 SUB #08 ;контроль за
00280 LD H,A ;переполнением
00290 LD A,L ;(снежинка
00300 ADD A,#20 ;дошла до
00310 LD L,A ;низа экрана,
00320 JR NC,PLOTS ;при этом
00330 LD A,H ;она появляется
00340 ADD A,#08 ;сверху);
00350 LD H,A ;если расчет
00360 CP #58 ;выполнен,
00370 JR C,PLOTS ;то переход
00380 LD H,#40 ;к метке PLOTS.
00390 PLOTS LD (IX+00),L ;В таблицу заносится новое
00400 LD (IX+01),H ;значение адреса снежинки.
00410 LD E,(HL) ;В буфер - бит экрана для сохранения
00420 LD (IX+02),E ;и последующего восстановления.
00430 LD A,C ;Формирование снежинки;
00440 OR E ;объединение по OR
00450 LD (HL),A ;с основной картинкой.
00460 LD A,C ;Вторая проверка типа снежинки; необхо-
00470 CP #03 ;дима потому же, что и 1-я; если сне-
00480 JR NZ,LOOP2 ;жинки маленькие, то переход на LOOP2.
00490 INC H ;Здесь печатаются по OR
00500 INC IX ;большие снежинки
00510 LD D,(HL) ;(точнее, их
00520 LD (IX+02),D ;нижние половинки);
00530 OR D ;значение экранного байта
00540 LD (HL),A ;запоминается в буфере.
00550 LOOP2 LD DE,#0003 ;Переходим к следующему элементу
00560 ADD IX,DE ;таблицы/буфера.
00570 DJNZ TYPE1 ;Если не напечатаны все снежинки
;данного типа, то повторение.
00580 DEC C ;Переход к следующему
00590 JR NZ,TYPES ;типу снежинок.
00600 RET ;Когда напечатаны 3 типа снежинок.
00610 DEFB #4B,#40,#00 ;Данные для таблицы/буфера.
00620 DEFB #00,#DD,#44 ;
00630 DEFB #00,#00,#19 ;Эти данные динамичны, то есть они
00640 DEFB #48,#00,#00 ;постоянно меняются в ходе работы.
00650 DEFB #C2,#48,#00 ;
00660 DEFB #00,#B0,#4C ;Расклад данных таков:
00670 DEFB #00,#00,#07 ;
00680 DEFB #50,#00,#00 ;1. Для больших снежинок
00690 DEFB #74,#54,#00 ; 2 байта - адрес; 2 байта - буфер.
00700 DEFB #00,#F7,#42 ;
00710 DEFB #00,#25,#4C ;2. Для средних снежинок
00720 DEFB #00,#49,#4C ; 2 байта - адрес; 1 байт - буфер.
00730 DEFB #00,#60,#52 ;
00740 DEFB #00,#12,#54 ;3. Для мелких снежинок
00750 DEFB #00,#BB,#52 ; 2 байта - адрес; 1 байт - буфер.
00760 DEFB #00,#CE,#54 ;
00770 DEFB #00,#0C,#41 ;Всего этот массив занимает
00780 DEFB #00,#43,#43 ; 28*3+21*3+21*3=70 байтов.
00790 DEFB #00,#55,#4D ;
00800 DEFB #00,#5E,#4D Ъ-------------------------------------
00810 DEFB #00,#E8,#41 і Start of object: #9C40 (40000)
00820 DEFB #00,#9A,#4B і Length : #00A9 (00169)
00830 DEFB #00,#31,#53 і Executes : #9C40 (40000)
Шестнадцатиричный дамп проце-
дуры "Снег":
9C40: CD 7C 00 3B 3B DD E1 01 :5A
9C48: 61 00 DD 09 0E 03 06 07 :49
9C50: DD 6E 00 DD 66 01 DD 5E :B6
9C58: 02 73 79 FE 03 20 05 24 :2C
9C60: DD 56 03 72 84 67 E6 07 :7C
9C68: 20 14 7C D6 08 67 7D C6 :3C
9C70: 20 6F 30 0A 7C C6 08 67 :86
9C78: FE 58 38 02 26 40 DD 75 :5C
9C80: 00 DD 74 01 5E DD 73 02 :1E
9C88: 79 B3 77 79 FE 03 20 09 :6A
9C90: 24 DD 23 56 DD 72 02 B2 :A9
9C98: 77 11 03 00 DD 19 10 B0 :75
9CA0: 0D 20 AB C9 4B 40 00 00 :68
9CA8: DD 44 00 00 19 48 00 00 :C6
9CB0: C2 48 00 00 B0 4C 00 00 :52
9CB8: 07 50 00 00 74 54 00 00 :73
9CC0: F7 42 00 25 4C 00 49 4C :9B
9CC8: 00 60 52 00 12 54 00 BB :37
9CD0: 52 00 CE 54 00 0C 41 00 :2D
9CD8: 43 43 00 55 4D 00 5E 4D :47
9CE0: 00 E8 41 00 9A 4B 00 31 :BB
9CE8: 53 00 00 00 00 00 00 00 :D7
И в заключение, Бейсик-прог-
рамма для тестирования процедуры:
5 BORDER 0: PAPER 0: INK 7
10 FOR a=10 TO 80 STEP 10
20 CIRCLE 127,85,a: NEXT a
30 RANDOMIZE USR 40000: PAUSE 1
40 IF INKEY$="" THEN GO TO 30
Программа имеет небольшой не-
достаток, над которым мы рекомен-
дуем подумать. Дело в том, что
когда блок кодов загружается в
первый раз, в буферных ячейках,
где должны храниться экранные
байты, еще записаны нули. Они при
старте перебрасываются в экран,
что несколько портит исходное
изображение, находящееся на экра-
не. Необходимо, чтобы при первом
старте буферные ячейки заполня-
лись данными с экрана, и только
после этого формировались бы сне-
жинки.