Welcome to Issue 1, October
QBasic Gamer

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Controling the Palette in QuickBasic - By Terry Cavanagh
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

It's no secret that QuickBasic isn't the ideal enviorment for programming games. You're stuck with a maximum of 256 colors, 16 if you want smooth animation, the standard palette is utterly useless, and the only command that exists in the language to modify the standard palette is the painfully slow PALETTE Command. So one of the first things QB programmers should really concentrate on is inproving thier palette. The tutorial is aimed at programmers who know some QB, but who still think they've got a lot to learn. You have to admit, most palette affects look cool. But there's more to it than that. A well kept secret is that palette effects are also quite easy to do, and require little programming knowelge save what most intermediate QuickBasic Programmers already know.

Ok, Let's get started. QuickBasic has one palette command. And here it is.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
PALETTE OldColor%, NewColor%
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

It's slow, but it gets the job done. Let me explain how it works.

The "OldColor%" is the Palette Slot to be changed. Say you wanted the Palette Slot 15 to be green instead of white.

Copy this into QB and run it to see the effect. I'll explain how it works after.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SCREEN 13
COLOR 15
PRINT "This Text is White - Or is it?"
SLEEP
PALETTE 15, 16128
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Huh? You're probably saying :) Ok, Let's go through EXACTLY how the Palette command works.

The OldColor% is the Slot. If you've run this program, you'll have seen the text change from white to bright Green when you hit the slot.

But the 16128? That probably confused a few people... In an EGA screen mode, the Palette command simply changes the OldColor% to the contents of the color in the NewColor% slot. In a VGA screen mode, however, like Screen 13, it's a little more complecated.

