::[ PART 02 - THE PALETTE ]::[ Source ]::[ Printable Version ]::
::[ DISCLAIMER ]::
I will hold no responsibility to whatever happens to you, your computer, your sanity, your pet, or whatever that may happen to your existence for your reading these texts and for the outcome of the various source code(s) given in each tutorial. So in short, read at your own risk!

 
::[ INTRODUCTION ]::
Ah, yes...it seems you've read my tutorial for Part I and are back for more eh?...:).

Anyway, what will be covered here today is how to set colors from the palette to your liking. This way, you won't have to guess what color no., say, red is at the palette...:).

SideNote: Actually, if we were working in modes with higher bit depth (e.g. 15/16bit modes), we wouldn't need to bother working with the palette, because we state blatantly the intensity of Red, Green, and Blue for each pixel...this way, we get more colors, and we don't have to remember where in the palette could we find a specified color...:).

 
::[ TUTORIAL ]::
"So what, Willie, WHAT, is this palette you're blabbering about?!?"...

If you're one of those who asked that while reading the introduction...read on!

As stated in Part I, an 8bit mode can show at any given time, 256 colors on the screen...but how do we know what color is color no. 43? or color no. 18? 23? 134?...well, we have the option to SET the palette with a given color.

Actually, each color is "described" using the R-G-B model (that's Red-Green-Blue), and each color in the model can have a maximum intensity of 63. So you can say that you want color number 10 to have a Red intensity of 21, a Blue intensity of 60, and a Green intensity of 0...:)

Now, the "smarter" (hehe) part of the populace reading this right now would notice...if I can set values of Red, Green, and Blue in a range of 0-63...then it would mean that each color can have 64 different intensities assigned to it... and that would give me 64*64*64 different number of combinations...and 64*64*64 = 262,144 colors!

Well, exactamundo dude! You have 262,144 colors to choose from! But sadly, at any given time, you can only show 256 colors out of 262,144 colors that lies in your possession...:).

Now the palette is like an array that "points" to another array of size 262,144 (which holds all colors possible), of which, only 256 colors it can "copy" at any given time.

So how do we set the palette with whatever color we want??? Here's the code:

  //----8<----[ CODE BEGIN ]--------//
    void palSET(char colornum, char R, char G, char B) {
      outp(0x03C8,colornum); 
      outp(0x03C9,R);
      outp(0x03C9,G);
      outp(0x03C9,B);
    }
  //----8<----[ CODE END   ]--------//

"Oh geez, Willie! Stop giving us Greek source codes!...".

Uhh...well, to "unGreek" the source code above, read my explanation below...:)...

outp() stands for OUT PORT...what it does is it writes a byte to the hardware port given the port number and the value that you want to write to it.

So what's a port??? Well, think of it (for now) as a gateway where your computer and your program exchange data...different ports would get/set different data from/to your computer via your program...:).

So "outp(0x03C8,colornum)" means you want to write colornum to port 0x03C8 (writing a byte to this port no. tells the computer that you want to set color no. colornum to the given R, G, and B intensities)...

...then this is followed by "outp(0x03C9,R)", which means you're setting the Red intensity of colornum through port no. 0x03C9...and so on...:).

Note that you cannot change the order of the way you outp() your Red, Green, and Blue intensities...guess why...:).

So to recap:

  • you write to port no. 0x03C8 the color number that you want to change the Red, Green, and Blue intensity of
  • you then write to port no. 0x03C9 the Red, Green, and Blue intensity of the color no. you want to change
Whew! So far so good?...It's all in the concept really, coding is pretty straightforward, you may even just rip the code off and use it, but then again...you won't learn won't you?...:).

Now that you know how to set the palette, how about getting the Red, Green, and Blue intensities of a certain color number? Here's the source:

  //----8<----[ CODE BEGIN ]--------//
    void palGET(char colornum, char *R, char *G, char *B) {
      outp(0x03C7,colornum); 
      (*R) = inp(0x03C9);
      (*G) = inp(0x03C9);
      (*B) = inp(0x03C9);
    }
  //----8<----[ CODE END   ]--------//

