home *** CD-ROM | disk | FTP | other *** search
/ Collection of Hack-Phreak Scene Programs / cleanhpvac.zip / cleanhpvac / FGDEMO40.ZIP / SOURCE.COM / MISC.C < prev    next >
Text File  |  1995-02-12  |  24KB  |  1,007 lines

  1. /**********************************************************************\
  2. *                                                                      *
  3. *  misc.c -- bird, mouse, keyboard handler, things on the Misc. menu.  *
  4. *                                                                      *
  5. \**********************************************************************/
  6.  
  7. #include "defs.h"
  8.  
  9. /* include bitmap data so the images are compiled into the EXE file */
  10.  
  11. #include "birds.h"
  12. #include "fgtitle.h"
  13. #include "fighter.h"
  14.  
  15. /**********************************************************************\
  16. *                                                                      *
  17. *  do_bird -- make a bitmapped bird fly across the screen              *
  18. *                                                                      *
  19. \**********************************************************************/
  20.  
  21. int do_bird()
  22. {
  23.    int x;
  24.    int frame;
  25.  
  26.    if (!exists("MOUNTAIN.PCX"))
  27.       abort_program("File missing: MOUNTAIN.PCX.\n");
  28.  
  29.    /* load the background on the hidden page */
  30.  
  31.    fg_mousevis(OFF);
  32.    fg_setpage(hidden);
  33.    fg_showpcx("MOUNTAIN.PCX",0);
  34.    fg_setpage(visual);
  35.    fg_copypage(hidden,visual);
  36.    fg_waitfor(8);
  37.  
  38.    fg_mousevis(OFF);
  39.    fg_transfer(0,xlimit,70,100,0,30,visual,hidden);
  40.  
  41.    /* the bird flies behind two trees -- store this image where we can
  42.       get it later */
  43.  
  44.    fg_transfer(0,119,70,100,0,61,visual,hidden);
  45.    fg_tcmask(0x8002);
  46.  
  47.    /* first pass -- the bird flies to the right */
  48.  
  49.    frame = 0;
  50.    for (x = 0; x < 640; x+=16)
  51.    {
  52.       fg_transfer(0,xlimit,0,30,0,100,hidden,hidden);
  53.  
  54.       fg_setpage(hidden);
  55.       frame = !frame;
  56.       if (frame == 0)
  57.       {
  58.          fg_move(x,100);
  59.          fg_clpimage(bird1,20,20);
  60.       }
  61.       else
  62.       {
  63.          fg_move(x,89);
  64.          fg_clpimage(bird2,24,20);
  65.       }
  66.  
  67.       /* redraw the trees on top of the bird */
  68.  
  69.       fg_tcxfer(0,119,31,61,0,100,hidden,hidden);
  70.  
  71.       fg_setpage(visual);
  72.       fg_restore(0,xlimit,70,100);
  73.       fg_waitfor(2);
  74.    }
  75.    fg_transfer(0,639,0,30,0,100,hidden,visual);
  76.  
  77.    /* put the Fastgraph title bitmap, with shadows */
  78.  
  79.    fg_waitfor(8);
  80.  
  81.    fg_move(187,75);
  82.    fg_setcolor(9);
  83.    fg_drawmap(fgtitle,36,53);
  84.  
  85.    fg_move(194,81);
  86.    fg_setcolor(0);
  87.    fg_drawmap(fgtitle,36,53);
  88.  
  89.    fg_move(195,82);
  90.    fg_setcolor(15);
  91.    fg_drawmap(fgtitle,36,53);
  92.  
  93.    fg_waitfor(8);
  94.  
  95.    /* second pass -- fly to the left -- flip the bird <g> */
  96.  
  97.    fg_transfer(0,xlimit,230,260,0,30,visual,hidden);
  98.    for (x = 624; x >-40; x-=16)
  99.    {
  100.       fg_transfer(0,xlimit,0,30,0,260,hidden,hidden);
  101.  
  102.       fg_setpage(hidden);
  103.       frame = !frame;
  104.       if (frame == 0)
  105.       {
  106.          fg_move(x,260);
  107.          fg_flpimage(bird1,20,20);
  108.       }
  109.       else
  110.       {
  111.          fg_move(x,249);
  112.          fg_flpimage(bird2,24,20);
  113.       }
  114.  
  115.       fg_setpage(visual);
  116.       fg_restore(0,xlimit,230,260);
  117.       fg_waitfor(1);
  118.    }
  119.    fg_transfer(0,639,0,30,0,260,hidden,visual);
  120.  
  121.    /* restore the hidden page */
  122.  
  123.    fg_setpage(hidden);
  124.    draw_screen(4);
  125.  
  126.    /* wait for a keystroke */
  127.  
  128.    fg_mousevis(ON);
  129.    wait_for_keystroke();
  130.  
  131.    /* copy menu screen from hidden to visual */
  132.  
  133.    fg_mousevis(OFF);
  134.    fg_copypage(hidden,visual);
  135.    fg_mousevis(ON);
  136.  
  137.    /* fix the colors */
  138.  
  139.    fg_palettes(default_colors);
  140.  
  141.    /* restore the screen and return to the menu */
  142.  
  143.    redraw = TRUE;
  144.    return(OK);
  145. }
  146.  
  147. /**********************************************************************\
  148. *                                                                      *
  149. *  do_borland -- display the Borland logo (we obtained a license from  *
  150. *                Borland to do this!)                                  *
  151. *                                                                      *
  152. \**********************************************************************/
  153.  
  154. int do_borland()
  155. {
  156.    if (!exists("BORLAND.PCX"))
  157.       abort_program("File missing: BORLAND.PCX.\n");
  158.  
  159.    fg_mousevis(OFF);
  160.    fg_setpage(hidden);
  161.    fg_showpcx("BORLAND.PCX",0);
  162.  
  163.    fg_tcmask(0x7FEE);
  164.    fg_tcxfer(32,295,7,191,136,300,hidden,visual);
  165.  
  166.    /* copy the visual page to the hidden page */
  167.  
  168.    fg_setpage(visual);
  169.    fg_copypage(visual,hidden);
  170.    fg_setpage(hidden);
  171.    fg_setcolor(15);
  172.    fg_rect(136,287,40,300);
  173.    fg_rect(288,433,122,300);
  174.    fg_setcolor(11);
  175.    fg_drect(136,287,40,300,matrix2);
  176.    fg_drect(288,433,122,300,matrix2);
  177.  
  178.    /* wait for a keystroke */
  179.  
  180.    fg_mousevis(ON);
  181.    wait_for_keystroke();
  182.  
  183.    /* copy menu screen from hidden to visual */
  184.  
  185.    fg_mousevis(OFF);
  186.    fg_fadein(0);
  187.    fg_mousevis(ON);
  188.  
  189.    /* restore the screen and return to the menu */
  190.  
  191.    redraw = TRUE;
  192.    return(OK);
  193. }
  194.  
  195. /**********************************************************************\
  196. *                                                                      *
  197. *  do_dub -- wavering Fastgraph logo courtesy of Dub Media             *
  198. *            Dub Media does renderings and sprite animation for        *
  199. *            game programmers. Call Mike or Alfred at (617)647-1101    *
  200. *                                                                      *
  201. \**********************************************************************/
  202.  
  203. int do_dub()
  204. {
  205.    int i,j,x,y;
  206.    int x1,y2;
  207.    int stall_time;
  208.  
  209.    if (!exists("DUB.PCX"))
  210.       abort_program("File missing: DUB.PCX.\n");
  211.  
  212.    stall_time = clockspeed/4;
  213.    fg_mousevis(OFF);
  214.    fg_setpage(hidden);
  215.    fg_showpcx("DUB.PCX",0);
  216.  
  217.    /* clear the visual screen below the menu */
  218.  
  219.    fg_setpage(visual);
  220.    fg_setcolor(0);
  221.    fg_rect(4,635,39,346);
  222.  
  223.    /* redraw the menu with no options highlighted */
  224.  
  225.    horizontal_menu(main_menu,-ITEMS,-3);
  226.    fg_mousevis(OFF);
  227.  
  228.    /* put the first image on the screen */
  229.  
  230.    fg_transfer(32,137,235,297,520,336,hidden,visual);
  231.  
  232.    /* draw the other images on the screen in sequence */
  233.  
  234.    x1 = 56;
  235.    y2 = 100;
  236.    fg_setcolor(0);
  237.    for (j = 0; j < 2; j++)
  238.    {
  239.       for (i = 1; i < 4; i++)
  240.       {
  241.          for (x = 0; x < 640; x+=160)
  242.          {
  243.             for (y = 56; y <= 224; y+= 56)
  244.             {
  245.                fg_rect(x1-8,x1-1,y2-56,y2);
  246.                fg_transfer(x,x+159,y-56,y,x1,y2,hidden,visual);
  247.                fg_stall(stall_time);
  248.                y2++;
  249.                x1+= 8;
  250.             }
  251.          }
  252.       }
  253.  
  254.       for (i = 1; i < 4; i++)
  255.       {
  256.          for (x = 0; x < 640; x+=160)
  257.          {
  258.             for (y = 56; y <= 224; y+= 56)
  259.             {
  260.                fg_rect(x1-8,x1-1,y2-56,y2);
  261.                fg_transfer(x,x+159,y-56,y,x1,y2,hidden,visual);
  262.                fg_stall(stall_time);
  263.                y2++;
  264.                x1-= 8;
  265.             }
  266.          }
  267.       }
  268.    }
  269.  
  270.    for (i = 1; i < 3; i++)
  271.    {
  272.       for (x = 0; x < 640; x+=160)
  273.       {
  274.          for (y = 56; y <= 224; y+= 56)
  275.          {
  276.             fg_rect(x1-8,x1-1,y2-56,y2);
  277.             fg_transfer(x,x+159,y-56,y,x1,y2,hidden,visual);
  278.             fg_stall(stall_time);
  279.             y2++;
  280.             x1+= 8;
  281.          }
  282.       }
  283.    }
  284.  
  285.    /* redraw the menu on the hidden page */
  286.  
  287.    fg_setpage(hidden);
  288.    draw_screen(3);
  289.  
  290.    /* wait for a keystroke */
  291.  
  292.    fg_mousevis(ON);
  293.    wait_for_keystroke();
  294.    fg_mousevis(OFF);
  295.  
  296.    /* restore the screen and return */
  297.  
  298.    fg_copypage(hidden,visual);
  299.    redraw = TRUE;
  300.    fg_fadein(0);
  301.    fg_palettes(default_colors);
  302.    fg_mousevis(ON);
  303.  
  304.    return(OK);
  305. }
  306.  
  307. /**********************************************************************\
  308. *                                                                      *
  309. *  do_histogram -- create a histogram                                  *
  310. *                                                                      *
  311. \**********************************************************************/
  312.  
  313. int do_histogram()
  314. {
  315.    register int i;
  316.    int x1,x2,y1,y2;
  317.    static char label[] = "Productivity";
  318.    static char title[] = "See profits soar with Fastgraph!";
  319.  
  320.    static int x[] = {130, 180, 230, 280, 330, 380, 430, 480};
  321.    static int y[] = {290, 275, 270, 265, 200, 170, 130, 100};
  322.  
  323.    /* clear the bottom of the screen */
  324.  
  325.    fg_mousevis(OFF);
  326.    fg_restore(0,xlimit,menu_bottom,ylimit);
  327.  
  328.    fg_setpage(visual);
  329.    fg_setcolor(0);
  330.  
  331.    y1 = 100;
  332.    y2 = 300;
  333.  
  334.    /* axes */
  335.  
  336.    fg_rect(120,520,y2,y2);
  337.    fg_rect(120,120,y1,y2);
  338.  
  339.    for (i = 100; i < 300; i+=20)
  340.    {
  341.       y1 = i;
  342.       fg_rect(120,126,y1,y1);
  343.    }
  344.  
  345.    /* boxes */
  346.  
  347.    for (i = 0; i < 8; i++)
  348.    {
  349.       x1 = x[i];
  350.       x2 = x1 + 30;
  351.       y1 = y[i];
  352.  
  353.       fg_setcolor(11);
  354.       fg_rect(x1,x2,y1,y2);
  355.  
  356.       fg_setcolor(0);
  357.       fg_box(x1,x2,y1,y2);
  358.    }
  359.  
  360.    /* label the x axis */
  361.  
  362.    x1 = 320 - length_pstring(label)/2 - 2;
  363.    x2 = 320 + length_pstring(label)/2 + 2;
  364.    y2 = 320;
  365.    y1 = y2 - PTSIZE - 1;
  366.    fg_setcolor(0);
  367.    center_pstring(label,x1,x2,y2);
  368.  
  369.    /* Profits soar with Fastgraph */
  370.  
  371.    x1 = 320 - length_pstring(title)/2 - 2;
  372.    x2 = 320 + length_pstring(title)/2 + 2;
  373.    y2 = 90;
  374.    y1 = y2 - PTSIZE - 1;
  375.    fg_setcolor(0);
  376.    center_pstring(title,x1,x2,y2);
  377.  
  378.    /* wait for a keystroke or mouse button */
  379.  
  380.    fg_mousevis(ON);
  381.    wait_for_keystroke();
  382.  
  383.    /* restore the screen and return to the menu */
  384.  
  385.    fg_mousevis(OFF);
  386.    fg_restore(0,xlimit,menu_bottom,ylimit);
  387.    redraw = TRUE;
  388.  
  389.    return(OK);
  390. }
  391.  
  392. /**********************************************************************\
  393. *                                                                      *
  394. *  do_joystick -- demo some joystick functions                         *
  395. *                                                                      *
  396. \**********************************************************************/
  397.  
  398. int do_joystick()
  399. {
  400.    static char *string1[] = {
  401.    "Joystick",
  402.    "Joysticks found on Port 1 and Port 2."
  403.    };
  404.  
  405.    static char *string2[] = {
  406.    "Joystick",
  407.    "Joystick found on Port 1."
  408.    };
  409.  
  410.    static char *string3[] = {
  411.    "Joystick",
  412.    "Joystick found on Port 2."
  413.    };
  414.  
  415.    static char *string4[] = {
  416.    "Joystick",
  417.    "Joystick not found."
  418.    };
  419.  
  420.    static int joy1_x[] = {140,200,260,140,200,260,140,200,260};
  421.    static int joy2_x[] = {360,420,480,360,420,480,360,420,480};
  422.    static int joy_y[] =  {110,110,110,140,140,140,170,170,170};
  423.  
  424.    char key,aux;
  425.    unsigned char key1,aux1;
  426.    int x,y;
  427.    int count,mousex,mousey;
  428.    int pos1,pos2,new_pos1,new_pos2;
  429.    int joystick[2];
  430.  
  431.    /* initialize joysticks, if possible */
  432.  
  433.    if (fg_initjoy(1) == 0)
  434.       joystick[0] = TRUE;
  435.    else
  436.       joystick[0] = FALSE;
  437.  
  438.    if (fg_initjoy(2) == 0)
  439.       joystick[1] = TRUE;
  440.    else
  441.       joystick[1] = FALSE;
  442.  
  443.    fg_mousevis(OFF);
  444.    fg_restore(0,xlimit,menu_bottom,ylimit);
  445.  
  446.    /* report status of joysticks */
  447.  
  448.    if (joystick[0] && joystick[1])
  449.       info_window(120,520,220,string1,2);
  450.    else if (joystick[0])
  451.       info_window(120,520,220,string2,2);
  452.    else if (joystick[1])
  453.       info_window(120,520,220,string3,2);
  454.    else
  455.       info_window(120,520,220,string4,2);
  456.  
  457.    /* draw a grid to illustrate joystick positions */
  458.  
  459.    fg_mousevis(OFF);
  460.    if (joystick[0])
  461.    {
  462.       fg_setcolor(15);
  463.       fg_rect(120,300,100,190);
  464.       fg_setcolor(0);
  465.       fg_box(120,300,100,190);
  466.       fg_box(180,240,100,190);
  467.       fg_box(120,300,130,160);
  468.    }
  469.  
  470.    if (joystick[1])
  471.    {
  472.       fg_setcolor(15);
  473.       fg_rect(340,520,100,190);
  474.       fg_setcolor(0);
  475.       fg_box(340,520,100,190);
  476.       fg_box(400,460,100,190);
  477.       fg_box(340,520,130,160);
  478.    }
  479.  
  480.    pos1 = 4; new_pos1 = pos1;
  481.    pos2 = 4; new_pos2 = pos2;
  482.  
  483.    /* draw red boxes to represent joystick straight up position */
  484.  
  485.    fg_setcolor(4);
  486.    if (joystick[0])
  487.    {
  488.       x = joy1_x[pos1];
  489.       y = joy_y[pos1];
  490.       fg_rect(x,x+20,y,y+10);
  491.    }
  492.    if (joystick[1])
  493.    {
  494.       x = joy2_x[pos2];
  495.       y = joy_y[pos2];
  496.       fg_rect(x,x+20,y,y+10);
  497.    }
  498.  
  499.    fg_mousevis(ON);
  500.    for(;;)
  501.    {
  502.       fg_waitfor(3);
  503.  
  504.       /* handle first joystick */
  505.  
  506.       if (joystick[0])
  507.       {
  508.          fg_intjoy(1,&key,&aux);
  509.          if (key == CR)
  510.             break;
  511.          if (aux == 0)
  512.             new_pos1 = 4;
  513.          else if (aux >= 71 && aux <= 73)
  514.             new_pos1 = aux - 71;
  515.          else if (aux >= 75 && aux <= 77)
  516.             new_pos1 = aux - 72;
  517.          else if (aux >= 79 && aux <= 81)
  518.             new_pos1 = aux - 73;
  519.  
  520.          if (new_pos1 != pos1)
  521.          {
  522.             fg_setcolor(15);
  523.             x = joy1_x[pos1];
  524.             y = joy_y[pos1];
  525.             fg_mousevis(OFF);
  526.             fg_rect(x,x+20,y,y+10);
  527.  
  528.             pos1 = new_pos1;
  529.             fg_setcolor(4);
  530.             x = joy1_x[pos1];
  531.             y = joy_y[pos1];
  532.             fg_rect(x,x+20,y,y+10);
  533.             fg_mousevis(ON);
  534.          }
  535.       }
  536.  
  537.       /* handle second joystick */
  538.  
  539.       if (joystick[1])
  540.       {
  541.          fg_intjoy(2,&key,&aux);
  542.          if (key == CR)
  543.             break;
  544.          if (aux == 0)
  545.             new_pos2 = 4;
  546.          else if (aux >= 71 && aux <= 73)
  547.             new_pos2 = aux - 71;
  548.          else if (aux >= 75 && aux <= 77)
  549.             new_pos2 = aux - 72;
  550.          else if (aux >= 79 && aux <= 81)
  551.             new_pos2 = aux - 73;
  552.  
  553.          if (new_pos2 != pos2)
  554.          {
  555.             fg_setcolor(15);
  556.             x = joy2_x[pos2];
  557.             y = joy_y[pos2];
  558.             fg_mousevis(OFF);
  559.             fg_rect(x,x+20,y,y+10);
  560.  
  561.             pos2 = new_pos2;
  562.             fg_setcolor(4);
  563.             x = joy2_x[pos2];
  564.             y = joy_y[pos2];
  565.             fg_rect(x,x+20,y,y+10);
  566.             fg_mousevis(ON);
  567.          }
  568.       }
  569.  
  570.       /* exit loop if key or mouse button pressed */
  571.  
  572.       fg_intkey(&key1,&aux1);
  573.       if (key1+aux1 > 0)
  574.          break;
  575.  
  576.       fg_mousebut(1,&count,&mousex,&mousey);
  577.       if (count > 0)
  578.          break;
  579.    }
  580.  
  581.    /* restore the screen and return to the menu */
  582.  
  583.    fg_mousevis(OFF);
  584.    fg_restore(0,xlimit,menu_bottom,ylimit);
  585.  
  586.    redraw = TRUE;
  587.    return(OK);
  588. }
  589.  
  590. /**********************************************************************\
  591. *                                                                      *
  592. *  do_mouse -- nice animated mouse from Tom Guthery                    *
  593. *                                                                      *
  594. \**********************************************************************/
  595.  
  596. int do_mouse()
  597. {
  598.    register int i,j;
  599.    int stalltime;
  600.  
  601.    if (!exists("MOUSE.PCX"))
  602.       abort_program("File missing: MOUSE.PCX.\n");
  603.  
  604.    stalltime = (int)(clockspeed/8);
  605.  
  606.    /* display the frames on the hidden page */
  607.  
  608.    fg_mousevis(OFF);
  609.    fg_setpage(hidden);
  610.    fg_showpcx("MOUSE.PCX",0);
  611.    fg_setpage(visual);
  612.  
  613.    /* redraw the menu bar, unhighlighted */
  614.  
  615.    fg_setcolor(0);
  616.    fg_rect(4,635,39,346);
  617.    horizontal_menu(main_menu,-ITEMS,-4);
  618.    fg_setcolor(0);
  619.  
  620.    /* run the mouse around 4 times */
  621.  
  622.    for (j = 0; j < 4; j++)
  623.    {
  624.       for  (i = 0; i < 36; i++)
  625.       {
  626.          mouserun(i);
  627.          if (j <= 1)
  628.             fg_waitfor(1);
  629.          else
  630.             fg_stall(stalltime);
  631.       }
  632.    }
  633.  
  634.    fg_rect(4,635,39,346);
  635.    mouserun(36);
  636.    fg_waitfor(1);
  637.  
  638.    /* "Flix" */
  639.  
  640.    fg_transfer(0,271,291,349,192,227,hidden,visual);
  641.  
  642.    /* panting mouse */
  643.  
  644.    for (j = 0; j < 12; j++)
  645.    {
  646.       for  (i = 37; i < 40; i++)
  647.       {
  648.          mouserun(i);
  649.          fg_waitfor(2);
  650.       }
  651.    }
  652.    for (j = 0; j < 2; j++)
  653.    {
  654.       for  (i = 1; i < 37; i++)
  655.       {
  656.          mouserun(i);
  657.          if (j < 1)
  658.             fg_waitfor(1);
  659.          else
  660.             fg_stall(stalltime);
  661.       }
  662.    }
  663.    fg_waitfor(1);
  664.  
  665.    /* panting mouse */
  666.  
  667.    for (j = 0; j < 6; j++)
  668.    {
  669.       for  (i = 37; i < 40; i++)
  670.       {
  671.          mouserun(i);
  672.          fg_waitfor(2);
  673.       }
  674.    }
  675.  
  676.    /* restore the hidden page */
  677.  
  678.    fg_setpage(hidden);
  679.    draw_screen(4);
  680.  
  681.    /* wait for a keystroke */
  682.  
  683.    /* copy menu screen from hidden to visual */
  684.  
  685.    fg_mousevis(OFF);
  686.    fg_fadein(0);
  687.    fg_mousevis(ON);
  688.  
  689.    /* restore the screen and return to the menu */
  690.  
  691.    redraw = TRUE;
  692.    return(OK);
  693. }
  694.  
  695. /**********************************************************************\
  696. *                                                                      *
  697. *  mouserun -- run the mousey around the screen                        *
  698. *                                                                      *
  699. \**********************************************************************/
  700.  
  701. int mouserun(int i)
  702. {
  703.    int j;
  704.    int difx,dify;
  705.  
  706.    /* location of each mouse frame on the hidden page */
  707.  
  708.    typedef struct rodent
  709.    {
  710.      int x1;
  711.      int x2;
  712.      int y1;
  713.      int y2;
  714.    } RODENT;
  715.  
  716.    static RODENT mousey[] =
  717.    {
  718.       {0,119,0,49},
  719.       {120,247,0,46},
  720.       {248,359,0,57},
  721.       {360,479,0,64},
  722.  
  723.       {248,303,64,180},
  724.       {304,359,64,186},
  725.       {360,423,72,178},
  726.       {424,495,72,188},
  727.  
  728.       {0,119,184,233},
  729.       {120,247,176,222},
  730.       {248,359,192,250},
  731.       {360,479,192,257},
  732.  
  733.       {0,55,56,170},
  734.       {56,103,56,178},
  735.       {104,167,56,162},
  736.       {168,239,56,172},
  737.  
  738.       {496,623,0,56},
  739.       {496,623,64,122},
  740.       {496,623,128,183}
  741.    };
  742.  
  743.    /* where we want the mouse to go on the visual page, and which frame */
  744.  
  745.    typedef struct path
  746.    {
  747.      int x;
  748.      int y;
  749.      int image;
  750.    } PATH;
  751.  
  752.    static PATH mousepath[] =
  753.    {
  754.  
  755.       {8,343,0},
  756.       {72,327,1},
  757.       {144,343,2},
  758.       {152,343,3},
  759.  
  760.       {176,343,0},
  761.       {240,327,1},
  762.       {312,343,2},
  763.       {320,343,3},
  764.  
  765.       {344,343,0},
  766.       {408,327,1},
  767.       {480,343,2},
  768.       {488,343,3},
  769.  
  770.       {512,343,0},
  771.  
  772.       {576,346,4},
  773.       {560,287,5},
  774.       {568,218,6},
  775.       {560,199,7},
  776.  
  777.       {576,169,4},
  778.  
  779.       {512,93,8},
  780.       {448,106,9},
  781.       {392,100,10},
  782.       {376,110,11},
  783.  
  784.       {344,93,8},
  785.       {280,106,9},
  786.       {224,100,10},
  787.       {208,110,11},
  788.  
  789.       {176,93,8},
  790.       {112,106,9},
  791.       {56,100,10},
  792.       {40,110,11},
  793.  
  794.       {8,93,8},
  795.  
  796.       {8,161,12},
  797.       {32,229,13},
  798.       {8,278,14},
  799.       {8,313,15},
  800.  
  801.       {8,343,12},
  802.  
  803.       {8,343,0},
  804.  
  805.       {56,343,16},
  806.       {56,343,17},
  807.       {56,343,18}
  808.    };
  809.  
  810.    /* draw the mouse */
  811.  
  812.    j = mousepath[i].image;
  813.    dify = mousey[j].y2 - mousey[j].y1;
  814.    difx = mousey[j].x2 - mousey[j].x1;
  815.  
  816.    /* erase the previous mouse-this is complicated to avoid flicker */
  817.  
  818.    if (j >= 0 && j < 4)                          /* bottom mouse */
  819.    {
  820.       fg_rect(8,mousepath[i].x-1,278,343);       /* erase to left */
  821.       fg_rect(8,631,mousepath[i].y+1,347);       /* erase below */
  822.       fg_rect(8,631,228,mousepath[i].y-dify);    /* erase above */
  823.    }
  824.  
  825.    else if (j >= 4 && j < 8)                     /* right mouse */
  826.    {
  827.       fg_rect(512,632,mousepath[i].y+1,347);     /* erase below */
  828.       fg_rect(512,mousepath[i].x-1,mousepath[i].y-dify,mousepath[i].y);
  829.       fg_rect(mousepath[i].x+difx+1,633,mousepath[i].y-dify,mousepath[i].y);
  830.    }
  831.    else if (j >= 8 && j < 12)                    /* top mouse */
  832.    {
  833.       fg_rect(mousepath[i].x + difx,633,40,110); /* erase right */
  834.       fg_rect(mousepath[i].x,633,mousepath[i].y,169); /* erase below */
  835.       fg_rect(mousepath[i].x,633,39,mousepath[i].y-dify); /* erase above */
  836.    }
  837.  
  838.    else if (j >= 12 && j < 16)                   /* left mouse */
  839.    {
  840.       fg_rect(8,79,40,mousepath[i].y - dify);            /* erase above */
  841.       fg_rect(7,mousepath[i].x-1,40,mousepath[i].y);     /* erase left */
  842.       fg_rect(mousepath[i].x+difx,128,40,mousepath[i].y);/* erase right */
  843.    }
  844.    else if (j >= 16)                            /* panting mouse */
  845.    {
  846.       fg_rect(56,180,280,mousepath[i].y-dify-1);
  847.       fg_rect(8,55,226,343);
  848.    }
  849.  
  850.    fg_transfer(mousey[j].x1,mousey[j].x2,mousey[j].y1,mousey[j].y2,
  851.                mousepath[i].x,mousepath[i].y,hidden,visual);
  852.    return(OK);
  853. }
  854.  
  855. /**********************************************************************\
  856. *                                                                      *
  857. *  do_keyboard -- simple game to show the keyboard handler             *
  858. *                                                                      *
  859. \**********************************************************************/
  860.  
  861. /* define keyboard keys */
  862.  
  863. #define kb_esc   1
  864. #define kb_alt   56
  865. #define kb_ctrl  29
  866. #define kb_left  75
  867. #define kb_right 77
  868. #define kb_up    72
  869. #define kb_down  80
  870.  
  871. int do_keyboard()
  872. {
  873.    int fighter_x,fighter_y;
  874.    int bullet_x[20],bullet_y[20];
  875.    int nbullets;
  876.    register int i;
  877.  
  878.    static char *string[] = {
  879.    "low level keyboard handler enabled",
  880.    "Use the arrow keys to move the plane around, CTRL to shoot, ESC to quit."
  881.    };
  882.  
  883.    fg_mousevis(OFF);
  884.    fg_restore(0,xlimit,menu_bottom,ylimit);
  885.    horizontal_menu(main_menu,-ITEMS,-4);
  886.  
  887.    /* post instructions at bottom of screen */
  888.  
  889.    info_window(20,620,308,string,2);
  890.  
  891.    /* set palette 13 to non-transparent black */
  892.  
  893.    fg_palette(13,0);
  894.  
  895.    fighter_x = 340;
  896.    fighter_y = 276;
  897.    nbullets = 0;
  898.  
  899.    /* put the fighter plane on the screen at the original positions */
  900.  
  901.    fg_move(fighter_x,fighter_y);
  902.    fg_drwimage(fighter,15,64);
  903.  
  904.    /* prepare background workspace area */
  905.  
  906.    fg_transfer (8,55,40,108,0,378,hidden,hidden);
  907.  
  908.    /* enable the keyboard handler */
  909.  
  910.    fg_kbinit(1);
  911.  
  912.    /* main loop  -- loop until escape is pressed */
  913.  
  914.    while (!fg_kbtest(kb_esc))
  915.    {
  916.       /* check the arrow keys */
  917.  
  918.       if (fighter_x > 16 && fg_kbtest(kb_left))
  919.          fighter_x -= 2;
  920.       if (fighter_x < 592 && fg_kbtest(kb_right))
  921.          fighter_x += 2;
  922.       if (fighter_y > 108 && fg_kbtest(kb_up))
  923.          fighter_y -= 2;
  924.       if (fighter_y < 300 && fg_kbtest(kb_down))
  925.          fighter_y += 2;
  926.  
  927.       /* move the plane around */
  928.  
  929.       fg_transfer (0,47,310,378,fighter_x-8,fighter_y+2,hidden,hidden);
  930.       fg_move(fighter_x,fighter_y);
  931.       fg_setpage(hidden);
  932.       fg_drwimage(fighter,15,64);
  933.       fg_setpage(visual);
  934.       fg_restore(fighter_x-8,fighter_x+39,fighter_y-68,fighter_y+2);
  935.  
  936.       /* fire bullets, if any */
  937.  
  938.       for (i = 0; i < nbullets; i++)
  939.       {
  940.          if (bullet_y[i] < fighter_y - 64 || bullet_x[i] <= fighter_x-8)
  941.             fg_transfer(0,8,311,312,bullet_x[i],bullet_y[i],hidden,visual);
  942.          if (bullet_y[i] < fighter_y - 64)
  943.             fg_transfer(0,8,311,312,bullet_x[i]+24,bullet_y[i],hidden,visual);
  944.  
  945.          bullet_y[i] -= 8;
  946.          fg_setcolor(4);
  947.          fg_setpage(visual);
  948.          fg_rect(bullet_x[i],bullet_x[i]+1,bullet_y[i]-1,bullet_y[i]);
  949.          fg_rect(bullet_x[i]+25,bullet_x[i]+26,bullet_y[i]-1,bullet_y[i]);
  950.       }
  951.  
  952.       /* new bullets? */
  953.  
  954.       if (nbullets < 20 && fg_kbtest(kb_ctrl))
  955.       {
  956.          i = nbullets;
  957.          bullet_x[i] = fighter_x+1;
  958.          bullet_y[i] = fighter_y-40;
  959.          fg_setcolor(4);
  960.          fg_setpage(visual);
  961.          fg_rect(bullet_x[i],bullet_x[i]+1,bullet_y[i]-1,bullet_y[i]);
  962.          fg_rect(bullet_x[i]+25,bullet_x[i]+26,bullet_y[i]-1,bullet_y[i]);
  963.          nbullets++;
  964.       }
  965.  
  966.       /* kill bullet at top of screen */
  967.  
  968.       for(;;)
  969.       {
  970.          if (nbullets > 0 && bullet_y[0] <= 48)
  971.          {
  972.             fg_transfer(0,8,311,312,bullet_x[0],bullet_y[0],hidden,visual);
  973.             fg_transfer(0,8,311,312,bullet_x[0]+25,bullet_y[0],hidden,visual);
  974.  
  975.             for (i = 0; i< nbullets-1; i++)
  976.             {
  977.                bullet_x[i] = bullet_x[i+1];
  978.                bullet_y[i] = bullet_y[i+1];
  979.             }
  980.             nbullets--;
  981.          }
  982.          else
  983.             break;
  984.       }
  985.    }
  986.  
  987.    /* disable the keyboard handler */
  988.  
  989.    fg_kbinit(0);
  990.  
  991.    /* restore the hidden page */
  992.  
  993.    fg_setpage(hidden);
  994.    draw_screen(4);
  995.  
  996.    /* restore the screen and return to the menu */
  997.  
  998.    fg_mousevis(OFF);
  999.    fg_copypage(hidden,visual);
  1000.    redraw = TRUE;
  1001.  
  1002.    /* fix the palette */
  1003.  
  1004.    fg_palette(13,61);
  1005.    return(OK);
  1006. }
  1007.