#include <stdio.h>
#include <stdlib.h> // for the rand() function
#include <math.h> // for the floor() function

#define ABS(x) ( ((x) >= 0) ? (x) : (x * -1) )
#define round(x) floor( (x) + 0.5)


unsigned char Pall[255][3],Pall2[255][3];
     // This declares the PALL variable. 0 to 255 signify the colors of the
     //  pallette, 1 to 3 signifies the Red, Green and Blue values. I am
     //  going to use this as a sort of "virtual pallette", and alter it
     //  as much as I want, then suddenly bang it to screen. Pall2 is used
     //  to "remember" the origional pallette so that we can restore it at
     //  the end of the program. 

//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
// This procedure gets you into 320x200x256 mode.

void Readkey(void)
{
        #pragma aux Readkey =   \
        "mov ax, 0001h",        \
        "int 16h"               \
        modify [ax];
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
// This procedure gets you into 320x200x256 mode.

void SetMCGA(void)
{
        #pragma aux SetMCGA =   \
        "mov ax, 0013h",        \
        "int 10h"               \
        modify [ax];
}

//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
//  This procedure returns you to text mode.

void SetText(void)
{
        #pragma aux SetText =   \
        "mov ax, 0003h",        \
        "int 10h"               \
        modify [ax];
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void WaitRetrace(void)
  // This waits until you are in a Verticle Retrace ... this means that all
  //  screen manipulation you do only appears on screen in the next verticle
  //  retrace ... this removes most of the "fuzz" that you see on the screen
  //  when changing the pallette. It unfortunately slows down your program
  //  by "synching" your program with your monitor card ... it does mean
  //  that the program will run at almost the same speed on different
  //  speeds of computers which have similar monitors. In our SilkyDemo,
  //  we used a WaitRetrace, and it therefore runs at the same (fairly
  //  fast) speed when Turbo is on or off. 

{
  while(inp(0x3DA) & 0x08);
  while(!(inp(0x3DA) & 0x08 ));
}

//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void GetPal(unsigned char ColorNo, unsigned char *R,unsigned char *G,unsigned char *B)
{
  // This reads the values of the Red, Green and Blue values of a certain
  //  color and returns them to you. 


   outp(0x3C7,ColorNo);
   *R = inp(0x3C9);
   *G = inp(0x3C9); 
   *B = inp(0x3C9);
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void Pal(unsigned char ColorNo, unsigned char R,unsigned char G,unsigned char B)
{
  // This sets the Red, Green and Blue values of a certain color 

   outp(0x3C8,ColorNo);
   outp(0x3C9,R);
   outp(0x3C9,G);
   outp(0x3C9,B);

}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
int sgn(float a)
   {

        if (a>0) return (+1);
        if (a<0) return (-1);
        if (a==0) return (0);
        return 0;

   }

//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void line(int a,int b,int c,int d,int col)
{

  // This draws a line from a,b to c,d of color col.

  float u,s,v,d1x,d1y,d2x,d2y,m,n;
  int i;

  float a1=a, b1=b, c1=c, d1=d;

     u = c1 - a1;
     v = d1 - b1;

     d1x= sgn(u);
     d1y= sgn(v);
     d2x= sgn(u);
     d2y= 0;
     m= ABS(u);
     n = ABS(v);

     if ( !(m>n) )
     {
          d2x =0;
          d2y = sgn(v);
          m = ABS(v);
          n = ABS(u);
     }
     s = (int)(m / 2);


     
     for(i=0;i<=round(m);i++)
     {
          putpixel(a,b,col);
          s = s + n;
          if (!(s<m))
          {
               s = s - m;
               a= a +round(d1x);
               b = b + round(d1y);
          }
          else
          {
               a = a + round(d2x);
               b = b + round(d2y);
          }
     }

}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
// This puts a pixel on the screen by writing directly to memory.

void putpixel(unsigned int x, unsigned int y, unsigned char col)
{
        *((char*) 0xa0000 + (y*320) + x) = col;
}

//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
// This clears the screen to the specified color

void Cls(unsigned char col)
{
        memset((char*) 0xa0000, col, 64000);
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void PalPlay(void)
{
  // This procedure mucks about with our "virtual pallette", then shoves it
  //  to screen. 
   unsigned char Tmp[3]; // This is used as a "temporary color" in our pallette
   int loop1;

   memcpy(Tmp,Pall[199],3); // This copies color 200 from our virtual pallette to the Tmp variable

   memcpy(Pall[1],Pall[0],200*3); // This moves the entire virtual pallette up one color

   memcpy(Pall[0],Tmp,3); // This copies the Tmp variable to the bottom of the virtual pallette

   WaitRetrace();

   for(loop1=1;loop1<=255;loop1++)
     pal (loop1,Pall[loop1][0],Pall[loop1][1],Pall[loop1][2]);

}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void SetUpScreen(void)
{
  // This gets our screen ready but setting up the pallette and drawing
  //  the lines.
   int Loop;

   memset(Pall,sizeof(Pall),0); // Clear the entire PALL variable to zero.
   for (Loop=0;Loop<=200;Loop++)
      Pall[Loop][0] = Loop%64;

       // This sets colors 0 to 200 in the PALL variable to values between
       //  0 to 63. the MOD function gives you the remainder of a division,
       //  ie. 105 mod 10 = 5 

   for (Loop=1;Loop<=320;Loop++)
   {
      Line(319,199,320-Loop,0,(Loop%199)+1);
      Line(0,0,Loop,199,(Loop%199)+1);
       // These two lines start drawing lines from the left and the right
       //  hand sides of the screen, using colors 1 to 199. Look at these
       //  two lines and understand them.

      PalPlay();
        // This calls the PalPlay procedure 
   }


}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void GrabPallette(void) 
{
int loop1;

  for (loop1=0;loop1<=255;loop1++)
    Getpal (loop1,&Pall2[loop1][0],&Pall2[loop1][1],&Pall2[loop1][2]);
}



//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void Blackout(void)
{
  // This procedure blackens the screen by setting the pallette values of
  // all the colors to zero. 
int loop1;

  WaitRetrace;
  for (loop1=0;loop1<=255;loop1++)
    Pal (loop1,0,0,0);
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void HiddenScreenSetup(void) 
{
 // This procedure sets up the screen while it is blacked out, so that the
 // user can't see what is happening. 
int loop1,loop2;

  for (loop1=0;loop1<=319;loop1++)
    for(loop2=0;loop2<=199;loop2++)
      PutPixel (loop1,loop2,(int) 256 * rand() / RAND_MAX);
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void Fadeup(void) {
  // This procedure slowly fades up the new screen
int loop1,loop2;
unsigned char Tmp[3];
      // This is temporary storage for the values of a color 

  for (loop1=1;loop1<64;loop1++)
  {
      // A color value for Red, green or blue is 0 to 63, so this loop only
      // need be executed a maximum of 64 times 
    WaitRetrace();
    for(loop2=0;loop2<255;loop2++)
    {
      Getpal (loop2,&Tmp[0],&Tmp[1],&Tmp[2]);

      if (Tmp[0]<Pall2[loop2][0]) Tmp[0]++;
      if (Tmp[1]<Pall2[loop2][1]) Tmp[1]++;
      if (Tmp[2]<Pall2[loop2][2]) Tmp[2]++;

        // If the Red, Green or Blue values of color loop2 are less then they
        //  should be, increase them by one. 
      Pal (loop2,Tmp[0],Tmp[1],Tmp[2]);
        // Set the new, altered pallette color.

    }
  }
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void FadeDown(void) {
  // This procedure fades the screen out to black. 
int loop1,loop2;
unsigned char Tmp[3];
      // This is temporary storage for the values of a color 

  for (loop1=1;loop1<64;loop1++)
  {
    WaitRetrace();
    for (loop2=0;loop2<255;loop2++)
    {
      Getpal (loop2,&Tmp[0],&Tmp[1],&Tmp[2]);
      if (Tmp[0]>0) Tmp[0]--;
      if (Tmp[1]>0) Tmp[1]--;
      if (Tmp[2]>0) Tmp[2]--;
        // If the Red, Green or Blue values of color loop2 are not yet zero,
        // then, decrease them by one. }
      Pal (loop2,Tmp[0],Tmp[1],Tmp[2]);
        // Set the new, altered pallette color. 
    }
  }
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
void RestorePallette(void)
{
  // This procedure restores the origional pallette 
int loop1;

  WaitRetrace;
  for (loop1=0;loop1<=255;loop1++)
    pal (loop1,Pall2[loop1][0],Pall2[loop1][1],Pall2[loop1][2]);
}


//ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
// BEGIN Of the main program

int main (void)

{

  printf("This program will draw lines of different colors across the\n");
  printf("screen and change them only by changing their pallette values.\n");
  printf("The nice thing about using the pallette is that one pallette\n");
  printf("change changes the same color over the whole screen, without\n");
  printf("you having to redraw it. Because I am using a WaitRetrace\n");
  printf("command, turning on and off your turbo during the demonstration\n");
  printf("should have no effect.\n");
  printf("\n");
  printf("The second part of the demo blacks out the screen using the\n");
  printf("pallette, fades in the screen, waits for a keypress, then fades\n");
  printf("it out again. I haven''t put in any delays for the fadein/out,\n");
  printf("so you will have to put ''em in yourself to get it to the speed you\n");
  printf("like. Have fun and enjoy! ;-)\n");
  printf("\n\n");
  printf("Hit any key to continue ...\n");
  Readkey();
  SetMCGA();
  GrabPallette();

  SetUpScreen();
  Readkey();

  while(!kbhit())
     PalPlay();
       // Call the PalPlay procedure repeatedly until a key is pressed.

  Readkey();
    // Read in the key pressed otherwise it is left in the keyboard buffer



  Blackout();
  HiddenScreenSetup();

  FadeUp();

  Readkey();
  FadeDown();
  Readkey();
  RestorePallette();

  SetText();
  printf("All done. This concludes the second sample program in the ASPHYXIA\n");
  printf("Training series. You may reach DENTHOR under the name of GRANT\n");
  printf("SMITH on the MailBox BBS, or leave a message to ASPHYXIA on the\n");
  printf("ASPHYXIA BBS. Get the numbers from Roblist, or write to :\n");
  printf("             Grant Smith\n");
  printf("             P.O. Box 270\n");
  printf("             Kloof\n");
  printf("             3640\n");
  printf("I hope to hear from you soon!\n");
  printf("\n\n");
  printf("Hit any key to exit ...\n");
  Readkey();


  return(0);

} // END Of the main program


Hosted by www.Geocities.ws

1