__________________________________________
┌─┬┐┌─┐┌─┬┐┌─┐┌─┐┌─┬┐┌─┐┌─┐
││││││││││││├┤││││││││├┤│││
││││││││││││ │││││││││ ││││
│││││││││││├┤││─┤││││├┤││─┤┌┐┌┐
└┴─┘└─┘└┴─┘└─┘└─┘└┴─┘└─┘└─┘└┘└┘
Если кодеру отрезать руки,
Если ноги отрезать тоже,
Этот кодер помрет...со скуки,
Потому что кодить не сможет!
(c)PIXel/BrC
__________________________________________
Люди, как так можно? Вы только посмотри-
те, что творится! Если в ЭСМИ есть что-то
для начинающих кодеров, то это обязательно
что-то типа: "Регистры бывают 8-и и 16-и
разрядные... команды делятся на группы.. и
т.п.". Все это, конечно, хорошо, но после
этого обычно ничего не следует. Поэтому
новичок загружает, например, DoD и видит
там такое, что сразу теряет всякую надежду
написать что-либо красивое. Сегодня я по-
пытаюсь объяснить, как разжечь огонь, буду
разжевывать алгоритм его создания.
Ну,начнем:
ORG 25000
ENT
Ах да, точно, надо бы сперва придумать,
как оно будет работать и как имитировать
огонь. Ну так вот, делаем так:
1.В буфере создаем массив, элементы ко-
торого задают интенсивность свечения эле-
мента огня (например, артибута, чанка или
пикселя).
2.Печатаем тот самый массив.
3.Изменяем элементы массива по опреде-
ленным правилам.
4.пауза, если необходимо.
5.переходим к пункту 2.
Правила изменения массива в каждом слу-
чае свои (они могут зависеть и от печатал-
ки буфера на экран). Элементарный огонь
подчиняется следующему правилу:
Элемент буфера (х,у) принимает значение,
равное половине суммы его (х,у) значения и
значения элемента находящегося под ним (х,
у+1).Т.е:M[x,y]:=(M[x,y]+M[x,y+1])/2
если эти два элемента равны, то первый об-
нуляется:
if M[x,y]=M[x,y+1] then M[x,y]:=0;
M[x,y]:=(M[x,y]+M[x,y+1])/2;
Нижняя строка элементов массива забивае-
тся случаимыми числами в пределах (max/2;
max),например:
Исходный буфер: Полученный буфер:
0---------------->x 0----------------->x
|................ |..........2......
|..........5..... |..13......2......
|..27......5..... |..13..1...3......
|......3...2..... |.....443.........
|.....ххх........ |.....ХХХ.........
y y
Как это ни странно, но получаем эффект го-
рящего огня или пламени, что одно и тоже.
Если все понятно, то продолжим, если нет,
то читай с самого начала руководство по
программингу на BASIC'е.
Для простоты будем изображать буфер в
области атрибутов с #5b00. Буфер засунем
по адесу #c000, а занимать он будет, как
вы, наверно, догадались, ровно 768+32
байтиков.
Чистим буфер, что ли:
LD hl,#c000
LD de,#c001
LD (hl),L
LD bc,768+32
LDIR
Теперь будем над ним извращаться:
flame LD ix,#c000+32;[0,1]
LD de,#c000 ;[0;0]
LD bc,768 ;длина
begin LD a,(DE) ;берем
CP (ix) ;сравним
JR nz,loop1 ;не равно
XOR a ;обнулим, если равно
loop1 ADD a,(ix) ;
SRL a ; >M[x,y]:=(M[x,y]+M[x,y+1])/2
LD (de),A ;/
INC ix ; следующий
INC de ;/ элемент
DEC bc ;
LD a,B ;
OR c ;
JR nz,begin ;если не все, то дальше
CALL print ;печатаем на экран
CALL pr_key ;опрос кнопков ;)
LD de,#c000 ;
LD a,R ;
AND %00011111 ;
LD h,A ;
LD a,R ;
LD l,A ;
LD de,#c000+768;типа на последнюю строку
LD bc,32 ; x'ов у нас 32
rnd LD a,R ;
OR (hl) ;сгенерили случайное число,
rang AND 31 ;чтоб не больше max
LD (de),A ;суем в последн строку
INC hl ; следующий элемент
INC de ;/ последней строки
DJNZ rnd ;пока не кончатся x'ы
JR flame ;и все с самого начала.
print LD hl,#c000 ;просто
LD de,#5800 ;кидаем
LD bc,768 ;в
LDIR ;атрибуты
RET ;и назад.
pr_key LD bc,#7ffe ;там SPACE живет
IN a ;это IN (C),A
BIT 0,a ;самый нулевой бит.
RET nz ;типа никто SP не жал.
POP de ;если надавил, то
RET ;возврат в XAS.
Вот, в принципе, и весь исходник, но мно-
гим может не понравиться то, что в пла-
мени присутствуют синие, зеленые, фиолето-
вые элементы. Это, конечно, можно испра-
вить, чем мы, собственно говоря, и займем-
ся. Для начала решим, какие атрубуты в ог-
не присутствовать должны. Рассмотрим их по
нарастающей:
(буду использовать сокращение: pXiY где X-
цвет paper'а, Y-цвет ink'а)
#00 = p0i0 = %00000000
#01 = p0i2 = %00000010
#02 = p0i6 = %00000110
#03 = p0i7 = %00000111
#04 = p2i0 = ...
#05 = ...
...
#0e = p7i6
#0f = p7i7
Я думаю, вы поняли принцип: должны присут-
ствовать только черный, красный, желтый и
белый цвета. Значит, от нашей печаталки
требуется принтить в атрибуты не сами зна-
чения элементов, а соответствующие этим
значениям атрибуты. Теперь замените строку
rang
на: rang AND 15 ; т.к. значений 15,
а Call print на Call pr_buff.
pr_buff LD de,buff ;начало буфера.
LD hl,#5800 ;куда принтим.
LD bc,768 ;сколько элементов.
pr_b0 PUSH bc ;чтоб не забыть :) .
LD a,(DE) ;возьмем, чтоб разглядеть.
AND #0f ;нам чужого(a>15) не надо.
PUSH hl ;смотри pr_b0.
LD hl,cnv_tab ;начало таблицы атрибутов,
LD b,0 ;в которой записано, какому
LD c,A ;значению какой атрибут
ADD hl,BC ;соответствует.
LD a,(HL) ;берем из таблички
POP hl ;вспомним HL
LD (hl),A ;зафигачим, куда надо :)
POP bc ;скока тама ужо элементов?
INC hl ;дальше - больше!
INC de ;больше и лучше! :)
DEC bc ;осталось на одного меньше.
LD a,B ;
OR c ; > всё или как?
JR nz,pr_b0 ;/ если не всё, то или как.
RET ;всё так всё, я не виноват.
cnv_tab
;000102030405060708090a0b0c0d0e0f ;табличка значений для тебя.
#000206071012161730323637383a3e3f ;соответствующие атрибуты.
Вот и всё. Вроде,ничего сложного - ста-
тья даже не требует глубоких знаний мате-
матики (хотя кодеру они не вредят). Все
исходники написаны на XAS'е, а посему мо-
жет присутствовать специФИЧНЫЙ синтаксис и
прочее, например:
#0123456789abcdef
надо понимать как:
DB #01,#23,#45,#67,#89,#AB,#CD,#EF
Вообще, для написания небольших программ и
алгоритмов этот ассемблер подходит лучше
всего (хотя, может, не лучше STORM'а). Он
является компромиссом между STORM'ом и
ALASM'ом (версии 4.2). Пишешь 3D-rotator -
грузи STORM, пишешь операционную систему -
добро пожаловать в ALASM. Вот если бы к
ALASM'у приделать XAS'овый или STORM'овый
редактор, то получится АССЕМБЛЕР МЕЧТЫ, и
я думаю, что не только моей. Ну да ладно,
чё-то меня не в ту сторону занесло. Совсем
не слышу никаких отзывов :( Наверно, зря я
тут стараюсь, и Nonsense... можно закрыва-
ть как раздел. Буду вам рассказывать луч-
ше, как я в детском саду (когда был мале-
нький) выжигал детям ладони увеличительным
стеклом (фокусируя лучь на кожу) и т.п. :)
Опять не туда... Ладно, похоже, на сегодня
всё, что я знал об огне, я рассказал.
Пока.
P.S. забыл сказать еще одну формулу:
M[x,y]:=(M[x-1,y+1]+M[x,y+1]+M[x+1,y+1]+M[x,y])/4
Вот теперь всё!
__________________________________________