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