inp() means IN PORT...which reads a byte from the hardware port no. you give it. Notice that this is almost the same as palSET() above, except you're reading bytes this time...and that you're using port no. 0x03C7 for getting different intensities, as oppose to 0x03C8 for setting colors...:)

To sum up the ports:

  • 0x03C7 - port no. to use for getting colors
  • 0x03C8 - port no. to use for setting colors
  • 0x03C9 - port no. that reads/write R,G,B values
So now you know how to set/get the palette, what use is this to you? Well, have you ever seen TV scenes or in the movies where the screen fades from a colorful picture to black? Well, you can do this now!...and that's my exercise for you...plot different random pixels to the screen, then fade the whole screen to black...:).

(The NOMAD.C Section below doesn't implement my exercise for you, it merely sets all of the pixels to WHITE in a heartbeat...NOT fading!)

 
::[ ENDING ]::
And that's that! Not hard eh? If there is anything that's not clear to you, your mind, or to that part of you that lets you comprehend the things here, you may email me at:

Part 3 & 4 will let you guys "probe" into higher and better screen resolutions!

Briefly, for compatibility for all monitors, you'll use a standard set by VESA. This is supported in all later (read: newer) models. The VESA has a structure that you load with to get various informations about the screen mode that you'll be getting into...all will be explained in Part 3...so check it out!

 
::[ NOMAD.C ]::

  #include <DOS.H>
  #include <MEM.H>
  #include <STDLIB.H>
  #include <STDIO.H>

  //--[ SETS SCREEN TO MODE 13H ]------------//
  void setGFXMODE() {
    _AX = 0x0013;
    geninterrupt(0x10);
  }

  //--[ SETS SCREEN TO TEXT MODE ]----------//
  void setTXTMODE() {
    _AX = 0x0003;
    geninterrupt(0x10);
  }

  //--[ PLOTS PIXEL DIRECTLY TO MEMORY ]----//
  void pixelMEMORY(int x, int y, char color) {
    memset(MK_FP(0xA000, x+(y*320)), color, 1);
  }
  
  //--[ SET THE PALETTE ]-------------------//      
  void palSET(char colornum, char R, char G, char B) {
    outp(0x03C8,colornum); 
    outp(0x03C9,R);
    outp(0x03C9,G);
    outp(0x03C9,B);
  }

  //--[ GET THE PALETTE ]-------------------//
  void palGET(char colornum, char *R, char *G, char *B) {
    outp(0x03C7,colornum); 
    (*R) = inp(0x03C9);
    (*G) = inp(0x03C9);
    (*B) = inp(0x03C9);
  }

  //--[ SETS ALL COLORS TO WHITE ]----------//
  void WHITEOUT() {
    int colornum;

    for(colornum=0; colornum<=255; colornum++) {
      palSET(colornum, 63,63,63);
    }
  }

  void main() {
    long ctr;
  
    setTXTMODE();

    printf("\n\nNOMAD GRAPHICS TUTORIAL - [ PART 2 ]\n");
    printf("\n  This is a sample code included with GFXTUT2.TXT");
    printf("\n  to show how to implement the sample codes that");
    printf("\n  were given in the said tutorial.\n");
    printf("\n  [ Press Any Key to Begin ]");

    (void)getch();

    setGFXMODE();
      for(ctr=0; ctr<100000; ctr++)
        pixelMEMORY(random(320), random(200), random(256));
      (void)getch();

      WHITEOUT();
      (void)getch();
    setTXTMODE();

    printf("\n\nNOMAD GRAPHICS TUTORIAL - [ PART 2 ]\n");
    printf("\n  That was 100000 random pixels all of which suddenly");
    printf("\n  was set to WHITE...:)\n");
    printf("\n  That's all for now. See you in GFXTUT3.TXT!...:)\n");
    printf("\n  email: [ willietang@hehe.com ]\n");
  }
This tutorial was written on: 10.08.2001 | Updated: 01.07.2003
:.Site.:.Menu.:
:// .site..news.
:// .tutorials..1.
:// .tutorials..2.
:// .projects.
:// .forums.
:// .gbook.
:// .links.