145 lines
6.2 KiB
Plaintext
145 lines
6.2 KiB
Plaintext
|
|
_____ ______ Wikki -
|
|
//---- \__ __\ Fragmentaria '95
|
|
||--- __ || __
|
|
|| | _- _ _ /_/ || _ ___ _ |_|
|
|
\| | |--\ | | | |__ \| |_/| | |_| | \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/~\-=-=-= Intro =-=-=-/~\
|
|
|
|
|
|
þ Here is the first tutorial from Fragmentaria! It is written by
|
|
yours truly, Aaron Clemmer, AKA Wikki... Hopefully it will help you
|
|
understand how everyone is making those neat-o firedemos, and possibly
|
|
help you code your own. The included source was my attempt at making
|
|
one. I wrote almost all of it, with several exceptions: the palette,
|
|
and all the ASM (excluding code that changes into mode 03h =).
|
|
Anything that I didn't write was from Kirk A. Baum's public domain
|
|
flame demo source. And no, I didn't use any of his techniques, I came
|
|
up with them myself. =)
|
|
|
|
|
|
|
|
/~\-=-=-= Overview =-=-=-/~\
|
|
|
|
|
|
þ In theory, the flame is generated like so: You have an array that
|
|
reflects the current status of your screen. You loop through this array,
|
|
reading the color values of the pixels surrounding your current position,
|
|
and get the average of those values. This averaged number goes into
|
|
another array of the same dimensions, positioned directly above the current
|
|
position, so that it will rise. After the entire frame is generated, it is
|
|
dumped to the screen, either one square (4x4 pixels) at a time, or by
|
|
copying the entire array at once. Then you copy the working array to the
|
|
array that contains what was on your screen, thus updating it, and you
|
|
start over.
|
|
|
|
|
|
|
|
/~\-=-=-= Details, Details... =-=-=-/~\
|
|
|
|
|
|
][~-~- Playing With The Palette -~-~][
|
|
|
|
þ First off, you need a palette suitable for a realistic flame.
|
|
What you want to do is set your 256 color palette so that '0' equals
|
|
black, '255' equals white, and everything in-between is a shade of red.
|
|
This obviously gives you a nice "flamey" palette that will do for our
|
|
purposes. One way to do this (other than use the included palette), is
|
|
to use a paint program that allows you to edit the palette, creating a
|
|
grade from the darkest shade of red to the lightest. Or, if you can
|
|
settle for using only 64 colors, edit the palette at runtime using a
|
|
loop sorta like this:
|
|
|
|
int red=0,blue=0,green=0;
|
|
for (red=0,red<64, red++)
|
|
{
|
|
pal_index = red;
|
|
setpalrgb(red, blue, green, pal_index);
|
|
}
|
|
|
|
This will increment through the first 64 colors of the palette and
|
|
set them to red colors. You normally would use the variable 'red'
|
|
in place of 'pal_index', but I was making it more clear what was going
|
|
on. It is also possible to make a loop that will set all 256 colors to
|
|
red, but this example will do for demonstration purposes.
|
|
|
|
|
|
][~-~- Ye Olde Buffers -~-~][
|
|
|
|
þ You have two buffers, one which reflects what is currently being
|
|
displayed on the screen, the other is your working buffer. We'll call
|
|
them CURRENT and WORKING. You usually set the dimensions to be [80][56].
|
|
Why not just make it the size of your screen? Speed. It is much faster
|
|
to use a screenful of four-pixel blocks instead of placing your color
|
|
values at every pixel location on the screen. Since you have to read
|
|
several pixel values, compute the average, and place the result in the
|
|
proper array each time you go through the loop for each element of the
|
|
array, using a 80x56 buffer is much faster, though a little blocky. =)
|
|
|
|
|
|
][~-~- Generating a Frame O' Flame -~-~][
|
|
|
|
þ First off, you loop through the two bottom lines of CURRENT, and randomly
|
|
set the value at your X,Y position to either the brightest color value or
|
|
the darkest. You do this because every time you go through the loop, you
|
|
need to have the flame vary, or it will get quite dull. =) One thing you
|
|
will notice when you run your program is that the bottom rows are rather
|
|
choppy, instead of being smooth as it is higher up. This is simply because
|
|
the flame at the bottom rows aren't very averaged out yet, and won't improve
|
|
until about 3-5 more rows up. The easiest way to fix this is to just not
|
|
display the bottom rows on the screen.
|
|
|
|
þ Once that is done, you run a loop that will start at the bottom position
|
|
of CURRENT (usually [0][56]). Then you go up towards the top of the buffer,
|
|
getting the averages of the surrounding pixels based on your current
|
|
position in the array. Afterwords, you place this value at the equivalent
|
|
X,Y position in WORKING. Of course you do not need to always use the
|
|
surrounding pixels when you are reading the values, you could produce some
|
|
cool effects by reading from different parts of the buffer.
|
|
|
|
|
|
][~-~- Showing It To Our Audience -~-~][
|
|
|
|
þ So what now? Dump the entire WORKING array to the screen, then copy it
|
|
to CURRENT, thus reflecting your changes to the screen. But as you may
|
|
notice, the flame is confined to the two bottom lines of the screen. Why?
|
|
You need to place your averaged color value at [X][Y-1], which is one line
|
|
above your current position, making the flame rise. Of course, you can
|
|
place the value anywhere in the array... for example, if you put it above
|
|
and to the right of your position, it will look like the wind is blowing it.
|
|
|
|
|
|
þ Now that you got it to rise, you see that your flame goes off the top of
|
|
the screen, instead of fading as it gets closer to the top. This is where
|
|
the decay variable comes into play. What you do is after you get your
|
|
average, you write: IF (COLOR > 1) COLOR--;. This decreases the color
|
|
values until they are black. Be sure to try values other than 1 when you
|
|
decrement, for different fade speeds.
|
|
|
|
|
|
|
|
/~\-=-=-= Contact Info, Etc. =-=-=-/~\
|
|
|
|
|
|
þ So you wanna say something to me, do you? Whether it says how wonderful
|
|
my tutorial is, or gripe mail, send it my way...
|
|
|
|
Internet E-mail: AARONC@BBS.GEMLINK.COM
|
|
Note that my internet account expires in September, and there is
|
|
*small* chance I may not re-subscribe... (horror of horrors!!! =)
|
|
|
|
Locust Grove BBS: (540)854-6760
|
|
You can e-mail me here, just address the message
|
|
to "AARON CLEMMER."
|
|
|
|
Snail-Mail: Aaron Clemmer
|
|
104 Battle Mountain Rd
|
|
Amissville, Va 22002 USA
|