Palette Tricks by Zkman 05.09.99
|The Palette is (in Screen 13 atleast) the group of 256 colors that you have to use when you're drawing tiles, making special effects, whatever. The values of those colors can be whatever you want (by value, I mean whether the color is yellow, red, a strange mix of green and orange, etc.). This article will discuss what it takes to make a good palette (using our handy-dandy palette creator or whatever you wish to use), how to speed up color changes, PSET's, etc., and palette manipulation.||
Download my palette editor
Provided for your use here in this article is my not-so-user-friendly palette editor. It gets the job done, but you should really try and use one linked to the tile editor you use; most big tile-eds (like SpriteShop) will have a palette editor included. Here's what you need to look for:
Gradients are a range of colors in increasing or decreasing magnitude. For example, say colors 1 through fifteen of you palette were grey. Color 1 would be dark grey, and color 15 almost white, with 2-14 filling in the rest of the gradient. Doing these by hand is not a good idea, and will cause you to waste hours of time. Most palettes can be done in less than an hour.
There are literally hundreds of ways to save a palette. Wafn's program Palpitation has over 10 different format loads, such as BSAVE, dqbString, numerical list, etc. Try and find a palette editor whose save and load make sense to you (i.e., you can pretty much understand the code), and make sure it will work with your tile editor of choice.
Other than that, you shouldn't have to worry much about your editor. Making the palette work for your game is the hard part.
Making your palette work
You also want to figure out what colors you'll be using in your game. Unless you're making QBarbie, you won't need 15 pinks, so don't use that many! If you're doing a futuristic game, think about a lot of greys, some black, silver, etc. If you want a fantasy rpg, green and brown are important background colors.
The most important thing, though, is to do a gradient palette. Almost all of your special effects will be much easier with such. Say you want fire in your game: make a 15 color gradient starting at red and ending with yellow. When it comes to some of the special effects, this will help you a lot. Also, for "main" colors, and colors that you think might be used translucently, make a 16 color long gradient. Why? Look below...
What the hell is this RGB you
RGB colors in VGA (256 color mode or SCREEN 13 or Mode 13h, among other names) are stored as a red number from 0 to 63, a green from 0 to 63, and a blue from 0 to 63. 0 means there is none of that color, and 63 means there is all of that color. So, an rgb of 0,0,0 would be black, 63,0,0 would be bright red, and 63,63,63 would be white.
Here are some equations to help you find a color: (When I say 1 part, I mean in relation to the other colors. For instance, 1 part green and 2 parts red means anything from 2,1,0 to 63,31,0)
Hope that's not *too* confusing ^_^.
The fast PSET you should already know
Because some of the palette tricks below can't be done fast enough without these speedups, I'll show them to you anyway. Most already know these tricks, so just skip down to the next section.
Here's the fast way of doing PSET:
DEF SEG =
The DEF SEG switches the segment over to the graphics buffer, and the POKE places the pixel of color "colour" at position x,y. This is up to twice as fast as PSET.
Another trick is to BSAVE the entire screen at once, so once you apply an effect, you can bring back the screen to whatever it looked like before the effect without having to redraw the screen. That's done as follows:
DEF SEG =
This will save the screen into a file of about 64000 bytes named "name.tmp". Of course, the name can be "goat.goa", "microsof.com", or even "bclinton.sex".
Then, after you've messed up the screen, you can get back the screen you'd saved in a millisecond with the following:
DEF SEG =
Just make sure you call back the same file name. These tricks will be called "Fast PSET" and "BSAVE Screen" below, so remember...or else!
|So how do we do translucency?
Rather than waste a lot of memory on something like alpha
blending, we can simply use a look-up table. Here's how
it works, and why gradients are so important.
DIM SHARED transluc(256)
Create the array for the look up table
Start the FOR/NEXT to go through all the colors. "boog" is just a sloppy placeholder to know if we've already got something in the array. There are better ways to code this =).
&H3C7 gives me access to the palette at number i (which is specified in the loop as something from 0 to 255). rd, gr, and bl are the RGB values for the said number.
Is the value for Red the highest of the three RGB's? We're trying to find the highest RGB value. If it is, we add the Red value to the array, and set boog to 1 so it's not overwritten.
Is blue the highest? Then add it to the array.
If green is highest, add it to the array, and go to the next color.
You only need to do this once, at the start of your program. The number in the array for each color now is from 0 to 15 (16 colors, which is why I said to divide your palette's main colors into blocks of 16). So now, we need to decide what the "translucent color" will be. The picture above used white, but you can make it blue, green, brown, whatever. Here's how:
So, what are we doing here? We're simply getting the color of a point we want to put the translucency over, then poke psetting from the array we created earlier a new color. So, for instance, let's say colors 30 to 45 were dark grey to white. We'd simply use 30 as "start_of_col" and there we go! Translucency for 256 bytes!
SEG = &HA000
Set up the preliminary variables in case they weren't clear. Value to change is the amount to change the variables: for instance, -20 to lower the rgb 20 (make it a lot darker) or 3 to make it a little lighter.
c = 0 TO 255
Get the palette register ready to go thru the colors
PEEK(i) + va > 63 THEN tr = 63 ELSE tr = PEEK(i) + va
For each RGB, increase it by said value, and if that value is over 63 or under 0, keep it at 63 or 0.
i = i + 4 NEXT DEF SEG
Increase variable "i" so the next pass will go up one color value, and then close out the FOR/NEXT.
A smooth way of doing day night is make your day/night "variable" start at 0. Every few seconds, make day/night 1 higher and pass the value to a sub with the above code. Once the number is 10 (high noon) start decreasing the number until it reaches -10 (night). A value of -10 of most palettes is almost enough to make it very hard to see! Using the above code, you can do effects like shadows, lanters, etc.
I hope you've learned enough about palette manipulation through this article, and have fun developing your own routines (both of the above were developed by me, but I'm sure they've been done before by someone). And don't forget to share your experience!