Lookup Tables and Lighting Effects - By Gary Beebe

Note:  This tutorial does not show you how to plot pixels or any other drawing techniques.  It is simply a tutorial showing you how to find the correct shade of color after you know where the original color sits on the palette.  Also, you may not be using palette specific functions.  In that case, this tutorial may be useless to you.  I suggest, if you are going to make functions that are palette specific, that you make your own palette.  This way it will be less painful making the lookup table.

The one main reason why you may want to use a lookup table is for lighting effects.  A lookup table can ensure that the color that you are going to use as a shade of the original color is in the same 'color stream'.  The picture below is of a palette that contains 24 colors.  For our lookup table we will be using the array Light(0 to 23) as String.

As you can see, in the picture above, we have 3 'streams'.  We have a red stream, a green stream, and a blue stream.  To make our lookup table we first must study our palette.  By knowing (and understanding) that the first color in our palette is considered as zero and each stream contains 8 colors, making our lookup table should be quite easy.  The code for our lookup table, for this palette, can easily be made using 3 For...Next loops.  Depending on the size of your palette (24 colors is unreasonably small) you might have anywhere from 8 to 32 For...Next loops.  The code for our 24 color palette is shown below:

Dim a
For a = 0 to 7
    Let Light(a) = "Red"
Next
For a = 8 to 15
    Let Light(a) = "Green"
Next
For a = 16 to 23
    Let Light(a) = "Blue"
Next

That was easy enough.  The next part, obtaining the right shade of color, is a little bit harder but not much.  To best describe this I will quickly show you the code to obtain the colors, using our lookup table.  This code has built in error handling incase your values fall outside the Light array.  If you make your lookup table in the same respect as shown above, the code below should work for you exactly as it is.

Public Function ChangeColor(Original As Integer, Value As Integer) As Integer
Dim NewColor as Integer

Let NewColor = Original + Value
If NewColor < 0 Then Let NewColor = 0
If NewColor > Ubound(Light) Then Let NewColor = Ubound(Light)

Do Until Light(Original) = Light(NewColor)
    If NewColor > Original Then Let NewColor = NewColor - 1
    If NewColor < Original Then Let NewColor = NewColor + 1
Loop

Let ChangeColor = NewColor
End Sub

What this Function does is:
First declare the variable, NewColor, that we are working with or trying to find.
Second it assigns the variable, NewColor, the Value of the Original.  The Value may be a positive or negative.
Third, it checks to see if the NewColor falls outside the Light array.  If it does fall out side the array then then we set it to the closest color in the array.
Fourth, we check to see if the NewColor falls inside the same color stream. We do this by matching the words inside the Light array of the Index NewColor and Original.  If it doesn't then we move the NewColor one step closer to the Original color.
Last, we set our return variable, ChangeColor, to the right color, NewColor.

To help explain this we will be trying to get a color that is 6 shades darker than the 11th color.  The 11th color is the 4th shade of green in the green stream.  To do this we execute our function as follows:

Let ShadedColor = ChangeColor(11, 6)

The Function will examine the color that is 6 Values (NewColor) away from our Original or 11th color.  By comparing the Original color and the NewColor with our lookup table (Light) we see that Original falls on "Green" and NewColor falls on "Blue".  In other words: NewColor falls on the 17th color which is the 2nd shade of blue.  Because a light shade of blue isn't a dark shade of green, the Do...Loop moves NewColor closer to our Original until it becomes a shade of green.  This way we get the closest existing color to the shade we wanted.

The reason I suggest that you make your own palette, if you are using palette specific functions, is because there are many complications in using default palettes.  For one, If you have some shades of blue at one side of the palette and other shades of blue somewhere else on the palette, there is no easy way to which color is next in a stream.  It can be done by cross referencing multiple tables.  One String table listing the flat value of the color "Red", "Green", "Blue", "Cyan", "Gray", etc.  Two Integer tables, one giving the value of the next brightest color and one giving the value of the next darkest color, of the current examined color.  And one Boolean table stating if the current examined color is either the first or last color in a stream.  A Function of this sort may be possible but may not be flawless.  A new and 5th table would have to be made by searching all the lookup tables and building a list of the possible colors, in the stream, in the correct order and then determining the correct color.

I hope this tutorial helps or at least has taught you a little about lookup tables.  As far as determining what shade of a color you should use for each pixel in your game, your on your own.  Using Copy and Paste isn't considered programming.  Typing hundreds and hundreds of lines of code is.