Make your own free website on
* Download Source, Executable, and this Document

 _____                    ______                   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... 

	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 

Snail-Mail:  Aaron Clemmer
	     104 Battle Mountain Rd
	     Amissville, Va 22002 USA

E-mail bdbHaiti's WebPage: Copyright ©1999