A fascination with fire is nothing new for humans, or even programmers. With that in mind, I wanted to give some insight into how to create your very own fire animations, like this: (https://i.imgur.com/tJUrnLi.gif)
In that program, I basically started from the top of the screen, working downward. I'd copy from the pixel below, with a 12.5% chance of the copy "burning up" and thus failing. To cause a perpetual burn, I then OR the original image back to the buffer and run the next iteration. If I didn't do this, then the image would disintegrate after a few seconds (which is cool, too).
Now of course, this is Assembly, which is fast, but it's also the Z80, so not that fast. Instead of operating on one pixel at a time, it's faster if we can operate on 8 pixels at a time (represented by 1 byte). Copying the pixels is easy-- if DE points to the current byte of pixels, and HL points to the byte of pixels below, then we can do ld a,(hl) \ ld (de),a (or ldi). The tricky part is coming up with some chance of messing with those pixels.
We want it to appear random or chaotic, so we need an RNG of some kind, in this case a Pseudo-Random Number Generator. Ideally, we also want it to be fast. If our PRNG returns numbers with the property that each bit is chaotic, but has a 50% chance of being 0 or 1, then we can apply some probability tricks. For example, if we OR three pseudo-random numbers, then the result has bits with probability 1/8 being 0, 7/8 being 1. Armed with this knowledge, if we then AND this with the pixels to copy, we have a 12.5% chance of turning any ON pixels to OFF.
This assumes the 'flames' are black. If we want white flames, AND three numbers from the PRNG and OR the result with the pixels to copy. This has a 12.5% chance of turning a pixel ON.
If we want more complicated probabilities, we can change the sequence of ANDs and ORs. For example, if we OR two PRNs and AND a third, the bit probabilities are 37.5% being 1, 62.5% being 0.
Just note that if we change the order, then the probabilities change! If we AND to PRNs and then OR a third, we have a 62.5% being 0 and 37.5% being 1.
To calculate, we start with p_{0}=50%.
If we OR with a PRN, then p_{i+1}=(1+p_{i})/2
If we AND with a PRN, then p_{i+1}=p_{i}/2
For example, if we AND/OR/AND/OR, we have:
p_{0}=.5
p_{1}=.5/2 = .25
p_{2}=(1+.25)/2 = .625
p_{3}=.625/2 = .3125
p_{4}=(1+.3125)/2 = .65625
With my example, I wanted it to be easy, so I just went with ORing three pseudo-random numbers to generate a bitmask. I created a 24-bit PRNG with the necessary qualities (and as a bonus, it passed a suite of randomness tests), so by calling it once and ORing each of the bytes together, I can make a mask.
For those who might be able to follow Axe code a little better:
StorePic
While getKey(15)=0
L3->W
For(Z,L6,L6+767)
{Z} or {W}->{Z}
W+1->W
End
L6->Z+12->W
For(K,0,755)
rand or rand or rand or {W}->{Z}
W+1->W
Z+1->Z
End
DispGraph
End