home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 440_01 / examples / examples.__c < prev    next >
Encoding:
Text File  |  1993-07-16  |  49.3 KB  |  950 lines

  1. *** NOTE  the names and structure of the routines used in these examples have
  2.           changed in The Best Library 2.00; the updated examples will be
  3.           released soon
  4.  
  5. EXAMP001.EXE - Prints a simple, common menu in text mode and waits for user
  6.                input.  Only the DOS shell and Exit options perform actual
  7.                tasks.  The other two just print messages signifying their
  8.                uselessness.
  9. EXAMP002.EXE - Prints a common menu in VGA graphics mode and waits for user
  10.                input.  The File-Load menu option enables other menu options,
  11.                as it would in a real program.  The File-New menu option
  12.                disables the menu options enabled with File-Load, as it would
  13.                in a real program.
  14. EXAMP003.EXE - The user is prompted for a string to animate around the screen
  15.                and the millisecond delay between each movement of the string.
  16.                If a mouse is detected, the left mouse button positions the
  17.                text and the right button asks for a new delay and string to
  18.                animate.
  19. EXAMP004.EXE - A little game where the object is to dodge the ever-oncoming
  20.                rocks.  The cursor pad can be used for movement, with or
  21.                without NUM LOCK active, or the right hand side of the keyboard
  22.                QWEASDZXC.  Each key corresponds respectively to the keypad's
  23.                789456123.  Again, the right hand keys work with or without
  24.                CAPS LOCK active.
  25. EXAMP005.EXE - A demonstration program showing off the mouse routines and
  26.                text output routines.  Continually displays the status of the
  27.                mouse cursor's coordinates and button states while filling the
  28.                blank areas of the screen with progressively larger ASCII
  29.                characters and then progressively smaller, in a circuit.
  30. EXAMP006.EXE - An animation demonstration, utilizing all four animation
  31.                procedures.  The first animation sequence will look strange, as
  32.                it was my first attempt at an animation procedure.  The second
  33.                is specifically designed for perfectly square objects; anything
  34.                not perfectly square will have its edges displayed (as in the
  35.                animation).  The third sequence animates any object perfectly
  36.                with NO distortion.  The disadvantage is the slowdown.  The
  37.                fourth animation moves the object one graphic row at a time, so
  38.                it is much quicker, but there is a slight flicker.
  39.  
  40. ==============================================================================
  41.  
  42. EXAMP001.EXE - source code listing
  43.  
  44. #include <stdio.h>
  45. #include "colors.h"
  46. #include "!bestlib.h"
  47.  
  48.    /*** NOTE  even though this program only uses the "keyp" structure, the
  49.               other three are necessary for the assembler routines in the
  50.               !BESTLIB.LIB library to function properly.  C would also
  51.               produce a "linker warning" if you have enabled that warning ***/
  52. filldata fidata;                       /* create a "filldata" structure     */
  53. printdata prdata;                      /* create a "printdata" structure    */
  54. mousedata msdata;                      /* create a "mousedata" structure    */
  55. asciiscan keyp;                        /* create an "asciiscan" structure   */
  56.  
  57. void main(void)
  58. {
  59.    int oldmode;
  60.    char *errmsg;
  61.  
  62.    oldmode = readvideomode();          /* save the current video mode       */
  63.    textm(0);                           /* make sure we are in text mode     */
  64.    textmem(3);                         /* store text video memory           */
  65.    cursor(3, 1);                       /* hide and store cursor position    */
  66.    clear(LIGHTGRAY, BLACK);            /* clear the screen and set colors   */
  67.  
  68.    do {
  69.       printsatxy("Select an option:", 5, 3);
  70.       printsatxy("1) Load", 8, 5);
  71.       printsatxy("2) Save", 8, 6);
  72.       printsatxy("3) Shell to DOS", 8, 7);
  73.       printsatxy("4) Exit program", 8, 8);       /* print small sample menu */
  74.  
  75.       getchr();                        /* wait for a user response          */
  76.       switch(keyp.ascii) {
  77.       case '1':                        /* load was selected                 */
  78.          beep();                       /* beep the speaker                  */
  79.          printsatxy("The Load option has not yet been written", 5, 24);
  80.          break;                        /* exit from switch statement        */
  81.       case '2':
  82.          beep();                       /* beep the speaker                  */
  83.          printsatxy("The Save option has not yet been written", 5, 24);
  84.          break;                        /* exit from switch statement        */
  85.       case '3':                        /* shell to DOS was selected         */
  86.          cursor(1, 1);                 /* show and restore cursor position  */
  87.          if ((errmsg = dosshell()) != NULL)
  88.             printsatxy(errmsg, 5, 24); /* print the returned error message  */
  89.          else {                        /* else if no error occurred..       */
  90.             cursor(3, 0);              /* hide and store ignore position    */
  91.             clear(LIGHTGRAY, BLACK);   /* clear the screen and set colors   */
  92.             printsatxy("Welcome back!", 5, 24);
  93.          }
  94.          break;                        /* exit from switch statement        */
  95.       case '4':                        /* exit program was selected         */
  96.          changevideomode(oldmode);     /* restore the original video mode   */
  97.          if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  98.                                        /* if the old mode was a text mode.. */
  99.             textmem(1);                /* restore text video memory         */
  100.             cursor(1, 1);              /* show and restore cursor position  */
  101.          }
  102.          break;                        /* exit from switch statement        */
  103.       default:                         /* the user pressed an invalid key   */
  104.          printsatxy("That is not a valid choice              ", 5, 24);
  105.          beep();                       /* beep the speaker to denote error  */
  106.       }
  107.    } while (keyp.ascii != '4');        /* loop until exit is chosen         */
  108. }
  109.  
  110. ------------------------------------------------------------------------------
  111.  
  112. EXAMP002.EXE source code listing:
  113.  
  114. #include <stdio.h>
  115. #include <stdlib.h>
  116. #include <graphics.h>
  117. #include "colors.h"
  118. #include "!bestlib.h"
  119.  
  120. #define FILE 1
  121. #define SORT 2
  122. #define PRINT 3
  123. #define SCREEN 4
  124. #define DOS 5
  125.  
  126. #define NEW 1
  127. #define LOAD 2
  128. #define SAVE 3
  129. #define FONTSIZE 1
  130. #define BLOCK 1
  131. #define ENTIREDOCUMENT 2
  132. #define EXTERNALFILE 3
  133. #define EXITTO 1
  134. #define SHELLTO 2
  135.  
  136. #define BGCOLOR DARKGRAY               /* background color                  */
  137. #define TEXTCOLOR WHITE                /* color of text messages            */
  138. #define ABORTCOLOR RED                 /* color of abort messages           */
  139. #define ERASECOMMANDTEXT boxfill(0, txty, MAXX, txtht, BGCOLOR, COPY_IMAGE);
  140.  
  141.    /*** NOTE  even though this program only uses the "keyp" structure, the
  142.               other three are necessary for the assembler routines in the
  143.               !BESTLIB.LIB library to function properly.  C would also
  144.               produce a "linker warning" if you have enabled that warning ***/
  145. filldata fidata;                       /* create a "filldata" structure     */
  146. printdata prdata;                      /* create a "printdata" structure    */
  147. mousedata msdata;                      /* create a "mousedata" structure    */
  148. asciiscan keyp;                        /* create an "asciiscan" structure   */
  149.  
  150. char *menu1ptr[] = { "FILE", "SORT", "PRINT", "SCREEN", "DOS" };   /* menus */
  151. char *menu1text[] = {                                           /* submenus */
  152.    (char *)0x001D,
  153.    "NEW", "LOAD", "SAVE",
  154.    "BLOCK", "ENTIRE DOCUMENT", "EXTERNAL FILE",
  155.    "FONT SIZE",
  156.    "EXIT TO", "SHELL TO"
  157. };
  158. int menu1data[][3] = { { 3, 1, 0x0007 },
  159.                        { 0, 0, 0x0000 },
  160.                        { 3, 4, 0x0004 },
  161.                        { 1, 7, 0x0001 },
  162.                        { 2, 8, 0x0003 }
  163. };
  164.  
  165. void main(void)
  166. {
  167.    int gr_err, gdrv = VGA, gmod = VGAHI, fontsize = 5,
  168.        oldmode, mouse = FALSE, command = FALSE, submenu,
  169.        txtht = 15, txty = 465, menu, menux = MAXX / 3, menuy = 220;
  170.    char *errmsg;
  171.  
  172.    oldmode = readvideomode();          /* save the current video mode       */
  173.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  174.                                        /* if the old mode was a text mode.. */
  175.       textmem(3);                      /* store text video memory           */
  176.       cursor(3, 1);                    /* hide and store cursor position    */
  177.    }
  178.    mouse = initms_gr();             /* initialize mouse driver if installed */
  179.    initgraph(&gdrv, &gmod, "");        /* initialize graphics mode          */
  180.    if ((gr_err = graphresult()) != grOk) {
  181.       /* if an error occurred in changing to graphics mode, print the error */
  182.       printf("Graphics error: %s\n", grapherrormsg(gr_err));
  183.       exit(1);                        /* exit to DOS returning errorlevel 1 */
  184.    }
  185.    settextjustify(LEFT_TEXT, TOP_TEXT);
  186.    settextstyle(SMALL_FONT, HORIZ_DIR, fontsize);  /* setup font size/style */
  187.    floodall(BGCOLOR);                  /* create the screen background      */
  188.    do {
  189.       command = popupmenu(menux, menuy, 1, 5,
  190.                           menu1ptr, menu1data, menu1text, mouse);
  191.       if (command == -1) break;       /* if unable to allocate memory, exit */
  192.       submenu = command & 0x000F, menu = command >> 4;
  193.       setcolor(TEXTCOLOR);             /* set the appropriate text color    */
  194.       switch(menu) {
  195.       case FILE:                       /* a selection from the file menu    */
  196.          switch(submenu) {
  197.          case NEW:                     /* the new submenu was selected      */
  198.             menu1text[0] = (char *)0x001D;  /* restore menu restrictions    */
  199.             menu1data[2][2] = 0x0004;       /* disable submenu restrictions */
  200.             ERASECOMMANDTEXT;               /* erase any previous messages  */
  201.             outtextxy(0, txty, "The NEW submenu was selected -- some options \
  202. disabled");
  203.             break;
  204.          case LOAD:                    /* the load submenu was selected     */
  205.             menu1text[0] = (char *)0x001F;  /* enable menu restrictions     */
  206.             menu1data[2][2] = 0x0007;       /* enable submenu restrictions  */
  207.             ERASECOMMANDTEXT;               /* erase any previous messages  */
  208.             outtextxy(0, txty, "The LOAD submenu was selected -- some options\
  209.  enabled");
  210.             break;
  211.          case SAVE: ;                  /* the save submenu was selected     */
  212.             ERASECOMMANDTEXT;          /* erase any previous messages       */
  213.             outtextxy(0, txty, "The SAVE submenu was selected");
  214.             break;
  215.          }
  216.          break;                        /* exit from switch statement        */
  217.       case SORT:                       /* the sort menu was selected        */
  218.          ERASECOMMANDTEXT;             /* erase any previous messages       */
  219.          outtextxy(0, txty, "The SORT menu was selected");
  220.          break;                        /* exit from switch statement        */
  221.       case PRINT:                      /* a selection from the print menu   */
  222.          switch(submenu) {
  223.          case BLOCK:                   /* the block submenu was selected    */
  224.             ERASECOMMANDTEXT;          /* erase any previous messages       */
  225.             outtextxy(0, txty, "The BLOCK submenu was selected");
  226.             break;
  227.          case ENTIREDOCUMENT:          /* the entiredocument was selected   */
  228.             ERASECOMMANDTEXT;          /* erase any previous messages       */
  229.             outtextxy(0, txty, "The ENTIRE DOCUMENT submenu was selected");
  230.             break;
  231.          case EXTERNALFILE: ;          /* the externalfile was selected     */
  232.             ERASECOMMANDTEXT;          /* erase any previous messages       */
  233.             outtextxy(0, txty, "The EXTERNAL FILE submenu was selected");
  234.             break;
  235.          }
  236.          break;                        /* exit from switch statement        */
  237.       case SCREEN:                     /* a selection from the fonts menu   */
  238.          switch(submenu) {
  239.          case FONTSIZE:         /* the select new font submenu was selected */
  240.             textm(0);                  /* make sure we are in text mode     */
  241.             clear(LIGHTGRAY, BLACK);   /* clear the screen and set colors   */
  242.             printsatxy("What font size would you like to use (1-7)?", 10, 12);
  243.             readnumber(7, 1, 54, 12, &fontsize);  /* ask user for font size */
  244.             initgraph(&gdrv, &gmod, "");     /* re-initialize graphics mode */
  245.             settextstyle(SMALL_FONT, HORIZ_DIR, fontsize);     /* font size */
  246.             txtht = textheight("A") + 3;     /* initialize text height      */
  247.             txty = MAXY - txtht;             /* initialize text y-coord     */
  248.             menux = MAXX - (textwidth(menu1ptr[3])+17 +
  249.                     textwidth(menu1text[4])+33 + textwidth(menu1text[5])+33 +
  250.                     textwidth(menu1text[6])+33);  /* calculate text x-coord */
  251.             if (menux > MAXX / 3) menux = MAXX / 3;
  252.             floodall(BGCOLOR);         /* create the screen background      */
  253.          }
  254.          break;                        /* exit from switch statement        */
  255.       case DOS:                        /* a selection from the DOS menu     */
  256.          switch(submenu) {
  257.          case EXITTO: break;           /* the exit to submenu was selected  */
  258.          case SHELLTO:                 /* the shell to submenu was selected */
  259.             if ((errmsg = dosshell()) != NULL) {
  260.                ERASECOMMANDTEXT;       /* erase any previous messages       */
  261.                while (textwidth(errmsg) > MAXX)  /* entire message must fit */
  262.                   settextstyle(SMALL_FONT, HORIZ_DIR, --fontsize);
  263.                outtextxy(0, txty, errmsg);  /* print the returned error msg */
  264.             }
  265.             else {                     /* else if no error occurred..       */
  266.                highstandardvga();      /* get back into 640x480x16 mode VGA */
  267.                settextjustify(LEFT_TEXT, TOP_TEXT);
  268.                settextstyle(SMALL_FONT, HORIZ_DIR, fontsize);
  269.                floodall(BGCOLOR);      /* restore the screen background     */
  270.                outtextxy(0, txty, "Welcome back!");
  271.             }
  272.             break;
  273.          }
  274.          break;
  275.       case FALSE:                      /* no selection was registered       */
  276.          setcolor(ABORTCOLOR);         /* set the appropriate abort color   */
  277.          ERASECOMMANDTEXT;             /* erase any previous messages       */
  278.          outtextxy(0, txty, "Operation aborted");
  279.          setcolor(TEXTCOLOR);          /* restore text message color        */
  280.          break;                        /* exit from switch statement        */
  281.       }
  282.    } while (menu != DOS || submenu != EXITTO);  /* loop until exit selected */
  283.  
  284.    changevideomode(oldmode);           /* restore the original video mode   */
  285.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  286.                                        /* if the old mode was a text mode.. */
  287.       textmem(1);                      /* restore text video memory         */
  288.       cursor(1, 1);                    /* show and restore cursor position  */
  289.    }
  290. }
  291.  
  292. ------------------------------------------------------------------------------
  293.  
  294. EXAMP003.EXE source code listing:
  295.  
  296. #include <stdlib.h>
  297. #include "colors.h"
  298. #include "!bestlib.h"
  299.  
  300.    /*** NOTE  even though this program only uses the "keyp" and "prdata"
  301.               structures, the other two are necessary for the assembler
  302.               routines in the !BESTLIB.LIB library to function properly.  C
  303.               would also produce a "linker warning" if you have enabled that
  304.               warning                                                     ***/
  305. filldata fidata;                       /* create a "filldata" structure     */
  306. printdata prdata = { WHITE, BLUE, -1, 1, 1, "Press any key to exit" };
  307.     /* see "printdata" under GLOBAL VARIABLES for explanation of the values */
  308. mousedata msdata;                      /* create a "mousedata" structure    */
  309. asciiscan keyp;                        /* create an "asciiscan" structure   */
  310.  
  311. void main(void)
  312. {
  313.    int oldmode, deltax = 1, deltay = 1, mouse, delaytime, z;
  314.    char input[80];          /* enough space for a 79-letter string and NULL */
  315.  
  316.    oldmode = readvideomode();          /* save the current video mode       */
  317.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  318.                                        /* if the old mode was a text mode.. */
  319.       textmem(3);                      /* store text video memory           */
  320.       cursor(3, 1);                    /* hide and store cursor position    */
  321.    }
  322.    textm(1);                          /* change to 80x25x16 color text mode */
  323.    clear(LIGHTGRAY, BLACK);            /* clear the screen and set colors   */
  324.    printsatxy("What text would you like to be animated? (79 letters maximum)",
  325.                1, 10);
  326.    z = readstring(input, 79, 0, 11);   /* ask user for the text to animate  */
  327.    if (z == -1) prdata.string2print = "Demonstration";
  328.    else prdata.string2print = input;   /* set up the text for printing      */
  329.    printsatxy("Enter movement delay in milliseconds (1-1000): [30]", 1, 13);
  330.    z = readnumber(1000, 1, 53, 13, &delaytime);  /* ask user for delay time */
  331.    if (z == FALSE) delaytime = 30;     /* if <ENTER> or <ESC>, use default  */
  332.    clear(WHITE, BLUE);                 /* clear the screen and set colors   */
  333.    mouse = initms();                   /* initialize mouse if installed     */
  334.    msec(1);                            /* initialize CPU-independent delay  */
  335.  
  336.    if (mouse == TRUE)                  /* if the mouse was initialized..    */
  337.       xyminmaxms(9, 4, 70, 20);        /* restrict its movement (for show)  */
  338.    while (!keyhit()) {                 /* loop until a key is pressed       */
  339.       print();                         /* print user-inputted text          */
  340.       if (mouse == TRUE) printsatxy("The mouse is just for show", 27, 0);
  341.       printsatxy("Press any key to exit", 29, 24);
  342.       if (mouse == TRUE) showms();     /* restore mouse cursor onto screen  */
  343.       msec(delaytime);                 /* wait 10 milliseconds              */
  344.       if (mouse == TRUE) hidems();     /* hide mouse before a screen update */
  345.       if (prdata.x >= 80 - stringlenpr() || prdata.x <= 0)
  346.                                        /* if the x-coordinate is at an edge */
  347.          deltax = -deltax;             /* reverse the x-increment (negate)  */
  348.       if (prdata.y >= 24 || prdata.y <= 0) /* if y-coordinate is at an edge */
  349.          deltay = -deltay;             /* reverse the y-increment (negate)  */
  350.       stringerasepr();                 /* erase user inputted text          */
  351.       prdata.x += deltax,
  352.       prdata.y += deltay;              /* increment the x and y coordinates */
  353.    }
  354.  
  355.    changevideomode(oldmode);           /* restore the original video mode   */
  356.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  357.                                        /* if the old mode was a text mode.. */
  358.       textmem(1);                      /* restore text video memory         */
  359.       cursor(1, 1);                    /* show and restore cursor position  */
  360.    }
  361. }
  362.  
  363. ------------------------------------------------------------------------------
  364.  
  365. EXAMP004.EXE source code listing:
  366.  
  367. #include <dos.h>
  368. #include <stdlib.h>
  369. #include "colors.h"
  370. #include "!bestlib.h"
  371.  
  372. #define ROCK 219                       /* ASCII code for the oncoming rocks */
  373. #define FACEMAN 1                      /* ASCII code for the main character */
  374. #define MAXROCKS 200                   /* the maximum number of rocks       */
  375. #define MAXROCKDELAY 6                 /* the maximum delay in clock ticks  */
  376. #define SCREENX 80                     /* number of characters on x axis    */
  377. #define SCREENY 50                     /* number of characters on y axis    */
  378.  
  379. void moverock(void);                   /* procedure definition to move rock */
  380. void movefaceman(void);      /* procedure definition to move main character */
  381.  
  382.    /*** NOTE  even though this program only uses the "keyp" structure, the
  383.               other three are necessary for the assembler routines in the
  384.               !BESTLIB.LIB library to function properly.  C would also
  385.               produce a "linker warning" if you have enabled that warning ***/
  386. filldata fidata;                       /* create a "filldata" structure     */
  387. printdata prdata;                      /* create a "printdata" structure    */
  388. mousedata msdata;                      /* create a "mousedata" structure    */
  389. asciiscan keyp;                        /* create an "asciiscan" structure   */
  390.  
  391. struct {                               /* the rock data structure           */
  392.    int x;                              /* the current x-coordinate          */
  393.    int y;                              /* the current y-coordinate          */
  394.    int oldx;                           /* the old x-coordinate              */
  395.    int oldy;                           /* the old y-coordinate              */
  396.    int dir;                            /* the direction                     */
  397. } rock[MAXROCKS];                      /* create an array for all the rocks */
  398.  
  399. struct {                               /* the main character data structure */
  400.    int x;                              /* the current x-coordinate          */
  401.    int y;                              /* the current y-coordinate          */
  402.    int oldx;                           /* the old x-coordinate              */
  403.    int oldy;                           /* the old y-coordinate              */
  404.    int dir;                            /* the direction                     */
  405. } faceman;                             /* only one main character           */
  406.  
  407. void main(void)
  408. {
  409.    int oldmode;
  410.    register int i;                     /* register class speeds up loops    */
  411.  
  412.    for (i = 0; i < MAXROCKS; i++) {    /* initialize rock structures        */
  413.       stopw(i, random(MAXROCKDELAY));  /* initialize stop watch             */
  414.       rock[i].x = rock[i].oldx = 0;    /* initialize x-coordinate           */
  415.       rock[i].y = rock[i].oldy = random(SCREENY);    /* random y-coordinate */
  416.       rock[i].dir = 3;                 /* initialize default direction      */
  417.    }
  418.    faceman.dir = 0;                /* initialize main character's direction */
  419.    faceman.x = faceman.oldx = 40;    /* initialize main character's y-coord */
  420.    faceman.y = faceman.oldy = 13;    /* initialize main character's x-coord */
  421.  
  422.    oldmode = readvideomode();          /* save the current video mode       */
  423.    textm(2);                           /* change to 50 line text mode       */
  424.    textmem(3);                         /* store text video memory           */
  425.    cursor(3, 1);                       /* hide and store cursor position    */
  426.    clear(LIGHTGREEN, BLUE);            /* clear the screen and set colors   */
  427.    printcatxy(FACEMAN, faceman.x, faceman.y);    /* draw the main character */
  428.  
  429.    do {
  430.       movefaceman();                   /* move the main character           */
  431.       moverock();                      /* move one rock at a time           */
  432.       printsatxy("Press <ESC> to exit", 30, 24);
  433.    } while (keyp.ascii != 27);         /* loop until <ESC> key is pressed   */
  434.  
  435.    changevideomode(oldmode);           /* restore the original video mode   */
  436.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  437.                                        /* if the old mode was a text mode.. */
  438.       textmem(1);                      /* restore text video memory         */
  439.       cursor(1, 1);                    /* show and restore cursor position  */
  440.    }
  441. }
  442.  
  443. /*
  444.  * MOVE ONE ROCK AT A TIME AND RANDOMLY SET THE NEW DELAY BEFORE THE NEXT MOVE
  445.  */
  446. void moverock(void)
  447. {
  448.    static int i = 0;                   /* this variable is never lost       */
  449.  
  450.    if (stopw(i, 0) > 0) {              /* if it is time to move this rock.. */
  451.       if (++rock[i].x >= SCREENX) {    /* if the rock is at the boundary..  */
  452.          rock[i].x = 0;                /* reset its x-coordinate            */
  453.          rock[i].y = random(SCREENY);  /* randomly reset its y-coordinate   */
  454.       }
  455.       printcatxy(32, rock[i].oldx, rock[i].oldy);     /* erase the old rock */
  456.       printcatxy(ROCK, rock[i].x, rock[i].y);         /* draw the new rock  */
  457.       rock[i].oldx = rock[i].x;  /* modify the old x-coordinate of the rock */
  458.       rock[i].oldy = rock[i].y;  /* modify the old y-coordinate of the rock */
  459.       stopw(i, random(MAXROCKDELAY)); /* new random delay for the next move */
  460.    }
  461.    if (++i >= MAXROCKS) i = 0;  /* if all rocks have moved, restart from #1 */
  462. }
  463.  
  464. /*
  465.  * MOVES THE MAIN CHARACTER ACCORDING TO KEYPRESS, REGARDLESS OF NUM LOCK
  466.  *
  467.  *                                      1         5   6       5 1 6
  468.  *                                     \|/         \|/         \|/
  469.  *                    DIRECTIONS:    2--+--3      --+--      2--+--3
  470.  *                                     /|\         /|\         /|\
  471.  *                                      4         7   8       7 4 8
  472.  */
  473. void movefaceman(void)
  474. {
  475.    register int i;
  476.  
  477.    for (i = 0; i < MAXROCKS; i++) {    /* check for a collision with a rock */
  478.       if (rock[i].x == faceman.x && rock[i].y == faceman.y) {
  479.      sound(120); msec(400);        /* create a 120 Hz sound for 400 ms  */
  480.          sound(40); msec(850);         /* create a 40 Hz sound for 850 ms   */
  481.          nosound();                    /* silence the speaker               */
  482.       }
  483.    }
  484.    if (keyhit() == FALSE) return;      /* if not keypress ready, return     */
  485.    getchr();                 /* read the keypress into the "keyp" structure */
  486.    kbclear();         /* clear all other character from the keyboard buffer */
  487.    keyp.ascii = dncase(keyp.ascii);    /* convert to lowercase if UPPERCASE */
  488.    if (!keyp.ascii)                    /* if there is no ASCII code..       */
  489.       keyp.ascii = keyp.scan;          /* read the scan code                */
  490.    switch(keyp.ascii) {
  491.    case 56 :                           /* direction 1, NUM LOCK active      */
  492.    case 72 :                           /* direction 1, NUM LOCK inactive    */
  493.    case 119: faceman.y--; break;       /* direction 1, right letter-pad     */
  494.    case 52 :                           /* direction 2, NUM LOCK active      */
  495.    case 75 :                           /* direction 2, NUM LOCK inactive    */
  496.    case 97 : faceman.x--; break;       /* direction 2, right letter-pad     */
  497.    case 54 :                           /* direction 3, NUM LOCK active      */
  498.    case 77 :                           /* direction 3, NUM LOCK inactive    */
  499.    case 100: faceman.x++; break;       /* direction 3, right letter-pad     */
  500.    case 50 :                           /* direction 4, NUM LOCK active      */
  501.    case 80 :                           /* direction 4, NUM LOCK inactive    */
  502.    case 120: faceman.y++; break;       /* direction 4, right letter-pad     */
  503.    case 55 :                           /* direction 5, NUM LOCK active      */
  504.    case 71 :                           /* direction 5, NUM LOCK inactive    */
  505.    case 113: faceman.x--, faceman.y--; break;
  506.                                        /* direction 5, right letter-pad     */
  507.    case 57 :                           /* direction 6, NUM LOCK active      */
  508.    case 73 :                           /* direction 6, NUM LOCK inactive    */
  509.    case 101: faceman.x++, faceman.y--; break;
  510.                                        /* direction 6, right letter-pad     */
  511.    case 49 :                           /* direction 7, NUM LOCK active      */
  512.    case 79 :                           /* direction 7, NUM LOCK inactive    */
  513.    case 122: faceman.x--, faceman.y++; break;
  514.                                        /* direction 7, right letter-pad     */
  515.    case 51 :                           /* direction 8, NUM LOCK active      */
  516.    case 81 :                           /* direction 8, NUM LOCK inactive    */
  517.    case 99 : faceman.x++, faceman.y++; /* direction 8, right letter-pad     */
  518.    }
  519.    if (faceman.x < 0) faceman.x = 0;   /* movement beyond the screen edge.. */
  520.    if (faceman.y < 0) faceman.y = 0;   /* not allowed                       */
  521.    if (faceman.y > SCREENY - 1) faceman.y = SCREENY - 1;
  522.    if (faceman.x > SCREENX - 1) faceman.x = SCREENX - 1;
  523.    printcatxy(32, faceman.oldx, faceman.oldy);  /* erase the main character */
  524.    printcatxy(FACEMAN, faceman.x, faceman.y);   /* print the main character */
  525.    faceman.oldx = faceman.x;    /* modify old x-coord of the main character */
  526.    faceman.oldy = faceman.y;    /* modify old y-coord of the main character */
  527. }
  528.  
  529. ------------------------------------------------------------------------------
  530.  
  531. EXAMP005.EXE - source code listing
  532.  
  533. #include <stdio.h>
  534. #include <stdlib.h>
  535. #include "colors.h"
  536. #include "!bestlib.h"
  537.  
  538. #define ERR01 0
  539. #define MSG01 1
  540. #define MSG02 2
  541. #define MSG03 3
  542. #define MSG04 4
  543. #define MSG05 5
  544. #define MSG06 6
  545. #define MSG07 7
  546. #define MSG08 8
  547. #define MSG09 9
  548. #define MSG0A 10
  549. #define MSG0B 11
  550. #define MSG0C 12
  551. #define LOC1 7
  552. #define LOC2 11
  553. #define LOC3 5
  554. #define LOC4 0
  555. #define LOC5 24
  556. #define QUE01 13
  557. #define QUE02 14
  558. #define QUE03 15
  559. #define TXT01 16
  560.  
  561. void floodtext(void);
  562. void showtext(void);
  563.  
  564. filldata  fidata = { GREEN, BLACK, 0, 0, 0, 80, 25, 32, 0, "" };
  565. printdata prdata = { -1, -1, -1, 0, 0, "" };
  566. mousedata msdata;
  567. asciiscan keyp;
  568.  
  569. char buffer[70];
  570. char *text[] = {
  571.    "!!! ERROR OCCURRED INITIALIZING THE MOUSE DRIVER !!!",        /* ERR01 */
  572.    "Demonstration of Microsoft compatible mouse routines",        /* MSG01 */
  573.    "Authored independently by George Vanous",                     /* MSG02 */
  574.    "left button is not pressed",                                  /* MSG03 */
  575.    "left button is pressed    ",                                  /* MSG04 */
  576.    "left button was pressed at",                                  /* MSG05 */
  577.    "left button was released at",                                 /* MSG06 */
  578.    "right button is not pressed",                                 /* MSG07 */
  579.    "right button is pressed    ",                                 /* MSG08 */
  580.    "right button was pressed at",                                 /* MSG09 */
  581.    "right button was released at",                                /* MSG0A */
  582.    " cursor is located at",                                       /* MSG0B */
  583.    "press any key to terminate",                                  /* MSG0C */
  584.    "Do you wish to continue regardless?",                         /* QUE01 */
  585.    "Which ASCII character to use as cursor? [219]",               /* QUE02 */
  586.    "What color? [7]",                                             /* QUE03 */
  587.    "ASCII table",                                                 /* TXT01 */
  588. };
  589.  
  590. void main(void)
  591. {
  592.    int chart, color, oldmode, z;
  593.  
  594.    if (!initms()) {                    /* if the mouse could not be found   */
  595.       cursorwhere(&prdata.x);          /* stores the position of the cursor */
  596.       prdata.string2print = text[ERR01];
  597.       print();                         /* print the error message           */
  598.       prdata.string2print = text[QUE01];
  599.       prdata.y++;
  600.       print();                         /* print the question                */
  601.       if (upcase(getchre()) != 'Y')    /* if the user response was not Yes  */
  602.          exit(1);                      /* exit to DOS with errorlevel 1     */
  603.    }
  604.    oldmode = readvideomode();          /* save the current video mode       */
  605.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  606.       textmem(3);   /* if old mode was a text mode, store text video memory */
  607.       cursor(3, 1);                    /* hide and store cursor position    */
  608.    }
  609.    textm(1);                          /* change to 80x25x16 color text mode */
  610.    clear(LIGHTGRAY, BLACK);            /* clear the screen and set colors   */
  611.  
  612.    prdata.x = 5, prdata.y = 11;        /* set the next print position       */
  613.    prdata.string2print = text[QUE02];
  614.    print();                            /* print the question                */
  615.    z = readnumber(255, 1, prdata.x + stringlen(prdata.string2print)+1,
  616.                   prdata.y, &chart);   /* get the user's input              */
  617.    if (z == FALSE) chart = 219;        /* if <ENTER> or <ESC>, use default  */
  618.    prdata.y += 2;                      /* set the next print position       */
  619.    prdata.string2print = text[QUE03];
  620.    print();                            /* print the question                */
  621.    z = readnumber(15, 0, prdata.x + stringlen(prdata.string2print)+1,
  622.                   prdata.y, &color);   /* get the user's input              */
  623.    if (z == FALSE) color = 7;          /* if <ENTER> or <ESC>, use default  */
  624.  
  625.    clear(LIGHTGRAY, BLACK);            /* clear the screen and set colors   */
  626.    showtext();                         /* print up the screen               */
  627.    prdata.y = LOC1;                    /* define the y-coordinate to print  */
  628.    prdata.command = -1;                /* specify no modifications          */
  629.    prdata.string2print = text[MSG03];
  630.    print();                            /* print left mouse button status    */
  631.    prdata.y = LOC2;                    /* define the y-coordinate to print  */
  632.    prdata.string2print = text[MSG07];
  633.    print();                            /* print right mouse button status   */
  634.    shapems(chart, color, -1);          /* change the mouse cursor and color */
  635.    showms();                           /* display the mouse cursor          */
  636.    stopw(0, 15);                       /* start stopwatch 0                 */
  637.  
  638.    while (!keyhit()) {
  639.       floodtext();                     /* fill the entire screen            */
  640.       statms();                        /* read the mouse status             */
  641.       if (msdata.pos[0] != msdata.npos[0]) {
  642.          msdata.pos[0] = msdata.npos[0];
  643.          msdata.update += 1;           /* if the mouse x-position changed.. */
  644.       }
  645.       if (msdata.pos[1] != msdata.npos[1]) {
  646.          msdata.pos[1] = msdata.npos[1];
  647.          msdata.update += 2;           /* if the mouse y-position changed.. */
  648.       }
  649.       if (msdata.buts[0] != msdata.nbuts[0]) {
  650.          msdata.buts[0] = ~msdata.buts[0];
  651.          msdata.update += 4;    /* if the left mouse button state changed.. */
  652.       }
  653.       if (msdata.buts[1] != msdata.nbuts[1]) {
  654.          msdata.buts[1] = ~msdata.buts[1];
  655.          msdata.update += 8;   /* if the right mouse button state changed.. */
  656.       }
  657.       if (msdata.update) {             /* if mouse registered activity..    */
  658.          msdata.update = 0;            /* reset the mouse activity flag     */
  659.          prdata.fgcolor = YELLOW;      /* set the foreground text color     */
  660.          prdata.command = 0;           /* specify text to be centered       */
  661.          prdata.x = 0, prdata.y = LOC3;     /* define the location to print */
  662.          sprintf((prdata.string2print = buffer), "%s %d, %d  ",
  663.                                    text[MSG0B], msdata.pos[0], msdata.pos[1]);
  664.          hidems();                    /* hide mouse cursor, updating screen */
  665.          print();                      /* print cursor location             */
  666.          prdata.command = -1;          /* specify no modifications          */
  667.          prdata.y = LOC1;              /* define y-coordinate of next print */
  668.          if (!msdata.buts[0]) {        /* if left button is not pressed..   */
  669.             prdata.string2print = text[MSG03];
  670.             print();                   /* print left button is not pressed  */
  671.             sprintf((prdata.string2print = buffer), "%s %d, %d  ",
  672.                                text[MSG06], msdata.butlr[0], msdata.butlr[1]);
  673.             prdata.y++;                /* increment y-coordinate of print   */
  674.          }
  675.          else {                        /* else left button is pressed..     */
  676.             prdata.string2print = text[MSG04];
  677.             print();                   /* print left button is pressed      */
  678.             sprintf((prdata.string2print = buffer), "%s %d, %d  ",
  679.                                text[MSG05], msdata.butlp[0], msdata.butlp[1]);
  680.             prdata.y += 2;             /* add to y-coordinate of print      */
  681.          }
  682.          print();                      /* print left button coordinates     */
  683.          prdata.y = LOC2;              /* define new y-coordinate for print */
  684.          if (!msdata.buts[1]) {        /* if right button is not pressed..  */
  685.             prdata.string2print = text[MSG07];
  686.             print();                   /* print right button is not pressed */
  687.             sprintf((prdata.string2print = buffer), "%s %d, %d  ",
  688.                                text[MSG0A], msdata.butrr[0], msdata.butrr[1]);
  689.             prdata.y++;                /* increment y-coordinate of print   */
  690.          }
  691.          else {                        /* else right button is pressed..    */
  692.             prdata.string2print = text[MSG08];
  693.             print();                   /* print right button is pressed     */
  694.             sprintf((prdata.string2print = buffer), "%s %d, %d  ",
  695.                                text[MSG09], msdata.butrp[0], msdata.butrp[1]);
  696.             prdata.y += 2;             /* add to y-coordinate of print      */
  697.          }
  698.          print();                      /* print right button coordinates    */
  699.          showms();                     /* show mouse cursor, done updating  */
  700.       }
  701.    }
  702.    changevideomode(oldmode);           /* restore the original video mode   */
  703.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  704.                                        /* if the old mode was a text mode.. */
  705.       textmem(1);                      /* restore text video memory         */
  706.       cursor(1, 1);                    /* show and restore cursor position  */
  707.    }
  708. }
  709.  
  710. /*
  711.  *  32 250 249 46 7 176 177 178 219
  712.  *      ·   ∙   .    ░   ▒   ▓   █
  713.  */
  714. void floodtext(void)
  715. #define FLOODCHARNO 8
  716. {
  717.    static int cycle = 1, dir = 1,
  718.               data[] = { 32, 250, 249, 46, 7, 176, 177, 178, 219 };
  719.  
  720.    if (stopw(0, 0) == TRUE) {
  721.       fidata.fillchar = data[cycle];   /* set the character to fill with    */
  722.       fidata.char2overwrite = data[cycle - dir];   /* set char to overwrite */
  723.       if (cycle == FLOODCHARNO || (cycle == 1 && dir < 0))
  724.          dir = -dir;        /* start cycling the fill characters in reverse */
  725.       cycle += dir;                    /* get the next fill character       */
  726.       hidems(); fillarea(); showms();  /* fill screen with the character    */
  727.       msdata.update++;                 /* reprint the mouse status onscreen */
  728.       showtext();                      /* reprint the standard text         */
  729.       stopw(0, 15);                    /* reset stopwatch 0                 */
  730.    }
  731. }
  732.  
  733. /*
  734.  * PRINTS INITIAL TEXT
  735.  */
  736. void showtext(void)
  737. {
  738.    prdata.fgcolor = WHITE, prdata.bgcolor = BLUE;    /* set printing colors */
  739.    prdata.command = 0;                 /* center the text to print          */
  740.    prdata.x = 0, prdata.y = LOC4;      /* define the coordinates to print   */
  741.    prdata.string2print = text[MSG01];
  742.    print();                            /* print first line of title         */
  743.    prdata.y++;                         /* increment the y-coordinate        */
  744.    prdata.string2print = text[MSG02];
  745.    print();                            /* print second line of title        */
  746.    prdata.y = LOC5;                    /* define the y-coordinate to print  */
  747.    prdata.string2print = text[MSG0C];
  748.    print();                            /* print the "any key exits" message */
  749. }
  750.  
  751. ------------------------------------------------------------------------------
  752.  
  753. EXAMP006.EXE - source code listing
  754.  
  755. #include <alloc.h>
  756. #include <stdlib.h>
  757. #include <graphics.h>
  758. #include "colors.h"
  759. #include "!bestlib.h"
  760.  
  761. #define BGCOLOR BLACK                  /* background color                  */
  762.  
  763.    /*** NOTE  even though this program only uses the "keyp" and "msdata"
  764.               structures, the other two are necessary for the assembler
  765.               routines in the !BESTLIB.LIB library to function properly.  C
  766.               would also produce a "linker warning" if you have enabled that
  767.               warning                                                     ***/
  768. filldata fidata;                       /* create a "filldata" structure     */
  769. printdata prdata;                      /* create a "printdata" structure    */
  770. mousedata msdata;                      /* create a "mousedata" structure    */
  771. asciiscan keyp;                        /* create an "asciiscan" structure   */
  772.  
  773. void main(void)
  774. {
  775.    typedef struct {
  776.       int x;
  777.       int y;
  778.       int maxx;
  779.       int maxy;
  780.    } graphicobject;
  781.  
  782.    graphicobject *graphic;
  783.    int oldmode, mouse, gdrv = VGA, gmod = VGAHI;
  784.    register int i, ii;
  785.    void *bgscrn[3], *image_or[1], *image[3];
  786.  
  787.    if (coreleft() < 280000L) {         /* if we do not have enough memory.. */
  788.       textm(0);                        /* make sure we are in a text mode   */
  789.       printsatcur("Insufficient memory to run EXAMP006.EXE");
  790.       exit(1);                         /* exit to DOS with errorlevel 1     */
  791.    }
  792.    if (isitega() == FALSE) {
  793.       textm(0);                        /* make sure we are in a text mode   */
  794.       printsatcur("I do not detect an EGA/VGA card, are you sure you have \
  795. one (Y/N)?");        /* a break is necessary or it wouldn't fit on one line */
  796.       getchr();
  797.       if (upcase(keyp.ascii) != 'Y')   /* if the user did not press 'Y'..   */
  798.          exit(2);                      /* exit to DOS with errorlevel 2     */
  799.    }
  800.    if ((oldmode = readvideomode()) == 3 || oldmode == 7 || oldmode == 21) {
  801.                                        /* if the old mode was a text mode.. */
  802.       textmem(3);                      /* store text video memory           */
  803.       cursor(3, 1);                    /* hide and store cursor position    */
  804.    }
  805.    initgraph(&gdrv, &gmod, "");        /* initialize graphics mode          */
  806.    settextjustify(LEFT_TEXT, TOP_TEXT);
  807.    settextstyle(SMALL_FONT, HORIZ_DIR, 4);         /* setup font size/style */
  808.  
  809.    mouse = initms_gr();             /* initialize mouse driver if installed */
  810.    floodall(BGCOLOR);                  /* create the screen background      */
  811.  
  812.    for (i = 0; i < 5; i++)             /* create the screen border          */
  813.       boxoutline(i, i, MAXX - i*2, MAXY - i*2, YELLOW, COPY_IMAGE);
  814.  
  815.                                        /* create the screen background      */
  816.    for (i = BLACK, ii = 5; i <= WHITE; i++, ii += 21)
  817.       boxfill(ii, 5, 21, MAXY - 10, i, COPY_IMAGE);
  818.    for (i = YELLOW; i > BLACK; i--, ii += 21)
  819.       boxfill(ii, 5, 21, MAXY - 10, i, COPY_IMAGE);
  820.  
  821.             /* print messages showing user each animation routine in action */
  822.    boxfill(5, 36, 50, 12, BLACK, COPY_IMAGE);
  823.    outtextxy(5, 36, "animate()");
  824.    boxfill(5, 136, 57, 12, BLACK, COPY_IMAGE);
  825.    outtextxy(5, 136, "animate1()");
  826.    boxfill(5, 236, 78, 12, BLACK, COPY_IMAGE);
  827.    outtextxy(5, 236, "animatepixel()");
  828.    boxfill(5, 336, 85, 12, BLACK, COPY_IMAGE);
  829.    outtextxy(5, 336, "animatebestss()");
  830.  
  831.                                        /* store the background into memory  */
  832.    bgscrn[0] = (void *) malloc(imagememreq(640, 204));
  833.    bgscrn[1] = (void *) malloc(imagememreq(640, 204));
  834.    bgscrn[2] = (void *) malloc(imagememreq(640, 72));
  835.    storeimage(0, 0, 640, 204, bgscrn[0]);
  836.    storeimage(0, 204, 640, 204, bgscrn[1]);
  837.    storeimage(0, 408, 640, 72, bgscrn[2]);
  838.  
  839.                              /* allocate memory for graphicobject structure */
  840.    graphic = (graphicobject *) malloc(sizeof(graphicobject));
  841.  
  842.                  /* draw the image to animate outside the visible video RAM */
  843.  /* because it is outside the visible range, mouse cursor can stay onscreen */
  844.    #define CLR1 LIGHTBLUE
  845.    #define CLR2 YELLOW                         /* draw the true-color image */
  846.    boxfill(0, MAXY, 32, 32, BGCOLOR, COPY_IMAGE);
  847.    boxfill(13, MAXY, 7, 32, CLR1, COPY_IMAGE);
  848.    boxfill(0, MAXY+13, 32, 7, CLR1, COPY_IMAGE);
  849.    linex(16, MAXY, 31, MAXY+15, CLR2);
  850.    linex(31, MAXY+15, 15, MAXY+31, CLR2);
  851.    linex(15, MAXY+31, 0, MAXY+16, CLR2);
  852.    linex(0, MAXY+16, 16, MAXY, CLR2);
  853.    boxfill(12, MAXY+12, 9, 9, BLACK, COPY_IMAGE);
  854.  
  855.    image[0] = (void *) malloc(imagememreq(32, 32));       /* for storeimage */
  856.    image_or[0] = (void *) malloc(imagememreq(32, 32));    /* for storeimage */
  857.    image[1] = (void *) malloc(pixelimagememreq(32, 32));
  858.                                                      /* for storepixelimage */
  859.    image[2] = (void *) malloc(pixelrcompressimagememreq(0, MAXY, 32, 32));
  860.                                              /* for storepixelcompressimage */
  861.    storeimage(0, MAXY, 32, 32, image[0]);                     /* save image */
  862.    storepixelimage(0, MAXY, 32, 32, BGCOLOR, image[1]);       /* save image */
  863.    storepixelcompressimage(0, MAXY, 32, 32, BGCOLOR, image[2]); /* sv image */
  864.  
  865.             /* draw the graphics to animate outside the visible screen area */
  866.    #undef CLR1
  867.    #undef CLR2
  868.    #define CLR1 WHITE
  869.    #define CLR2 WHITE                          /* draw the pure-white image */
  870.    boxfill(0, MAXY, 32, 32, BGCOLOR, COPY_IMAGE);
  871.    boxfill(13, MAXY, 7, 32, CLR1, COPY_IMAGE);
  872.    boxfill(0, MAXY+13, 32, 7, CLR1, COPY_IMAGE);
  873.    linex(16, MAXY, 31, MAXY+15, CLR2);
  874.    linex(31, MAXY+15, 15, MAXY+31, CLR2);
  875.    linex(15, MAXY+31, 0, MAXY+16, CLR2);
  876.    linex(0, MAXY+16, 16, MAXY, CLR2);
  877.    boxfill(12, MAXY+12, 9, 9, BLACK, COPY_IMAGE);
  878.    storeimage(0, MAXY, 32, 32, image_or[0]);   /* save the pure-white image */
  879.  
  880.                             /* display all the graphics -- ready to animate */
  881.    writeimage(6, 50, COPY_IMAGE, image[0]);
  882.    writeimage(6, 150, COPY_IMAGE, image[0]);
  883.    writepixelimage(6, 250, image[1]);
  884.    writepixelcompressimage(6, 350, image[2]);
  885.    if (mouse == TRUE) showms();        /* if mouse detected, show ms cursor */
  886.    getchr();    /* wait for a keypress before beginning animation sequences */
  887.    graphic->maxx = graphic->maxy = 32; /* initialize the graphic dimensions */
  888.    graphic->x = 6, graphic->y = 50;   /* initialize graphic coordinates    */
  889.    if (mouse == TRUE) hidems();        /* if mouse detected, hide ms cursor */
  890.  
  891.    for (i = 6; i < MAXX - 37; graphic->x = i, i += 2) {
  892.       if (keyhit()) {                  /* if the user hit a key..           */
  893.          getchr();                     /* read the key                      */
  894.          if (keyp.ascii == 27)         /* if it was the <ESC> key..         */
  895.             exit(0);                   /* exit to DOS with errorlevel 0     */
  896.          break;                       /* else abort this animation sequence */
  897.       }
  898.       animate((int *)graphic, i, 50, 0, image_or, image, bgscrn);
  899.    }
  900.  
  901.    graphic->x = 6, graphic->y = 150;
  902.    for (i = 6; i < MAXX - 37; graphic->x = i, i += 2) {
  903.       if (keyhit()) {                  /* if the user hit a key..           */
  904.          getchr();                     /* read the key                      */
  905.          if (keyp.ascii == 27)         /* if it was the <ESC> key..         */
  906.             exit(0);                   /* exit to DOS with errorlevel 0     */
  907.          break;                       /* else abort this animation sequence */
  908.       }
  909.       animate1((int *)graphic, i, 150, 0, image, bgscrn);
  910.    }
  911.  
  912.    graphic->x = 6, graphic->y = 250;
  913.    for (i = 6; i < MAXX - 37; graphic->x = i, i += 2) {
  914.       if (keyhit()) {                  /* if the user hit a key..           */
  915.          getchr();                     /* read the key                      */
  916.          if (keyp.ascii == 27)         /* if it was the <ESC> key..         */
  917.             exit(0);                   /* exit to DOS with errorlevel 0     */
  918.          break;                       /* else abort this animation sequence */
  919.       }
  920.       animatepixel((int *)graphic, i, 250, 1, image, bgscrn);
  921.    }
  922.  
  923.    graphic->x = 6;
  924.    for (i = 6; i < MAXX - 37; graphic->x = i, i += 2) {
  925.       if (keyhit()) {                  /* if the user hit a key..           */
  926.          getchr();                     /* read the key                      */
  927.          if (keyp.ascii == 27)         /* if it was the <ESC> key..         */
  928.             exit(0);                   /* exit to DOS with errorlevel 0     */
  929.          break;                       /* else abort this animation sequence */
  930.       }
  931.       animatebestss(graphic->x, 350, i, 350, image[2], image[2], bgscrn);
  932.    }
  933.  
  934.    free(image_or[0]);                  /* free all allocated memory         */
  935.    for (i = 0; i < 3; i++) free(image[i]);
  936.    if (mouse == TRUE) showms();        /* if mouse detected, show ms cursor */
  937.    getchr();                           /* wait for keypress before exitting */
  938.    if (mouse == TRUE) hidems();        /* if mouse detected, hide ms cursor */
  939.    changevideomode(oldmode);           /* restore the original video mode   */
  940.    if (oldmode == 3 || oldmode == 7 || oldmode == 21) {
  941.                                        /* if the old mode was a text mode.. */
  942.       textmem(1);                      /* restore text video memory         */
  943.       cursor(1, 1);                    /* show and restore cursor position  */
  944.    }
  945. }
  946.  
  947. ==============================================================================
  948.  
  949.                          END OF SOURCE CODE LISTINGS
  950.