Click here if you are stuck in someone else's frames.
Random Graphics Program

Okay, time for another demo before we move on.  This demo will display random graphics on the screen of random colors, beleive me, this program is long.

     /* RANDOM_G.C -- by Gary Neal, Jr.
      *
      * Draws random graphics of random colors.
      */

     #include <stdlib.h> /* Required for rand() functions */
     #include <dos.h>    /* Required for int86() functions */
     #include <conio.h>  /* Required for keyboard functions */
     #include <mem.h>    /* For memset & _fmemset functions */
     #include <math.h>   /* For sine & cosine functions */

     /* Video display definitions */
     #define TEXT_MODE 0x03
     #define VGA256    0x13

     /* Define constants for screen dimensions */
     #define ScreenWidth  (unsigned)320
     #define ScreenHeight (unsigned)200

     /* Create a pointer to video memory */
     unsigned char far *videoMem = (unsigned char far *)0xA0000000L;

     /* Function prototypes */
     void SetVideoMode(int mode);
     void SetPixel(int X, int Y, unsigned char C);
     void FillScreen(int color);
     void Line(int X1, int Y1, int X2, int Y2, unsigned char C);
     void Circle(int xOffset, int yOffset, int radius, unsigned char C);

     /* Our main program */
     int main(void)
     {
          while (kbhit()) getch();  /* Clear keyboard */

          SetVideoMode(VGA256);     /* Set VGA mode 13h */

          /* Random pixel demonstration */
          while (!kbhit())
               SetPixel(rand()%320, rand()%200, rand()%256);

          while (kbhit()) getch();  /* Clear keyboard */
          FillScreen(0);            /* Clear screen */

          /* Random line demonstration */
          while (!kbhit())
               Line(rand()%320, rand()%200, rand()%320, rand()%200, rand()%256);

          while (kbhit()) getch();  /* Clear keyboard */
          FillScreen(0);            /* Clear screen */

          /* Random circle demonstration */
          while (!kbhit())
               Circle(rand()%320, rand()%200, rand()%100, rand()%256);

          while (kbhit()) getch();  /* Clear keyboard */

          SetVideoMode(TEXT_MODE);  /* Set VGA mode 13h */

          return 0;                 /* Return without errors */
     }

     /* SetVideoMode function */
     void SetVideoMode(int mode)
     {
          union REGS regs;  /* Create register variables */

          regs.x.ax = mode; /* Set video mode */

          /* Call interrupt to complete the task */
          int86(0x10, ®s, ®s);
     }

     /* SetPixel function */
     void SetPixel(int X, int Y, unsigned char C)
     {
          videoMem[Y * 320 + X] = C;
     }

     /* FillScreen function */
     void FillScreen(int color)
     {
          /* Set all video memory to appropriate color */
          _fmemset(videoMem, color, ScreenWidth * ScreenHeight);
     }

     /* Line function
      *
      * Revised line function that will draw full lines
      * in any slope at any angle.
      */
     void Line(int X1, int Y1, int X2, int Y2, unsigned char C)
     {
         float currX, currY;           /* Current pixel to be plotted */
         float deltaX, deltaY, slope;  /* 2 deltas and slope */
         int tempVal;                  /* Holds temporary values */

         deltaX = X2 - X1;             /* Get value for delta X */
         deltaY = Y2 - Y1;             /* Get value for delta Y */

         if (deltaX < 0) deltaX = -deltaX;  /* Need absolute */
         if (deltaY < 0) deltaY = -deltaY;  /* values only.  */

         if (deltaY > deltaX) {

             /* |slope| > 1 */
             if (Y2 < Y1) {
                 /* Swap coordinates, Y1 must be < Y2 */
                 tempVal = Y2; Y2 = Y1; Y1 = tempVal;
                 tempVal = X2; X2 = X1; X1 = tempVal;
             }

             /* Compute deltas and slope */
             deltaX = X2 - X1;
             deltaY = Y2 - Y1;

             /* Slope off the vertical axis */
             slope = deltaX / deltaY;

             /* Plot each pixel starting at (X1, Y1) */
             currX = X1;
             for (currY = Y1; currY <= Y2; currY++) {
                 SetPixel((int)currX, (int)currY, C);
                 currX += slope;    /* increment X by the slope */
             }
             return;

         } else if ((deltaY || deltaX) != 0) {

             /* |slope| < 1 */
             if (X2 < X1) {
                 /* Swap coordinates, X1 must be < X2 */
                 tempVal = X2; X2 = X1; X1 = tempVal;
                 tempVal = Y2; Y2 = Y1; Y1 = tempVal;
             }

             /* Compute deltas and slope */
             deltaX = X2 - X1;
             deltaY = Y2 - Y1;

             /* Slope off the horizontal axis */
             slope = deltaY / deltaX;

             /* Plot each pixel starting at (X1, Y1) */
             currY = Y1;
             for (currX = X1; currX <= X2; currX++) {
                 SetPixel((int)currX, (int)currY, C);
                 currY += slope;    /* increment Y by the slope */
             }
             return;

         } else

             /* Set a single pixel because Y1 = Y2 and X1 = X2 */
             SetPixel(X1, Y1, C);
     }

     void Circle(int xOffset, int yOffset, int radius, unsigned char C)
     {
          float xPlot, yPlot;     /* Current pixel being plotted */
          float angle, angleRad;  /* Current angle degrees & radiens */

          for (angle = 0.; angle < 360.; angle += 0.5) {

               /* Convert degrees to radiens */
               angleRad = angle * (3.141592654 / 180);

               /* Convert polar to rectangular coordinates */
               xPlot = (radius * cos(angleRad)) + xOffset;
               yPlot = (radius * sin(angleRad)) + yOffset;

               /* Check boundaries */
               if (xPlot < 0)
                    xPlot = 0;
               else if (xPlot >= ScreenWidth)
                    xPlot = ScreenWidth - 1;

               if (yPlot < 0)
                    yPlot = 0;
               else if (yPlot >= ScreenHeight)
                    yPlot = ScreenHeight - 1;

               /* Plot the pixel on the graphics screen */
               SetPixel((int)xPlot, (int)yPlot, C);
          }
     }

Whew!!  That was long indeed.  However, if you let a program like this intimidate you, then you are not going to enjoy programming too much for much longer.  Fortunate for you, in this case, the code is ready go right here already tested and debugged.   It runs great under the Turbo C++ 3.0 compiler for DOS (the compiler that I use) and I've taken many steps to get it to work under other compilers by using as many standard functions as possible.   However, I haven't tested it under other compilers so it may not work as expected.  If you are having problems and you can't figure out how to get it to work, let me know and I'll be glad to help.

Previous Page | Main Page | Next page

Send your questions, comments, or ideas to: garyneal@geocities.com