Here's the forumla.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
PALETTE OldColor%, Red% + (Green% * 256) + (Blue% * 65536)
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Bearing in mind that the maximum intensities for Red%, Green% and Blue% are 63, being the brightest, and 0 being pitch dark, you can create any color with these. You can mix combinations, et cetera. Let's look at that code above again.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SCREEN 13
COLOR 15
PRINT "This Text is White - Or is it?"
SLEEP
PALETTE 15, 16128
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Screen 13 simply changes to a 256 VGA screen mode (QB's only). Color 15 tells the computer that you will be using this color for your text. The Print Command shows the text in the brackets on screen. And the Sleep command waits for a keypress before contining. All this you should have already known. But the Palette command is the key. What exactly is 16128? It's 63 * 256 - i.e, the brightest shade of Green! Let's play around with the Palette some more :

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SCREEN 13
COLOR 15
PRINT "This Text is white - or is it?"
SLEEP
PALETTE 15, 0
SLEEP
PALETTE 15, 63
SLEEP
PALETTE 15, 256 * 63
SLEEP
PALETTE 15, (256 * 63) + 63
SLEEP
PALETTE 15, 65536 * 63
SLEEP
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Run that to see its effects.

Alright, You've gotten the jist of the Palette command. But there's so much more to learn!

What'll we do first? Something we should really try to improve on is the palette's speed. Sure, That runs at a reasonable speed, but what if you wanted to change the entire palette? Try to do this, and the program slows down considerbly, to such an extend that on my Pentium 433 Mhz, the entire palette takes a wopping 3 seconds to replace. sigh.. In this day and age, that's much too slow. Lucky for QB, we've always gotten by on pokes to speed things up. Here's a listing that will have the same effect as the palette command.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
OUT &H3C8, Slot%
OUT &H3C9, Red%
OUT &H3C9, Green%
OUT &H3C9, Blue%
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

You simply write those four lines exactly like that, one after the other. I advise that you write it down rather than cut and paste it, because it's good habit to type it in everytime you need it - It'll stick in you head that way.

Now for the main part of the tutorial - I'm going to mentain a trick that can be done with palettes, give a listing, and then explain how it works.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Trick One - Chosing the background text color in a screenmode other than 0.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

SCREEN 13
OUT &H3C8, 0
OUT &H3C9, 63
OUT &H3C9, 63
OUT &H3C9, 63
COLOR 8
PRINT "Look See!"
PRINT "The Text is gray!
PRINT "The Background is White!"
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Well, we all have to start somewhere, don't we? Let's explain the code word for word.

The reason why we might want to do this is simple - The Background of the text is always black - in screen 0 you can select the background text color with the color command, but that's a different story. To get the background text color to be something other than black, you need to change the color that resides in slot zero.

The first line changes the screenmode.

The next four lines change color 0 to white.

The next line changes the foreground color to dark gray.

And the last few lines demonstrate the effects.

If you're totally lost at this stage, you havn't a hope of catching up now. I'd advise testing your skills now, and coming back to the tutorial at this point. Things are just about to get complicated.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=>
Trick Two - Fading the Entire Screen
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

RANDOMIZE TIMER
DIM Red%(255), Green%(255), Blue%(255)
SCREEN 13
FOR I% = 0 TO 255

    OUT &H3C7, I%
    Red%(I%) = INP(&H3C9)
    Green%(I%) = INP(&H3C9)
    Blue%(I%) = INP(&H3C9)

NEXT I%
FOR Y% = 0 TO 199

    FOR X% = 0 TO 319

      PSET (X%, Y%), RND * 256

    NEXT X%

NEXT Y%

LOCATE 10, 4
PRINT "Example Of QuickBasic Fade Effect"
LOCATE 11, 12
PRINT "By Terry Cavanagh"
SLEEP
GOSUB FadeOut
SLEEP
GOSUB FadeIn
SLEEP
END

FadeOut:
FOR I% = 0 TO 63

    FOR X% = 0 TO 255

      OUT &H3C7, X%
      R% = INP(&H3C9) - 1: IF R% < 0 THEN R% = 0
      G% = INP(&H3C9) - 1: IF G% < 0 THEN G% = 0
      B% = INP(&H3C9) - 1: IF B% < 0 THEN B% = 0
      OUT &H3C8, X%
      OUT &H3C9, R%
      OUT &H3C9, G%
      OUT &H3C9, B%

    NEXT X%

NEXT I%
RETURN

FadeIn:
FOR I% = 0 TO 63

    FOR X% = 0 TO 255

      OUT &H3C7, X%
      R% = INP(&H3C9) + 1: IF R% > Red%(X%) THEN R% = Red%(X%)
      G% = INP(&H3C9) + 1: IF G% > Green%(X%) THEN G% = Green%(X%)
      B% = INP(&H3C9) + 1: IF B% > Blue%(X%) THEN B% = Blue%(X%)
      OUT &H3C8, X%
      OUT &H3C9, R%
      OUT &H3C9, G%
      OUT &H3C9, B%

    NEXT X%

NEXT I%
RETURN
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Ok, Loads of new stuff here. Run this program to see what happens.

To explain how this works, bear a few points in mind.

First of all, If you fade the screen out, the current palette is destroyed. This is why arrays exist to store the current palette. That explains the line :

DIM Red%(255), Green%(255), Blue%(255)

Also, There's a new trick in action here. You can read the Red, Green and Blue intensities of any palette slot with this code :

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
OUT &H3C7, Slot%
R% = INP(&H3C9)
G% = INP(&H3C9)
B% = INP(&H3C9)
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

Simple! You'll notice it bears more than a passing resemblence to the code to set a palette color. Try to memerize this also. Here's a full explaination.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
RANDOMIZE TIMER

Ensures that a completely new set of random numbers are generated each time the program is run.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
DIM Red%(255), Green%(255), Blue%(255)

Arrays to hold the current pallette
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SCREEN 13

Change to VGA Screenmode
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
FOR I% = 0 TO 255

    OUT &H3C7, I%
    Red%(I%) = INP(&H3C9)
    Green%(I%) = INP(&H3C9)
    Blue%(I%) = INP(&H3C9)

NEXT I%

Reads the contents of the current palette into the arrays.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
FOR Y% = 0 TO 199

    FOR X% = 0 TO 319

      PSET (X%, Y%), RND * 256

    NEXT X%

NEXT Y%
LOCATE 10, 4
PRINT "Example Of QuickBasic Fade Effect"
LOCATE 11, 12
PRINT "By Terry Cavanagh"

Draws a Quick Screen to be Faded.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SLEEP
GOSUB FadeOut
SLEEP
GOSUB FadeIn
SLEEP
END

The Main Engine. Waits for a key, then Fades Out. Waits again, then fades back in and exits the program. Have a look at the sections which perform the Fades.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
FadeOut:
FOR I% = 0 TO 63

    FOR X% = 0 TO 255

      OUT &H3C7, X%
      R% = INP(&H3C9) - 1: IF R% < 0 THEN R% = 0
      G% = INP(&H3C9) - 1: IF G% < 0 THEN G% = 0
      B% = INP(&H3C9) - 1: IF B% < 0 THEN B% = 0
      OUT &H3C8, X%
      OUT &H3C9, R%
      OUT &H3C9, G%
      OUT &H3C9, B%

    NEXT X%

NEXT I%
RETURN

Creates a loop for each color intensity, and inside creates a loop for every palette color. Inside this loop, the current contents of each palette color is observed, reduced by one in intensity, then changed. The first loop ensures that the screen is faded the whole way to black, and errors are avoided by making sure that if an intensity is reduced below zero that it is kept at zero.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
FadeIn:
FOR I% = 0 TO 63

    FOR X% = 0 TO 255

      OUT &H3C7, X%
      R% = INP(&H3C9) + 1: IF R% > Red%(X%) THEN R% = Red%(X%)
      G% = INP(&H3C9) + 1: IF G% > Green%(X%) THEN G% = Green%(X%)
      B% = INP(&H3C9) + 1: IF B% > Blue%(X%) THEN B% = Blue%(X%)
      OUT &H3C8, X%
      OUT &H3C9, R%
      OUT &H3C9, G%
      OUT &H3C9, B%

    NEXT X%

NEXT I%
RETURN

Almost the same, except that instead of reducing the color it increases it. Also, instead of stopping the program going below 0, it stops it going above the color that the palette should be.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

There! I bet you all thought that fading was a difficult thing to do. Let's try something more fancy.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Trick Three - Static
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

RANDOMIZE TIMER
SCREEN 13
FOR I% = 0 TO 255

    X% = RND * 64
    OUT &H3C8, I%
    OUT &H3C9, X%
    OUT &H3C9, X%
    OUT &H3C9, X%

NEXT I%
FOR Y% = 0 TO 199

    FOR X% = 0 TO 319

      PSET (X%, Y%), RND * 256

    NEXT X%

NEXT Y%
SLEEP
DO

    FOR I% = 0 TO 256

      X% = RND * 64
      OUT &H3C8, I%
      OUT &H3C9, X%
      OUT &H3C9, X%
      OUT &H3C9, X%

    NEXT I%

LOOP UNTIL INKEY$ = CHR$(27)
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

This is a lot easier to do than fading the screen, but all this stuff is so easy anyway that there's little or no difference! Let's go through this step by step...

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
RANDOMIZE TIMER

Creates a new set of numbers each time the program is run.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SCREEN 13

Changes to screenmode 13.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
FOR I% = 0 TO 255

    X% = RND * 64
    OUT &H3C8, I%
    OUT &H3C9, X%
    OUT &H3C9, X%
    OUT &H3C9, X%
NEXT I%

Sets the entire palette to shades of White.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
FOR Y% = 0 TO 199
    FOR X% = 0 TO 319
      PSET (X%, Y%), RND * 256
    NEXT X%
NEXT Y%

Draws random dots all over the screen.
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
SLEEP

Drift into never never land. What do you think :) ?
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
DO
    FOR I% = 0 TO 256
      X% = RND * 64
      OUT &H3C8, I%
      OUT &H3C9, X%
      OUT &H3C9, X%
      OUT &H3C9, X%
    NEXT I%
LOOP UNTIL INKEY$ = CHR$(27)

The main part, Keep changing the shades of white until escape is pressed!
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

The effect is pretty pleasing, as you can see! Try a few different things! An invasion of color can be managed by adding a delay between changes of each palette color. A red static looks pretty cool too!

Anyway, so ends this tutorial. I was going to show how to do translucantcy also, but instead I decided to leave it, because to do a full explaination of translucantcy, and the many different ways to do it would fill a tutorial of this size. Maybe If I get some nice feedback, I'll write another tutorial explaining it (hint hint nudge nudge). This thing is probably littered with spelling mistakes, because I didn't read over it. Incedently, I wrote all this code myself, so If you want to use it in your programs, let me know about it and give me credit. Hopefully this tutorial will show you just how easy these sort of things are.

Till next Time!

Terry Cavanagh, terrycavanagh@eircom.net